Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

libcurl delays for 1 second before uploading data, command-line curl does not

I am using libcurl to send an API command to a local service (i.e. on 127.0.0.1).

The program is intended to replace a shell script (that uses the curl program.)

Everything is working, except that there is a 1-second delay somewhere, i.e 1 second elapses from the time I call curl_easy_perform() to when my read callback function is first called.

The C program is using these options (error checking & callback code omitted):

curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:12345/x");
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
curl_easy_setopt(curl, CURLOPT_INFILESIZE, (long)getLengthOfCommandObject());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, &myReadFunction);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &myWriteFunction);

But if I run curl from the shell like this:

$ curl --data-binary '<command>' http://127.0.0.1:12345/x

it sends the request immediately, without suffering from the 1-second delay.

What might be causing the delay, and is there an option I can set to prevent it?


Edit The server is based on mongoose

like image 584
finnw Avatar asked Jun 29 '13 17:06

finnw


People also ask

Does cURL use libcurl?

cURL is a command-line tool for getting or sending data including files using URL syntax. Since cURL uses libcurl, it supports every protocol libcurl supports. cURL supports HTTPS and performs SSL certificate verification by default when a secure protocol is specified such as HTTPS.

What does the cURL command do?

cURL, which stands for client URL, is a command line tool that developers use to transfer data to and from a server. At the most fundamental, cURL lets you talk to a server by specifying the location (in the form of a URL) and the data you want to send.

What protocol does cURL use?

curl is a tool to transfer data from or to a server, using one of the supported protocols (HTTP, HTTPS, FTP, FTPS, GOPHER, DICT, TELNET, LDAP or FILE). The command is designed to work without user interaction.

Which cURL partial command represents the post command?

POSTing with curl's -d option will include a default header that looks like: Content-Type: application/x-www-form-urlencoded .


1 Answers

The reason for the delay was:

  • libcurl was sending an Expect: 100-Continue header
  • The server (which is based on mongoose) is not configured to send 100 Continue responses automatically.
  • libcurl waits up to 1 second for this response. If it does not receive it after this time then it proceeds to send the request body anyway.

A solution on the client side is to disable the Expect header like so:

headers = curl_slist_append(NULL, "Expect:");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// ...
result = curl_easy_perform(curl);
curl_slist_free_all(headers);

Equivalent fix for PHP client and related PHP question

like image 185
finnw Avatar answered Sep 28 '22 00:09

finnw