2

Even though I set in header Content-Lenght I'm getting 411 error. I'm trying to send PUT request. struct curl_slist *headers = NULL;

curl = curl_easy_init();
std::string paramiters =
        "<data_file><archive>false</archive><data_type_id>0a7a184a-dcc6-452a-bcd3-52dbd2a83ea2</data_type_id><data_file_name>backwardstep.stt</data_file_name><description>connectionfile</description><job_id>264cf297-3bc7-42e1-8edc-5e2948ee62b6</job_id></data_file>";

if (curl) {

    headers = curl_slist_append(headers, "Accept: */*");
    headers = curl_slist_append(headers, "Content-Length: 123");
    headers = curl_slist_append(headers, "Content-Type: application/xml");


    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");

    curl_easy_setopt(curl, CURLOPT_URL,
            "..url/data_files/new/link_upload.xml");

    curl_easy_setopt(curl, CURLOPT_USERPWD, "kolundzija@example.ch:PASS");

    curl_easy_setopt(curl, CURLOPT_HEADER, 1L);

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, paramiters.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE,
            strlen(paramiters.c_str()));

    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);

    res = curl_easy_perform(curl);

and this is response from SERVER:

Host: cloud...
Transfer-Encoding: chunked
Accept: */*
Content-Length: 123
Content-Type: application/xml
Expect: 100-continue

* The requested URL returned error: 411 Length Required
* Closing connection #0

2 Answers2

0

Ok, I honestly can not find your error. But you should have an example from the curl website (first google hit for "curl put c code"): http://curl.haxx.se/libcurl/c/httpput.html

Maybe mixing the easy and advanced interface confuses curl.

What confuses me are the options CURLOPT_POSTFIELDS and CURLOPT_POSTFIELDSIZE. This is a put request, so why are they even there? With PUT the arguments are in the URL. The body is opaque, at least from the perspective of HTTP.

rioki
  • 5,988
  • 5
  • 32
  • 55
  • Hi I couldn't find any example where u send data with PUT(not file just string). Then someone wrote here that you can use CURLOPT_CUSTOMREQUEST "PUT" + postfields method.This is why I've tried like this. – user3082058 Dec 09 '13 at 11:13
  • http://stackoverflow.com/questions/7569826/send-string-in-put-request-with-libcurl – user3082058 Dec 09 '13 at 11:29
  • from console it works using CURL so I guess its problem since its not sending body. If you have any idea how to send sting with PUT pls dont hasitate to tell :) – user3082058 Dec 09 '13 at 11:37
  • only way how it works is to save sting in the file and then do according the libcurl example. – user3082058 Dec 09 '13 at 11:57
0

You DON'T need to use a file and do NOT use custom requests, INstead set the UPLOAD and PUT options as it is specified in the documentation here:

http://curl.haxx.se/libcurl/c/httpput.html

Unlike the example above where they use a file as your data structure you can USE ANYTHING to hold your data.It's all on using a callback function with this option: CURLOPT_READFUNCTION The difference is made on how you set your callback function which only has to do two things: 1.-measure the size of your payload (your data) in bytes 2.-copy the data to the memory address that curl passes to the callback (that is the first argument on your call back function, the FIRST void pointer in this definition)

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)

That is the ptr argument.

Use memcpy to copy the data.

Take a look at this link. I ran into the same problem as you and was able to solve it using this approach,one thing YOU need to keep in mind is that you ALSO need to set the file size before sending the curl request.

How do I send long PUT data in libcurl without using file pointers?

Use CURLOPT_INFILESIZE or CURLOPT_INFILESIZE_LARGE for that.

Community
  • 1
  • 1
eco
  • 1,254
  • 1
  • 12
  • 22