196

As an example, POSTing to a web server with the -v argument:

curl -v http://testserver.com/post -d "firstname=john&lastname=doe"

And the output

> POST /post HTTP/1.1
> User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3
> Host: testserver.com
> Accept: */*
> Content-Length: 28
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 200 OK
(etc)

There is no mention of the data that I posted.

Is there an option in cURL to display the string "firstname=john&lastname=doe" in the output?

Note: Obviously the string I want is in the command I executed, but there are several other post options such as --form and --data-ascii etc. I'd like to see the raw data being sent to the server.

2
  • 1
    You can also run tcpdump to capture the actual data being sent to the server. Or wireshark (better) if you have that.
    – Keith
    Jun 1, 2011 at 9:15
  • I'm not sure you can. Is this an example of security by obscurity? - stackoverflow.com/questions/198462/… Jun 1, 2011 at 9:24

5 Answers 5

237

The closest I got without using tcpdump is using the --trace-ascii option:

~ curl http://w3.org/ -d "hello=there" --trace-ascii /dev/stdout
== Info: About to connect() to w3.org port 80 (#0)
== Info:   Trying 128.30.52.45... == Info: connected
== Info: Connected to w3.org (128.30.52.45) port 80 (#0)
=> Send header, 210 bytes (0xd2)
0000: POST / HTTP/1.1
0011: User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.1
0051: 9.7 OpenSSL/0.9.8l zlib/1.2.3
0070: Host: w3.org
007e: Accept: */*
008b: Content-Length: 11
009f: Content-Type: application/x-www-form-urlencoded
00d0: 
=> Send data, 11 bytes (0xb)
0000: hello=there

Unfortunately, this doesn't work when you're posting multipart/form-data:

~ curl http://w3.org/ -F hello=there -F testing=123 --trace-ascii /dev/stdout
== Info: About to connect() to w3.org port 80 (#0)
== Info:   Trying 128.30.52.45... == Info: connected
== Info: Connected to w3.org (128.30.52.45) port 80 (#0)
=> Send header, 270 bytes (0x10e)
0000: POST / HTTP/1.1
0011: User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.1
0051: 9.7 OpenSSL/0.9.8l zlib/1.2.3
0070: Host: w3.org
007e: Accept: */*
008b: Content-Length: 244
00a0: Expect: 100-continue
00b6: Content-Type: multipart/form-data; boundary=--------------------
00f6: --------19319e4d1b79
010c: 
<= Recv header, 32 bytes (0x20)
0000: HTTP/1.1 301 Moved Permanently
9
  • 5
    I know it is your own answer, but I think you can accept this as the correct answer. It solved it for me anyway, thanks :-) May 6, 2012 at 2:49
  • 7
    Remove any -v or --verbose as they override the trace directive. Feb 17, 2014 at 14:56
  • 3
    @AugustinRiedinger It works fine with https. I just tried it and saw the payload. The data is encrypted but since you are the endpoint of the connection, you have all the data available to you, and therefore curl can see it.
    – gak
    Aug 29, 2014 at 1:18
  • 2
    Using --trace-ascii worked for me on OS X 10.8.5 Mountain Lion. I have uploaded a multipart form entity with two images and a json body and everything worked as expected Sep 4, 2014 at 21:13
  • 10
    Instead of --trace-ascii /dev/stdout you can --trace-ascii - (dash) Sep 7, 2016 at 11:40
54

Or you could test with https://httpbin.org/

$ curl https://httpbin.org/post -d "firstname=john&lastname=doe"
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "firstname": "john", 
    "lastname": "doe"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "27", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.43.0"
  }, 
  "json": null, 
  "origin": "*.*.*.*", 
  "url": "https://httpbin.org/post"
}
1
  • While this is not useful to see actual data sent like Gert's answer, it is useful that it parses the response so one can know whether there is format error. Mar 18, 2022 at 18:56
30

Would like to add netcat alternative

#!/bin/bash
nc -l 8080 &

curl "http://localhost:8080" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data @- <<EOF
{
  "me": "$USER",
  "something": $(date +%s)
}
EOF
1
  • I can't listen to port 8080 with nc because it is already in use(by the application). What am i doing wrong? Dec 20, 2023 at 1:45
27

--trace - works with curl 7.58 and shows you the POST body:

$ curl --trace - -d 'foo=bar' http://example.org
== Info: Rebuilt URL to: http://example.org/
== Info:   Trying 2606:2800:220:1:248:1893:25c8:1946...
== Info: TCP_NODELAY set
== Info: Connected to example.org (2606:2800:220:1:248:1893:25c8:1946) port 80 (#0)
=> Send header, 144 bytes (0x90)
0000: 50 4f 53 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d POST / HTTP/1.1.
0010: 0a 48 6f 73 74 3a 20 65 78 61 6d 70 6c 65 2e 6f .Host: example.o
0020: 72 67 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 rg..User-Agent: 
0030: 63 75 72 6c 2f 37 2e 35 38 2e 30 0d 0a 41 63 63 curl/7.58.0..Acc
0040: 65 70 74 3a 20 2a 2f 2a 0d 0a 43 6f 6e 74 65 6e ept: */*..Conten
0050: 74 2d 4c 65 6e 67 74 68 3a 20 37 0d 0a 43 6f 6e t-Length: 7..Con
0060: 74 65 6e 74 2d 54 79 70 65 3a 20 61 70 70 6c 69 tent-Type: appli
0070: 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 cation/x-www-for
0080: 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 0d 0a 0d 0a m-urlencoded....
=> Send data, 7 bytes (0x7)
0000: 66 6f 6f 3d 62 61 72                            foo=bar
== Info: upload completely sent off: 7 out of 7 bytes
<= Recv header, 17 bytes (0x11)
0000: 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK.
0010: 0a                                              .
<= Recv header, 22 bytes (0x16)
2
  • This is the best answer, because it also works for mulitpart/form-data requests, without having to use a third party proxy
    – nobody
    Apr 20, 2021 at 13:02
  • For multipart/form-data, it only shows the file name. Can it show the file content? Dec 19, 2023 at 2:51
10

You could use Charles and curl --proxy localhost:8888. Simples!

4
  • 5
    no, it does not work with https. Accepted answer is fine and easier. May 18, 2015 at 20:41
  • https was not a requirement in the question :p
    – Dori
    May 19, 2015 at 10:11
  • @CasparHarmer what's your prob with the accepted answer? if you need more, TCPdump does the deal.
    – Gewure
    Jun 20, 2017 at 12:55
  • This happened 3 years ago. I cannot remember. Jun 20, 2017 at 16:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .