Code

Merge branch 'maint'
[git.git] / remote-curl.c
index 8f169ddca0fd465b332a6044e0a05a628fa7b825..70fdceade5b0d1f13be2f9f8bba3a310d0af8182 100644 (file)
@@ -290,6 +290,7 @@ struct rpc_state {
        int out;
        struct strbuf result;
        unsigned gzip_request : 1;
+       unsigned initial_buffer : 1;
 };
 
 static size_t rpc_out(void *ptr, size_t eltsize,
@@ -300,6 +301,7 @@ static size_t rpc_out(void *ptr, size_t eltsize,
        size_t avail = rpc->len - rpc->pos;
 
        if (!avail) {
+               rpc->initial_buffer = 0;
                avail = packet_read_line(rpc->out, rpc->buf, rpc->alloc);
                if (!avail)
                        return 0;
@@ -314,6 +316,29 @@ static size_t rpc_out(void *ptr, size_t eltsize,
        return avail;
 }
 
+#ifndef NO_CURL_IOCTL
+curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)
+{
+       struct rpc_state *rpc = clientp;
+
+       switch (cmd) {
+       case CURLIOCMD_NOP:
+               return CURLIOE_OK;
+
+       case CURLIOCMD_RESTARTREAD:
+               if (rpc->initial_buffer) {
+                       rpc->pos = 0;
+                       return CURLIOE_OK;
+               }
+               fprintf(stderr, "Unable to rewind rpc post data - try increasing http.postBuffer\n");
+               return CURLIOE_FAILRESTART;
+
+       default:
+               return CURLIOE_UNKNOWNCMD;
+       }
+}
+#endif
+
 static size_t rpc_in(const void *ptr, size_t eltsize,
                size_t nmemb, void *buffer_)
 {
@@ -370,8 +395,13 @@ static int post_rpc(struct rpc_state *rpc)
                 */
                headers = curl_slist_append(headers, "Expect: 100-continue");
                headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
+               rpc->initial_buffer = 1;
                curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);
                curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);
+#ifndef NO_CURL_IOCTL
+               curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);
+               curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);
+#endif
                if (options.verbosity > 1) {
                        fprintf(stderr, "POST %s (chunked)\n", rpc->service_name);
                        fflush(stderr);