133

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.

  • 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 '11 at 9:15
  • I'm not sure you can. Is this an example of security by obscurity? - stackoverflow.com/questions/198462/… – slotishtype Jun 1 '11 at 9:24
163

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
  • 4
    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 :-) – Darren Cook May 6 '12 at 2:49
  • 3
    Remove any -v or --verbose as they override the trace directive. – AlikElzin-kilaka Feb 17 '14 at 14:56
  • 1
    @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 '14 at 1:18
  • 1
    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 – Heath Borders Sep 4 '14 at 21:13
  • 4
    Instead of --trace-ascii /dev/stdout you can --trace-ascii - (dash) – Adam Michalik Sep 7 '16 at 11:40
24

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": "78.228.163.126", 
  "url": "https://httpbin.org/post"
}
11

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 @<(cat <<EOF
{
  "me": "$USER",
  "something": $(date +%s)
}
EOF
)
9

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.