Implementing CURL command using libcurl in C/C++

Barry barry at barrys-emacs.org
Fri Dec 13 08:29:47 EST 2019



> On 13 Dec 2019, at 08:53, Karthik Sharma <karthik.sharma at gmail.com> wrote:
> 
> The `CURL` command that I am using is shown below.
> 
>    curl -F 'file=@/home/karthik/Workspace/downloadfile.out' http://127.0.0.1:5000/file-upload --verbose
> 
> The response from the server is shown below.
> 
>    *   Trying 127.0.0.1...
>    * Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
>> POST /file-upload HTTP/1.1
>> Host: 127.0.0.1:5000
>> User-Agent: curl/7.47.0
>> Accept: */*
>> Content-Length: 663876790
>> Expect: 100-continue
>> Content-Type: multipart/form-data; boundary=------------------------4e96ef0714498bd7
>> 
>    < HTTP/1.1 100 Continue
>    * HTTP 1.0, assume close after body
>    < HTTP/1.0 201 CREATED
>    < Content-Type: application/json
>    < Content-Length: 46
>    < Server: Werkzeug/0.16.0 Python/3.5.2
>    < Date: Sat, 14 Dec 2019 07:05:15 GMT
>    < 
>    {
>      "message": "File successfully uploaded"
>    }
>    * Closing connection 0
> 
> I want to implement the same command in C/C++ using libcurl. I am using the following function.
> 
>    int FileUploadDownload::upload(const std::string &filename, const std::string &url) {
> 
>        CURL *curl;
>        CURLcode res;
>        struct stat file_info;
>        curl_off_t speed_upload, total_time;
>        FILE *fd;
> 
>        fd = fopen(filename.c_str(), "rb");
>        if(!fd) {
>            m_logger->errorf("unable to open file: %s\n",strerror(errno));
>            return 1;
>        }
>        if(fstat(fileno(fd), &file_info) != 0) {
>            m_logger->errorf("unable to get file stats: %s\n",strerror(errno));
>            return 2;
>        }
> 
>        std::cout << "filename : "<< filename << std::endl;
>        std::cout << "url : " << url << std::endl;
> 
>        curl = curl_easy_init();
>        if(curl) {
> 
>            curl_easy_setopt(curl, CURLOPT_URL,
>                             url.c_str());
> 
>            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, filename.c_str());
>            curl_easy_setopt(curl, CURLOPT_POST, 1L);
>            curl_easy_setopt(curl, CURLOPT_READDATA, fd);
>            curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
>                             (curl_off_t) file_info.st_size);
>            curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
> 
>            res = curl_easy_perform(curl);
>            if (res != CURLE_OK) {
>                m_logger->errorf("curl_easy_perform() failed: %s\n",curl_easy_strerror(res));
>            } else {
>                curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
>                curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
>                m_logger->infof("Speed: %" CURL_FORMAT_CURL_OFF_T " bytes/sec during %"
>                                CURL_FORMAT_CURL_OFF_T ".%06ld seconds\n",
>                                speed_upload,
>                                (total_time / 1000000), (long) (total_time % 1000000));
>            }
>        }
>        return 0;
>    }
> The below is the result that I get from the server.
> 
>    The result that I get is shown below.
>       *   Trying 127.0.0.1...
>    * Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
>> POST /file-upload HTTP/1.1
>> Host: 127.0.0.1:5000
>> User-Agent: curl/7.47.0
>> Accept: */*
>> Content-Length: 550
>> Expect: 100-continue
>> Content-Type: multipart/form-data; boundary=------------------------c8ef4837136fca99
>> 
>    < HTTP/1.1 100 Continue
>    * HTTP 1.0, assume close after body
>    < HTTP/1.0 201 CREATED
>    < Content-Type: application/json
>    < Content-Length: 46
>    < Server: Werkzeug/0.16.0 Python/3.5.2
>    < Date: Sat, 14 Dec 2019 07:09:47 GMT
>    < 
>    {
>      "message": "File successfully uploaded"
>    }
>    * Closing connection 0
> 
> 
> My aim is to mimic the curl command above in the C/C++ code below. What am I doing wrong ?

My guess Is that there is way to handle the 100 continue and you are missing that code. Or you need to tell curl not to use the send the “Expect: 100 Continue” header.

The purpose of the 100 Continue is to allow the server to refuse the POST.

https://tools.ietf.org/html/rfc7231#section-6.2.1

Barry

> -- 
> https://mail.python.org/mailman/listinfo/python-list
> 


More information about the Python-list mailing list