Browse Source

Allow libcurl to rewind the upload buffer

pooler 13 years ago
parent
commit
7af9720199
1 changed files with 34 additions and 5 deletions
  1. 34 5
      util.c

+ 34 - 5
util.c

@@ -78,6 +78,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 {
@@ -177,18 +178,41 @@ static size_t upload_data_cb(void *ptr, size_t size, size_t nmemb,
 		pool->lp_active = true;
 		pool->lp_active = true;
 	}
 	}
 
 
-	if (len > ub->len)
-		len = ub->len;
+	if (len > ub->len - ub->pos)
+		len = ub->len - ub->pos;
 
 
 	if (len) {
 	if (len) {
-		memcpy(ptr, ub->buf, len);
-		ub->buf += len;
-		ub->len -= len;
+		memcpy(ptr, ub->buf + ub->pos, len);
+		ub->pos += 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 json_rpc_call_state * const state = user_data;
+	struct upload_buffer * const ub = &state->upload_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;
@@ -461,6 +485,10 @@ void json_rpc_call_async(CURL *curl, const char *url,
 	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &state->all_data);
 	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &state->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, state);
 	curl_easy_setopt(curl, CURLOPT_READDATA, state);
+#if LIBCURL_VERSION_NUM >= 0x071200
+	curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, &seek_data_cb);
+	curl_easy_setopt(curl, CURLOPT_SEEKDATA, state);
+#endif
 	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &state->curl_err_str[0]);
 	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &state->curl_err_str[0]);
 	curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
 	curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
 	curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, resp_hdr_cb);
 	curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, resp_hdr_cb);
@@ -486,6 +514,7 @@ void json_rpc_call_async(CURL *curl, const char *url,
 
 
 	state->upload_data.buf = rpc_req;
 	state->upload_data.buf = rpc_req;
 	state->upload_data.len = strlen(rpc_req);
 	state->upload_data.len = strlen(rpc_req);
+	state->upload_data.pos = 0;
 	sprintf(len_hdr, "Content-Length: %lu",
 	sprintf(len_hdr, "Content-Length: %lu",
 		(unsigned long) state->upload_data.len);
 		(unsigned long) state->upload_data.len);
 	sprintf(user_agent_hdr, "User-Agent: %s", PACKAGE"/"VERSION);
 	sprintf(user_agent_hdr, "User-Agent: %s", PACKAGE"/"VERSION);