ChatGPT解决这个技术问题 Extra ChatGPT

How can I see the request headers made by curl when sending a request to the server?

I want to see the request headers made by curl when I am sending a request to the server. How can I check that?

this url may be helpful. helloacm.com/curl

E
Elijah Lynn

I think curl --verbose/-v is the easiest. It will spit out the request headers (lines prefixed with '>') without having to write to a file:

$ curl -v -I -H "Testing: Test header so you see this works" http://stackoverflow.com/
* About to connect() to stackoverflow.com port 80 (#0)
*   Trying 69.59.196.211... connected
* Connected to stackoverflow.com (69.59.196.211) port 80 (#0)
> HEAD / HTTP/1.1
> User-Agent: curl/7.16.3 (i686-pc-cygwin) libcurl/7.16.3 OpenSSL/0.9.8h zlib/1.2.3 libssh2/0.15-CVS
> Host: stackoverflow.com
> Accept: */*
> Testing: Test header so you see this works
>
< HTTP/1.0 200 OK
...

curl -v -D - stackoverflow.com -o /dev/null (in order to do not display whole site's content, just headers)
curl -Ivs http://example.com > /dev/null : -I for a HEAD request, -v to show sent headers, -s to hide progress bar, > /dev/null to show only the -v output, avoiding duplication.
@PiotrekDe -D - was neat, but was not useful to me as it simply duplicated the headers that -v already displayed. If you want them unprefixed for automated machine consumption, then maybe it would be better in that case, but I only wanted to glimpse at what a problem was in more detail.
There are two very helpful feature of the "verbose" flag: first, it also prints the TLS handshake process when accessing website through HTTPS, such as curl -v https://www.example.com; second, it also prints the CONNECT request if you are visiting the site through HTTP proxy, such as curl --proxy my-proxy:8080 http://www.example.com. I believe it would help more users if some examples of these two features are mentioned in this answer.
TL;DR: Don't use -I In the modern world, when people ask about seeing headers, they are probably talking about APIs. And if you use that "I use -I to see the headers with my Apache webserver" mentality, you are going to waste a lot of time developing against a HEAD method when you probably mean to use GET. Stop telling people to use -I. If they want HEAD, use -X HEAD (TWSS)
M
Mikko Rantalainen

The question did not specify if command line command named curl was meant or the whole cURL library.

The following PHP code using cURL library uses first parameter as HTTP method (e.g. "GET", "POST", "OPTIONS") and second parameter as URL.

<?php
$ch = curl_init();
$f = tmpfile(); # will be automatically removed after fclose()
curl_setopt_array($ch, array(
    CURLOPT_CUSTOMREQUEST  => $argv[1],
    CURLOPT_URL            => $argv[2], 
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_FOLLOWLOCATION => 0,
    CURLOPT_VERBOSE        => 1,
    CURLOPT_HEADER         => 0,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_STDERR         => $f,
));
$response = curl_exec($ch);
fseek($f, 0);
echo fread($f, 32*1024); # output up to 32 KB cURL verbose log
fclose($f);
curl_close($ch);
echo $response;

Example usage:

php curl-test.php OPTIONS https://google.com

Note that the results are nearly identical to following command line

curl -v -s -o - -X OPTIONS https://google.com

This is the best answer, because the file used in this method contains everything in curl_getinfo() referenced below, along with more details on both the request and the response.
You can use CURLOPT_WRITEHEADER for the header information and CURLOPT_FILE for the whole transfer
Bear in mind that if the connection is refused files that were specified with CURLOPT_WRITEHEADER and CURLOPT_FILE are empty.
Who said anything about using php?
Ive upvoted your answer because while the question was not php related, your php based answer pointed me into the right direction for solving my own issue with sending a bearer token. Thank you. I stated my reason here only in the vain attempt to have this question show up in future google searches for php devs with a similar issue.
J
Jonathan Leffler

The --trace-ascii option to curl will show the request headers, as well as the response headers and response body.

For example, the command

curl --trace-ascii curl.trace http://www.google.com/ 

produces a file curl.trace that starts as follows:

== Info: About to connect() to www.google.com port 80 (#0)
== Info:   Trying 209.85.229.104... == Info: connected
== Info: Connected to www.google.com (209.85.229.104) port 80 (#0)
=> Send header, 145 bytes (0x91)
0000: GET / HTTP/1.1
0010: User-Agent: curl/7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3
0050:  OpenSSL/0.9.7l zlib/1.2.3
006c: Host: www.google.com
0082: Accept: */*
008f: 

It also got a response (a 302 response, to be precise but irrelevant) which was logged.

If you only want to save the response headers, use the --dump-header option:

curl -D file url
curl --dump-header file url

If you need more information about the options available, use curl --help | less (it produces a couple hundred lines of output but mentions a lot of options). Or find the manual page where there is more explanation of what the options mean.


-D gives you the response headers (as does -I, but to STDIN). The question asked for the request headers.
w
wkm

The only way I managed to see my outgoing headers (curl with php) was using the following options:

curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);

Getting your debug info:

$data = curl_exec($ch);
var_dump($data);
var_dump(curl_getinfo($ch));

For me that appeared to be the response header not the outgoing header.
var_dump $data will return the response headers as well as the response body. The var_dump curl_getinfo($ch) will give you the request headers.
CURLOPT_HEADER is the response header - CURLINFO_HEADER_OUT is the request header. This is what the OP is asking for :)
D
Daniel Stenberg

curl --trace-ascii {filename} or use a single dash instead of file name to get it sent to stdout:

curl --trace-ascii - {URL}

CURLOPT_DEBUGFUNCTION if you're using libcurl

This shows you everything curl sends and receives, with some extra info thrown in.


This is very verbose, but certainly shows you everything you should need to know.
This is the only answer that helped me. Some external script was setting some proxy settings and this told me the proxy was being used when it shouldn't have been. Verbose output did not mention the proxy.
G
GregT

I tried the answers here and found that the most useful and easiest one is not listed as an answer yet, but it is:

curl -v https://example.com/path

This prints out the REQUEST headers as well as the RESPONSE headers plus other useful such as the SSL cert and whether an existing TCP connection was reused. the -v flag can be combined with other flags, of course, such as to follow redirects and prompt for HTTP authentication:

curl -vL --user my_username https://example.com/path

Hope this helps.


It is listed at the topmost place
i
igorpcholkin

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 stdout

sed - 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 '> ' prefix

s/< // - remove '< ' prefix


H
Haravikk

I know this is a little late, but my favoured method for doing this is netcat, as you get exactly what curl sent; this can differ from the --trace or --trace-ascii options which won't show non-ASCII characters properly (they just show as dots or need to be decoded).

You can do this as very easily by opening two terminal windows, in the first type:

nc -l localhost 12345

This opens a listening process on port 12345 of your local machine.

In the second terminal window enter your curl command, for example:

curl --form 'foo=bar' localhost:12345

In the first terminal window you will see exactly what curl sent in the request.

Now of course nc won't send anything in response (unless you type it in yourself), so you will need to interrupt the curl command (control-c) and repeat the process for each test.

However, this is a useful option for simply debugging your request, as you're not involving a round-trip anywhere, or producing bogus, iterative requests somewhere until you get it right; once you're happy with the command, simply redirect it to a valid URL and you're good to go.

You can do the same for any cURL library as well, simply edit your request to point to the local nc listener until you're happy with it.


Upvote this. It's the cleanest way to see with complete confidence exactly what curl is sending. Most people answered some variation on curl -v which basically works, but also dumps tons of other noise, especially for HTTPS.
I totally agree with @Yitz. If you are just interested in what was sent by curl (and don't care about the networking details), this is the best way to go.
M
Machavity

dump the headers in one file and the payload of the response in a different file

curl -k -v -u user:pass  "url" --trace-ascii headers.txt >> response.txt

j
juancholas
curl -s -v -o/dev/null -H "Testheader: test" http://www.example.com

You could also use -I option if you want to send a HEAD request and not a GET request.


T
Tsvetan Filev

Here is my http client in php to make post queries with cookies included:

function http_login_client($url, $params = "", $cookies_send = "" ){

    // Vars
    $cookies = array();
    $headers = getallheaders();

    // Perform a http post request to $ur1 using $params
    $ch = curl_init($url);
    $options = array(   CURLOPT_POST => 1,
                        CURLINFO_HEADER_OUT => true,
                        CURLOPT_POSTFIELDS => $params,
                        CURLOPT_RETURNTRANSFER => 1,
                        CURLOPT_HEADER => 1,
                        CURLOPT_COOKIE => $cookies_send,
                        CURLOPT_USERAGENT => $headers['User-Agent']
                    );

    curl_setopt_array($ch, $options);

    $response = curl_exec($ch);

/// DEBUG info echo $response; var_dump (curl_getinfo($ch)); ///

    // Parse response and read cookies
    preg_match_all('/^Set-Cookie: (.*?)=(.*?);/m', $response, $matches);

    // Build an array with cookies
    foreach( $matches[1] as $index => $cookie )
        $cookies[$cookie] = $matches[2][$index];

    return $cookies;
} // end http_login_client

M
Machavity

You can see it by using -iv

$> curl  -ivH "apikey:ad9ff3d36888957" --form  "file=@/home/mar/workspace/images/8.jpg" --form "language=eng" --form "isOverlayRequired=true" https://api.ocr.space/Parse/Image

P
Paweł Polewicz

You can use wireshark or tcpdump to look on any network traffic (http too).


if the payload is over HTTPS, those are useless without a proxy or application layer monitor.
V
Visruth

Make a sample request to https://http-tools.appspot.com/reflect-http-request/some-unique-id and check what this request contains (request header, request body, request parameters) by its corresponding finder url https://http-tools.appspot.com/reflect-http-request-finder/some-unique-id. You can use any string instead of some-unique-id, check out https://http-tools.appspot.com for more details.


Thanks, while not exactly answering the question, this is exactly what I needed. Device A makes a request, Device B checks a request has been made.
p
pseudocode

You can dump headers directly to stdout by using "-" as the filename - so for example to see headers and content, and follow redirects, all in one output:

curl -L -D - -s [url]

This was in a previous answer, but since it was at the bottom of a long answer I am upvoting as it's useful