fixed compilation warnings and errors when not using curl
[strongswan.git] / src / libstrongswan / utils / fetcher.c
1 /**
2 * @file fetcher.c
3 *
4 * @brief Implementation of fetcher_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2007 Andreas Steffen
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <fetcher://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #ifdef LIBCURL
24 #include <curl/curl.h>
25 #endif
26
27 #include <library.h>
28 #include <debug.h>
29
30 #include "fetcher.h"
31
32 typedef struct private_fetcher_t private_fetcher_t;
33
34 /**
35 * @brief Private Data of a h object.
36 */
37 struct private_fetcher_t {
38 /**
39 * Public data
40 */
41 fetcher_t public;
42
43 /**
44 * URI of the information source
45 */
46 const char *uri;
47
48 #ifdef LIBCURL
49 /**
50 * we use libcurl from http://curl.haxx.se/ as a fetcher
51 */
52 CURL* curl;
53 #endif /* LIBCURL */
54
55 };
56
57 /**
58 * writes data into a dynamically resizeable chunk_t
59 * needed for libcurl responses
60 */
61 size_t curl_write_buffer(void *ptr, size_t size, size_t nmemb, void *data)
62 {
63 size_t realsize = size * nmemb;
64 chunk_t *mem = (chunk_t*)data;
65
66 mem->ptr = (u_char *)realloc(mem->ptr, mem->len + realsize);
67 if (mem->ptr) {
68 memcpy(&(mem->ptr[mem->len]), ptr, realsize);
69 mem->len += realsize;
70 }
71 return realsize;
72 }
73
74 /**
75 * Implements fetcher_t.get
76 */
77 static chunk_t get(private_fetcher_t *this, const char *uri)
78 {
79 return chunk_empty;
80 }
81
82 /**
83 * Implements fetcher_t.post
84 */
85 static chunk_t post(private_fetcher_t *this, const char *request_type, chunk_t request)
86 {
87 chunk_t response = chunk_empty;
88
89 #ifdef LIBCURL
90 if (this->curl)
91 {
92 CURLcode res;
93 struct curl_slist *headers = NULL;
94 chunk_t curl_response = chunk_empty;
95 char curl_error_buffer[CURL_ERROR_SIZE];
96 char content_type[BUF_LEN];
97
98 /* set content type header */
99 snprintf(content_type, BUF_LEN, "Content-Type: %s", request_type);
100 headers = curl_slist_append(headers, content_type);
101
102 /* set options */
103 curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
104 curl_easy_setopt(this->curl, CURLOPT_URL, this->uri);
105 curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer);
106 curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response);
107 curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, request.ptr);
108 curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, request.len);
109 curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer);
110 curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
111 curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT);
112
113 DBG2("sending http post request to '%s'", this->uri);
114 res = curl_easy_perform(this->curl);
115
116 if (res == CURLE_OK)
117 {
118 DBG2("received valid http response");
119 response = chunk_clone(curl_response);
120 }
121 else
122 {
123 DBG1("http post request to '%s' using libcurl failed: %s",
124 this->uri, curl_error_buffer);
125 }
126 curl_slist_free_all(headers);
127 curl_free(curl_response.ptr);
128 }
129 #else
130 DBG1("warning: libcurl fetching not compiled in");
131 #endif /* LIBCURL */
132 return response;
133 }
134
135 /**
136 * Implements fetcher_t.destroy
137 */
138 static void destroy(private_fetcher_t *this)
139 {
140 #ifdef LIBCURL
141 curl_easy_cleanup(this->curl);
142 #endif /* LIBCURL */
143 free(this);
144 }
145
146 /*
147 * Described in header.
148 */
149 fetcher_t *fetcher_create(const char *uri)
150 {
151 private_fetcher_t *this = malloc_thing(private_fetcher_t);
152
153 /* initialize */
154 this->uri = uri;
155 #ifdef LIBCURL
156 this->curl = curl_easy_init();
157 if (this->curl == NULL)
158 {
159 DBG1("curl_easy_init_failed()");
160 }
161 #endif /* LIBCURL */
162
163 /* public functions */
164 this->public.get = (chunk_t (*) (fetcher_t*,const char*))get;
165 this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))post;
166 this->public.destroy = (void (*) (fetcher_t*))destroy;
167
168 return &this->public;
169 }
170
171 /**
172 * Described in header.
173 */
174 void fetcher_initialize(void)
175 {
176 #ifdef LIBCURL
177 CURLcode res;
178
179 /* initialize libcurl */
180 DBG1("initializing libcurl");
181 res = curl_global_init(CURL_GLOBAL_NOTHING);
182 if (res != CURLE_OK)
183 {
184 DBG1("libcurl could not be initialized: %s", curl_easy_strerror(res));
185 }
186 #endif /* LIBCURL */
187 }
188
189 /**
190 * Described in header.
191 */
192 void fetcher_finalize(void)
193 {
194 #ifdef LIBCURL
195 /* finalize libcurl */
196 DBG1("finalizing libcurl");
197 curl_global_cleanup();
198 #endif /* LIBCURL */
199 }
200