A HTTP request is what curl sends to the server when it tells the server what to do. When it wants to get data or send data. All transfers involving HTTP starts with a HTTP request.
A HTTP request contains a method, a path, HTTP version and a set of request headers. And of course a libcurl using application can tweak all those fields.
Every HTTP request contains a "method", sometimes referred to as a "verb". It is usually something like GET, HEAD, POST or PUT but there are also more esoteric ones like DELETE, PATCH and OPTIONS.
Usually when you use libcurl to set up and perform a transfer the specific request method is implied by the options you use. If you just ask for a URL, it means the method will be
GET while if you set for example
CURLOPT_POSTFIELDS that will make libcurl use the
POST method. If you set
CURLOPT_UPLOAD to true, libcurl will send a
PUT method in its HTTP request and so on. Asking for
CURLOPT_NOBODY will make libcurl use
However, sometimes those default HTTP methods are not good enough or simply not the ones you want your transfer to use. Then you can instruct libcurl to use the specific method you like with
CURLOPT_CUSTOMREQUEST. For example, you want to send a
DELETE method to the URL of your choice:
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.txt");
The CURLOPT_CUSTOMREQUEST setting should only be the single keyword to use as method in the HTTP request line. If you want to change or add additional HTTP request headers, see the following section.
When libcurl issues HTTP requests as part of performing the data transfers you've asked it to, it will of course send them off with a set of HTTP headers that are suitable for fulfilling the task given to it.
If just given the URL "http://localhost/file1.txt", libcurl 7.51.0 would send the following request to the server:
GET /file1.txt HTTP/1.1Host: localhostAccept: */*
If you would instead instruct your application to also set
CURLOPT_POSTFIELDS to the string "foobar" (6 letters, the quotes only used for visual delimiters here), it would send the following headers:
POST /file1.txt HTTP/1.1Host: localhostAccept: */*Content-Length: 6Content-Type: application/x-www-form-urlencoded
If you are not pleased with the default set of headers libcurl sends, the application has the power to add, change or remove headers in the HTTP request.
To add a header that would not otherwise be in the request, add it with
CURLOPT_HTTPHEADER. Suppose you want a header called
Name: that contains
struct curl_slist *list = NULL;list = curl_slist_append(list, "Name: Mr Smith");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);curl_easy_perform(curl);curl_slist_free_all(list); /* free the list again */
If one of those default headers are not to your satisfaction you can alter them. Like if you think the default
Host: header is wrong (even though it is derived from the URL you give libcurl), you can tell libcurl your own:
struct curl_slist *list = NULL;list = curl_slist_append(list, "Host: Alternative");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);curl_easy_perform(curl);curl_slist_free_all(list); /* free the list again */
When you think libcurl uses a header in a request that you really think it should not, you can easily tell it to just remove it from the request. Like if you want to take away the
Accept: header. Just provide the header name with nothing to the right sight of the colon:
struct curl_slist *list = NULL;list = curl_slist_append(list, "Accept:");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);curl_easy_perform(curl);curl_slist_free_all(list); /* free the list again */
As you may then have noticed in the above sections, if you try to add a header with no contents on the right side of the colon, it will be treated as a removal instruction and it will instead completely inhibit that header from being sent. If you instead truly want to send a header with zero contents on the right side, you need to use a special marker. You must provide the header with a semicolon instead of a proper colon. Like
Header;. So if you want to add a header to the outgoing HTTP request that is just
Moo: with nothing following the colon, you could write it like:
struct curl_slist *list = NULL;list = curl_slist_append(list, "Moo;");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);curl_easy_perform(curl);curl_slist_free_all(list); /* free the list again */
Referer: header (yes, it is misspelled) is a standard HTTP header that tells the server from which URL the user-agent was directed from when it arrived at the URL it now requests. It is a normal header so you can set it yourself with the
CURLOPT_HEADER approach as shown above, or you can use the shortcut known as
CURLOPT_REFERER. Like this:
curl_easy_setopt(curl, CURLOPT_REFERER, "https://example.com/fromhere/");curl_easy_perform(curl);
When libcurl is asked to follow redirects itself with the
CURLOPT_FOLLOWLOCATION option, and you still want to have the
Referer: header set to the correct previous URL from where it did the redirect, you can ask libcurl to set that by itself:
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1L);curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/redirected.cgi");curl_easy_perform(curl);