Support FETCH_CALLBACK in curl fetcher

This commit is contained in:
Martin Willi
2011-04-04 08:48:27 +02:00
parent 13eda8e903
commit c5a46f3b63
+34 -11
View File
@@ -43,22 +43,33 @@ struct private_curl_fetcher_t {
* Optional HTTP headers * Optional HTTP headers
*/ */
struct curl_slist *headers; struct curl_slist *headers;
/**
* Callback function
*/
fetcher_callback_t cb;
}; };
/** /**
* writes data into a dynamically resizeable chunk_t * Data to pass to curl callback
*/ */
static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data) typedef struct {
fetcher_callback_t cb;
void *user;
} cb_data_t;
/**
* Curl callback function, invokes fetcher_callback_t function
*/
static size_t curl_cb(void *ptr, size_t size, size_t nmemb, cb_data_t *data)
{ {
size_t realsize = size * nmemb; size_t realsize = size * nmemb;
data->ptr = (u_char*)realloc(data->ptr, data->len + realsize); if (data->cb(data->user, chunk_create(ptr, realsize)))
if (data->ptr)
{ {
memcpy(&data->ptr[data->len], ptr, realsize); return realsize;
data->len += realsize;
} }
return realsize; return 0;
} }
METHOD(fetcher_t, fetch, status_t, METHOD(fetcher_t, fetch, status_t,
@@ -66,9 +77,15 @@ METHOD(fetcher_t, fetch, status_t,
{ {
char error[CURL_ERROR_SIZE]; char error[CURL_ERROR_SIZE];
status_t status; status_t status;
chunk_t *result = userdata; cb_data_t data = {
.cb = this->cb,
.user = userdata,
};
*result = chunk_empty; if (this->cb == fetcher_default_callback)
{
*(chunk_t*)userdata = chunk_empty;
}
if (curl_easy_setopt(this->curl, CURLOPT_URL, uri) != CURLE_OK) if (curl_easy_setopt(this->curl, CURLOPT_URL, uri) != CURLE_OK)
{ /* URL type not supported by curl */ { /* URL type not supported by curl */
@@ -78,8 +95,8 @@ METHOD(fetcher_t, fetch, status_t,
curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE); curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE); curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT); curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT);
curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)append); curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)curl_cb);
curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void*)result); curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, &data);
if (this->headers) if (this->headers)
{ {
curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, this->headers); curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, this->headers);
@@ -147,6 +164,11 @@ METHOD(fetcher_t, set_option, bool,
va_arg(args, u_int)); va_arg(args, u_int));
break; break;
} }
case FETCH_CALLBACK:
{
this->cb = va_arg(args, fetcher_callback_t);
break;
}
default: default:
supported = FALSE; supported = FALSE;
break; break;
@@ -179,6 +201,7 @@ curl_fetcher_t *curl_fetcher_create()
}, },
}, },
.curl = curl_easy_init(), .curl = curl_easy_init(),
.cb = fetcher_default_callback,
); );
if (!this->curl) if (!this->curl)