As described earlier, each HTTP transfer starts with curl sending a HTTP request. That request consists of a request line and a number of request headers, and this chapter details how you can modify all of those.
The first line of the request includes the method - sometimes also referred to as the verb. When doing a simple GET request as this command line would do:
curl http://example.com/file
…the initial request line looks like this:
GET /file HTTP/1.1
You can tell curl to change the method into something else by using the -X
or --request
command-line options followed by the actual method name. You
can, for example, send a DELETE
instead of GET
like this:
curl http://example.com/file -X DELETE
This command-line option only changes the text in the outgoing request, it
does not change any behavior. This is particularly important if you, for
example, ask curl to send a HEAD with -X
, as HEAD is specified to send all
the headers a GET response would get but never send a response body, even if
the headers otherwise imply that one would come. So, adding -X HEAD
to a
command line that would otherwise do a GET will cause curl to hang, waiting
for a response body that will not come.
When asking curl to perform HTTP transfers, it will pick the correct method
based on the option so you should only rarely have to explicitly ask for
it with -X
. It should also be noted that when curl follows redirects like
asked to with -L
, the request method set with -X
will be sent even on the
subsequent redirects.
In the example above, you can see how the path section of the URL gets turned
into /file
in the request line. That is called the request target. That's
the resource this request will interact with. Normally this request target is
extracted from the URL and then used in the request and as a user you do not
need to think about it.
In some rare circumstances, user may want to go creative and change this
request target in ways that the URL does not really allow. For example, the
HTTP OPTIONS method has a specially define request target for magic that
concerns the server and not a specific path, and it uses *
for that. Yes,
a single asterisk. There's no way to specify a URL for this, so if you want to
pass a single asterisk in the request target to a server, like for OPTIONS,
you have to do it like this:
curl -X OPTIONS --request-target "*" http://example.com/
A URL may contain an anchor, also known as a fragment, which is written with a
pound sign and string at the end of the URL. Like for example
http://example.com/foo.html#here-it-is
. That fragment part, everything from
the pound/hash sign to the end of the URL, is only intended for local use and
will not be sent over the network. curl will simply strip that data off and
discard it.
In a HTTP request, after the initial request-line, there will typically follow
a number of request headers. That's a set of name: value
pairs that ends
with a blank line that separates the headers from the following request body
(that sometimes is empty).
curl will by default and on its own account pass a few headers in requests,
like for example Host:
, Accept:
, User-Agent:
and a few others that may
depend on what the user asks curl to do.
All headers set by curl itself can be overridden, replaced if you will, by the
user. You just then tell curl's -H
or --header
the new header to use and
it will then replace the internal one if the header field matches one of those
headers, or it will add the specified header to the list of headers to send in
the request.
To change the Host:
header, do this:
curl -H "Host: test.example" http://example.com/
To add a Elevator: floor-9
header, do this:
curl -H "Elevator: floor-9" http://example.com/
If you just want to delete an internally generated header, just give it to curl without a value, just nothing on the right side of the colon.
To switch off the User-Agent:
header, do this:
curl -H "User-Agent:" http://example.com/
Finally, if you then truly want to add a header with no contents on the right side of the colon (which is a rare thing), the magic marker for that is to instead end the header field name with a semicolon. Like this:
curl -H "Empty;" http://example.com
When a user clicks on a link on a web page and the browser takes the user away
to the next URL, it will send the new URL a Referer:
header in the new
request telling it where it came from. That is the referer header. And yes,
referer is misspelled but that's how it is supposed to be!
With curl you set the referer header with -e
or --referer
, like this:
curl --referer http://comes-from.example.com https://www.example.com/
The User-Agent is a header that each client can set in the request to inform the server which user-agent it is. Sometimes servers will look at this header and determine how to act based on its contents.
The default header value is 'curl/[version]', as in User-Agent: curl/7.54.1
for curl version 7.54.1.
You can set any value you like, using the option -A
or --user-agent
plus
the string to use or, as it's just a header, -H "User-Agent: foobar/2000"
.
As comparison, a recent test version of Firefox on a Linux machine sent this User-Agent header:
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0
HTTP supports conditional requests. They are requests that contain a condition in the sense that it asks the server to only deliver a response body if the associated condition evaluates true.
A useful condition is time. For example, ask the server to only deliver a response if the resource has been modified after a particular time:
curl --time-cond "1 Jul 2011" https://www.example.org/file.html
curl can also reverse the condition. Only get the file if it is older than the given date by prefixing the date with a dash:
curl --time-cond "-1 Jul 2011" https://www.example.org/file.html
The date parser is liberal and will accept most formats you can write the date, and you can of course also specify it complete with a time:
curl --time-cond "Sun, 12 Sep 2004 15:05:58 -0700" https://www.example.org/file.html
curl can also get the time stamp off a local file as a shortcut. No need to download the file again if it has not changed on the server, right? If the string does not match a time or date, curl checks if there's a file named like that, and if so gets the time from its modification time.
curl --time-cond file https://www.example.org/file.html -o file