Command line curl can display response header by using -D
option, but I want to see what request header it is sending. How can I do that?
9 Answers
curl's -v
or --verbose
option shows the HTTP request headers, among other things. Here is some sample output:
$ curl -v http://google.com/
* About to connect() to google.com port 80 (#0)
* Trying 66.102.7.104... connected
* Connected to google.com (66.102.7.104) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.16.4 (i386-apple-darwin9.0) libcurl/7.16.4 OpenSSL/0.9.7l zlib/1.2.3
> Host: google.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Date: Thu, 15 Jul 2010 06:06:52 GMT
< Expires: Sat, 14 Aug 2010 06:06:52 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 1; mode=block
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
* Connection #0 to host google.com left intact
* Closing connection #0
A popular answer for displaying response headers, but OP asked about request headers.
curl -s -D - -o /dev/null http://example.com
-s
: Avoid showing progress bar-D -
: Dump headers to a file, but-
sends it to stdout-o /dev/null
: Ignore response body
This is better than -I
as it doesn't send a HEAD
request, which can produce different results.
It's better than -v
because you don't need so many hacks to un-verbose it.
I believe the command line switch you are looking for to pass to curl is -I
.
Example usage:
$ curl -I http://heatmiser.counterhack.com/zone-5-15614E3A-CEA7-4A28-A85A-D688CC418287
HTTP/1.1 301 Moved Permanently
Date: Sat, 29 Dec 2012 15:22:05 GMT
Server: Apache
Location: http://heatmiser.counterhack.com/zone-5-15614E3A-CEA7-4A28-A85A-D688CC418287/
Content-Type: text/html; charset=iso-8859-1
Additionally, if you encounter a response HTTP status code of 301, you might like to also pass a -L
argument switch to tell curl
to follow URL redirects, and, in this case, print the headers of all pages (including the URL redirects), illustrated below:
$ curl -I -L http://heatmiser.counterhack.com/zone-5-15614E3A-CEA7-4A28-A85A-D688CC418287
HTTP/1.1 301 Moved Permanently
Date: Sat, 29 Dec 2012 15:22:13 GMT
Server: Apache
Location: http://heatmiser.counterhack.com/zone-5-15614E3A-CEA7-4A28-A85A-D688CC418287/
Content-Type: text/html; charset=iso-8859-1
HTTP/1.1 302 Found
Date: Sat, 29 Dec 2012 15:22:13 GMT
Server: Apache
Set-Cookie: UID=b8c37e33defde51cf91e1e03e51657da
Location: noaccess.php
Content-Type: text/html
HTTP/1.1 200 OK
Date: Sat, 29 Dec 2012 15:22:13 GMT
Server: Apache
Content-Type: text/html
You get a nice header output with the following command:
curl -L -v -s -o /dev/null google.de
-L, --location
follow redirects-v, --verbose
more output, indicates the direction-s, --silent
don't show a progress bar-o, --output /dev/null
don't show received body
Or the shorter version:
curl -Lvso /dev/null google.de
Results in:
* Rebuilt URL to: google.de/
* Trying 2a00:1450:4008:802::2003...
* Connected to google.de (2a00:1450:4008:802::2003) port 80 (#0)
> GET / HTTP/1.1
> Host: google.de
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.de/
< Content-Type: text/html; charset=UTF-8
< Date: Fri, 12 Aug 2016 15:45:36 GMT
< Expires: Sun, 11 Sep 2016 15:45:36 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 218
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
<
* Ignoring the response-body
{ [218 bytes data]
* Connection #0 to host google.de left intact
* Issue another request to this URL: 'http://www.google.de/'
* Trying 2a00:1450:4008:800::2003...
* Connected to www.google.de (2a00:1450:4008:800::2003) port 80 (#1)
> GET / HTTP/1.1
> Host: www.google.de
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Fri, 12 Aug 2016 15:45:36 GMT
< Expires: -1
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=ISO-8859-1
< P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info."
< Server: gws
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
< Set-Cookie: NID=84=Z0WT_INFoDbf_0FIe_uHqzL9mf3DMSQs0mHyTEDAQOGY2sOrQaKVgN2domEw8frXvo4I3x3QVLqCH340HME3t1-6gNu8R-ArecuaneSURXNxSXYMhW2kBIE8Duty-_w7; expires=Sat, 11-Feb-2017 15:45:36 GMT; path=/; domain=.google.de; HttpOnly
< Accept-Ranges: none
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
<
{ [11080 bytes data]
* Connection #1 to host www.google.de left intact
As you can see curl
outputs both the outgoing and the incoming headers and skips the bodydata althought telling you how big the body is.
Additionally for every line the direction is indicated so that it is easy to read. I found it particular useful to trace down long chains of redirects.
A command like the one below will show three sections: request headers, response headers and data (separated by CRLF). It avoids technical information and syntactical noise added by curl.
curl -vs www.stackoverflow.com 2>&1 | sed '/^* /d; /bytes data]$/d; s/> //; s/< //'
The command will produce the following output:
GET / HTTP/1.1
Host: www.stackoverflow.com
User-Agent: curl/7.54.0
Accept: */*
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=UTF-8
Location: https://stackoverflow.com/
Content-Length: 149
Accept-Ranges: bytes
Date: Wed, 16 Jan 2019 20:28:56 GMT
Via: 1.1 varnish
Connection: keep-alive
X-Served-By: cache-bma1622-BMA
X-Cache: MISS
X-Cache-Hits: 0
X-Timer: S1547670537.588756,VS0,VE105
Vary: Fastly-SSL
X-DNS-Prefetch-Control: off
Set-Cookie: prov=e4b211f7-ae13-dad3-9720-167742a5dff8; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a HREF="https://stackoverflow.com/">here</a></body>
Description:
-vs
- add headers (-v) but remove progress bar (-s)2>&1
- combine stdout and stderr into single stdoutsed
- edit response produced by curl using the commands below/^* /d
- remove lines starting with '* ' (technical info)/bytes data]$/d
- remove lines ending with 'bytes data]' (technical info)s/> //
- remove '> ' prefixs/< //
- remove '< ' prefix
I had to overcome this problem myself, when debugging web applications. -v
is great, but a little too verbose for my tastes. This is the (bash-only) solution I came up with:
curl -v http://example.com/ 2> >(sed '/^*/d')
This works because the output from -v
is sent to stderr, not stdout. By redirecting this to a subshell, we can sed
it to remove lines that start with *
. Since the real output does not pass through the subshell, it is not affected. Using a subshell is a little heavy-handed, but it's the easiest way to redirect stderr to another command. (As I noted, I'm only using this for testing, so it works fine for me.)
the -v option for curl is too verbose in the error output which contains the leading *
(status line) or >
(request head field) or <
(response head field). to get only the request head field:
curl -v -sS www.stackoverflow.com 2>&1 >/dev/null | grep '>' | cut -c1-2 --complement
to get only the request head field:
curl -v -sS www.stackoverflow.com 2>&1 >/dev/null | grep '<' | cut -c1-2 --complement
or to dump it into /tmp/test.txt
file with the -D option
curl -D /tmp/test.txt -sS www.stackoverflow.com > /dev/null
in order to filter the -v
output, you should direct the error output to terminal and the std output to /dev/null, the -s option is to forbid the progress metering
If you want more alternatives, You can try installing a Modern command line HTTP client like httpie which is available for most of the Operating Systems with package managers like brew, apt-get, pip, yum etc
eg:- For OSX
brew install httpie
Then you can use it on command line with various options
http GET https://www.google.com
curl --head http://google.com
will do the same as the-I
flag :) – Abel Terefe--head
/-I
: not all servers respond exactly the same toHEAD
requests (for example,Content-Encoding
would be missing if you were attempting to verify that the body would be gzipped) and not all servers supportHEAD
.-v
is usually the safer choice. – cfeduke