The curl cheat sheet to myself
It has been not even a full week building REST style interfaces for the Playmaker Studio mobile platform and I am very annoyed of all the curl
guides how to access your REST API with curl
. So here is my cheat sheet on this topic. Be aware that the I will update this frequently.
Common use cases
GETting data from a URL
This is a very simple use case just use:
curl https://graph.facebook.com/740999649
{"id":"740999649","name":"Niclas Meier"}
curl
will automatically use the HTTP method GET
.
POSTting updates
In the REST dictionary the HTTP method POST
represents the verb ‘update’. So updating data implies a POST
request to an URL.
Basic
Let’s have a look at the basics, I added some (revised / half the original) debugging output by supplying the -v
option.
curl -v -X POST http://localhost:8080/1/stuff/23f96c6bd4c87910c.json -d 'name=Niclas'
> POST /1/stuff/23f96c6bd4c87910c.json HTTP/1.1
> Host: localhost:8080
> Accept: */*
> Content-Length: 11
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Content-Length: 25
<
Stuff: 23f96c6bd4c87910c
There are some options involved:
-v
added the request/response header for debugging-X
specified the request method (POST
) to use.-d
added some data in the request (POST
) body.
So the 'name=Niclas'
was sent to the server using the request body, but curl
does not display the request body using the -v
option.
Using a JSON body
So this is nice, when you want to post key-value pairs to your server, but many applications (e.g. CouchDB want to post JSON objects to the server. The initial guess
curl -v -X POST http://localhost:8080/1/stuff/23f96c6bd4c87910c.json -d '{"name":"Niclas"}'
Stuff: 23f96c6bd4c87910c, JSON body:
does not work. That’s where the content type comes in. If you post the JSON whiteout supplying the proper content type curl
and/or the server will try to use application/x-www-form-urlencoded
* content type. This is the same content type your browser uses when submitting a form to a web server. Doesn’t sound bad, does it?
But it’s bad because the JSON will be ignored/dropped/whatever and the server is unable to understand the request. To solve the problem use:
curl -H "Content-Type: application/json" -X POST http://localhost:8080/1/stuff/23f96c6bd4c87910c.json -d '{"name":"Niclas"}'
Stuff: 23f96c6bd4c87910c, JSON body: {"name":"Niclas"}
So these options are involved
-X
specified the request method (POST
) to use.-H
added the headerContent-Type: application/json
to the request.-d
defined the data used for the request body ({"name":"Niclas"}
).
A JSON file as body
So far so good. But if you have huge JSON requests, you don’t want to type all the JSON into the console. You may use the @
symbol in conjunction with the -d
option so curl
will read the request body contents from a file. This may look like this.
curl -H "Content-Type: application/json" -X POST http://localhost:8080/1/stuff/23f96c6bd4c87910c.json -d @some-huge-request.json
Stuff: 23f96c6bd4c87910c, JSON body: {"name":"Niclas", ..., "foo":"Bar"}
A nice trick is, that if you use the -d
with @-
. curl
will read the request body from the standard input. So you can do stuff like this:
cat some-huge-request.json | curl -H "Content-Type: application/json" -X POST http://localhost:8080/1/stuff/23f96c6bd4c87910c.json -d @-
Stuff: 23f96c6bd4c87910c, JSON body: {"name":"Niclas", ..., "foo":"Bar"}
PUTting stuff
Is much like POST
, so if you can POST
you can PUT
. One nasty little difference is, that you don’t have to supply a Content-Type
HTTP header for PUT
. curl
does not use application/x-www-form-urlencoded
as content type for PUT
. Lost an hour (or so), because I did some PUT
stuff before switching to POST
.
Debugging
Detailed information
The key to get almost every information by supplying the -v
option to curl.
curl -v https://graph.facebook.com/740999649
* About to connect() to graph.facebook.com port 443 (#0)
* Trying 66.220.147.38... connected
* Connected to graph.facebook.com (66.220.147.38) port 443 (#0)
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
* subject: C=US; ST=California; L=Palo Alto; O=Facebook, Inc.; CN=*.facebook.com
* start date: 2010-01-13 00:00:00 GMT
* expire date: 2013-04-11 23:59:59 GMT
* common name: *.facebook.com (matched)
* issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert High Assurance CA-3
* SSL certificate verify ok.
> GET /740999649 HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: graph.facebook.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Cache-Control: private, no-cache, no-store, must-revalidate
< Content-Type: text/javascript; charset=UTF-8
< ETag: "f89bfe40c87e487ae641d427c96746b226a91f3c"
< Expires: Sat, 01 Jan 2000 00:00:00 GMT
< Pragma: no-cache
< X-FB-Rev: 482216
< X-FB-Server: 10.36.50.102
< X-Cnection: close
< Date: Wed, 07 Dec 2011 13:14:19 GMT
< Content-Length: 183
<
* Connection #0 to host graph.facebook.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
{"id":"740999649","name":"Niclas Meier","first_name":"Niclas","last_name":"Meier","link":"http:\/\/www.facebook.com\/people\/Niclas-Meier\/740999649","gender":"male","locale":"de_DE"}
But for may occasions that is simply too much, so check out the -i
option.
Header information
Often it’s enough to get only the response headers for debugging. To get only these headers just use the -i
option in curl
.
curl -i https://graph.facebook.com/740999649
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Cache-Control: private, no-cache, no-store, must-revalidate
Content-Type: text/javascript; charset=UTF-8
ETag: "f89bfe40c87e487ae641d427c96746b226a91f3c"
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Pragma: no-cache
X-FB-Rev: 482216
X-FB-Server: 10.42.67.29
X-Cnection: close
Date: Wed, 07 Dec 2011 13:18:24 GMT
Content-Length: 183
{"id":"740999649","name":"Niclas Meier","first_name":"Niclas","last_name":"Meier","link":"http:\/\/www.facebook.com\/people\/Niclas-Meier\/740999649","gender":"male","locale":"de_DE"}