cURL / Mailing Lists / curl-library / Single Mail

curl-library

Chunked POST appears to be empty

From: Erik Ronström <erik.ronstrom_at_doremir.com>
Date: Sun, 30 Aug 2015 10:40:07 +0200

Hi curlers,

I’m trying to do a chunked POST, taking the post-callback example as a starting point. However, it appears that unless I provide a content length (with CURLOPT_POSTFIELDSIZE), the post data is being sent. The read callback is being called, but no body data is actually being sent to the server.

Below is the code used, and its output. libcurl says the request is 65525 bytes, but RequestBin says ”Form/Post Parameters: None” and ”Raw Body: None”. (http://requestb.in/1glodpr1?inspect#1mtrcf)

What am I missing here? Probably something trivial, but I cannot figure it out!

Many thanks
Erik

static size_t _upload_read_function(void *ptr, size_t size, size_t nmemb, void *data)
{
    struct WriteThis *pooh = (struct WriteThis *)data;
    size_t max_bytes = size*nmemb;
    if (max_bytes < 1)
        return 0;

    if (pooh->sizeleft) {
        size_t bytes = max_bytes < pooh->sizeleft ? max_bytes : pooh->sizeleft;
        memcpy(ptr, pooh->readptr, bytes);
        pooh->readptr += bytes;
        pooh->sizeleft -= bytes;
        printf("upload_read_function: %zu bytes (%ld left)\n", bytes, pooh->sizeleft);
        return size*nmemb;
    }

    return 0;
}

int main(int argc, char const *argv[])
{
  curl_version_info_data *curl_version = curl_version_info(CURLVERSION_NOW);
  printf("libcurl: %s\n", curl_version->version);
  
  size_t buffer_size = ... ;
  unsigned char *ogg_buffer = ... ;
  
  struct WriteThis pooh;
  pooh.readptr = ogg_buffer;
  pooh.sizeleft = buffer_size;
  
  CURL *curl = curl_easy_init();
  if (curl) {
      curl_easy_setopt(curl, CURLOPT_URL, "http://requestb.in/1glodpr1");
      curl_easy_setopt(curl, CURLOPT_POST, 1L);
      struct curl_slist *chunk = NULL;
      chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
      curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
      // curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, buffer_size); // <-- if this line is enabled, data is sent correctly
      curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
      curl_easy_setopt(curl, CURLOPT_READFUNCTION, _upload_read_function);
      curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
      CURLcode res = curl_easy_perform(curl);
      
      if (res == CURLE_OK) {
          long response_code;
          double request_size;
          curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
          curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &request_size);
          printf("Server responeded with %d, request was %f bytes\n", response_code, request_size);
      } else {
          fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
      }
      
      // Cleanup
      curl_slist_free_all(chunk);
      curl_easy_cleanup(curl);
  }
  

libcurl: 7.37.1
* Hostname was NOT found in DNS cache
* Trying 54.225.217.107...
* Connected to requestb.in (54.225.217.107) port 80 (#0)
> POST /1glodpr1 HTTP/1.1
Host: requestb.in
Accept: */*
Transfer-Encoding: chunked
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

< HTTP/1.1 100 Continue
upload_read_function: 16372 bytes (48988 left)
upload_read_function: 16372 bytes (32616 left)
upload_read_function: 16372 bytes (16244 left)
upload_read_function: 16244 bytes (0 left)
< HTTP/1.1 200 OK
< Connection: close
* Server gunicorn/19.3.0 is not blacklisted
< Server: gunicorn/19.3.0
< Date: Sun, 30 Aug 2015 08:33:07 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 2
< Sponsored-By: https://www.runscope.com
< Via: 1.1 vegur
<
* Closing connection 0
ok
Server responeded with 200, request was 65525.000000 bytes

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2015-08-30