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