Allow libcurl to rewind the upload buffer

This commit is contained in:
pooler 2012-06-11 18:42:12 +02:00
parent 66f14094d0
commit 364051e8f3

38
util.c
View file

@ -41,6 +41,7 @@ struct data_buffer {
struct upload_buffer { struct upload_buffer {
const void *buf; const void *buf;
size_t len; size_t len;
size_t pos;
}; };
struct header_info { struct header_info {
@ -153,18 +154,40 @@ static size_t upload_data_cb(void *ptr, size_t size, size_t nmemb,
struct upload_buffer *ub = user_data; struct upload_buffer *ub = user_data;
int len = size * nmemb; int len = size * nmemb;
if (len > ub->len) if (len > ub->len - ub->pos)
len = ub->len; len = ub->len - ub->pos;
if (len) { if (len) {
memcpy(ptr, ub->buf, len); memcpy(ptr, ub->buf + ub->pos, len);
ub->buf += len; ub->pos += len;
ub->len -= len;
} }
return len; return len;
} }
#if LIBCURL_VERSION_NUM >= 0x071200
static int seek_data_cb(void *user_data, curl_off_t offset, int origin)
{
struct upload_buffer *ub = user_data;
switch (origin) {
case SEEK_SET:
ub->pos = offset;
break;
case SEEK_CUR:
ub->pos += offset;
break;
case SEEK_END:
ub->pos = ub->len + offset;
break;
default:
return 1; /* CURL_SEEKFUNC_FAIL */
}
return 0; /* CURL_SEEKFUNC_OK */
}
#endif
static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data) static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data)
{ {
struct header_info *hi = user_data; struct header_info *hi = user_data;
@ -288,6 +311,10 @@ json_t *json_rpc_call(CURL *curl, const char *url,
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, upload_data_cb); curl_easy_setopt(curl, CURLOPT_READFUNCTION, upload_data_cb);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_data); curl_easy_setopt(curl, CURLOPT_READDATA, &upload_data);
#if LIBCURL_VERSION_NUM >= 0x071200
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, &seek_data_cb);
curl_easy_setopt(curl, CURLOPT_SEEKDATA, &upload_data);
#endif
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
@ -314,6 +341,7 @@ json_t *json_rpc_call(CURL *curl, const char *url,
upload_data.buf = rpc_req; upload_data.buf = rpc_req;
upload_data.len = strlen(rpc_req); upload_data.len = strlen(rpc_req);
upload_data.pos = 0;
sprintf(len_hdr, "Content-Length: %lu", sprintf(len_hdr, "Content-Length: %lu",
(unsigned long) upload_data.len); (unsigned long) upload_data.len);