This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the web-development category.
Last Updated: 2024-11-23
I was trying to send JSON commands to the Project M /commands
POST endpoint but without much luck.
I realized I was lacking some understanding of HTTP POST, thus this piece.
The values are sent in the request body, in the format that the content type specifies. The following shows an example. Note the necessary blank line between the HTTP header and the body (containing the params)
POST /path/script.cgi HTTP/1.0
From: frog@jmarshall.com
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
home=Cosby&favorite+flavor=flies
Usually the content type is application/x-www-form-urlencoded
, so the request
body uses the format you see above. On the command line with curl
, this gets
generated with the -d
flag, e.g. curl -d home=Cosby -d favorite flavor=flies
would generate a post chunk that looks like the above.
When you use a file upload in the form, you use the multipart/form-data
encoding instead, which has a different format.
Curl now requires you to use -F
for each field (not just the data to be
uploaded!)
curl -X POST -F person=anonymous -F secret=@file.txt http://example.com/submit.cgi
Note too the use of the @file.txt
to indicate that a local file should be sent.
The generated HTTP is something like what follows
POST /submit.cgi HTTP/1.1
Host: example.com
User-Agent: curl/7.46.0
Accept: */*
Content-Length: 313
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------d74496d66958873e
--------------------------d74496d66958873e
Content-Disposition: form-data; name="person"
anonymous
--------------------------d74496d66958873e
Content-Disposition: form-data; name="secret"; filename="file.txt"
Content-Type: text/plain
contents of the file
--------------------------d74496d66958873e--
The Content-Type header has a boundary that consists of random digits and is
used to separate data parts. Each part for a name=X
area, where X is the
parameter key name. Inside the following body, is either the parameter value
(e.g. anonymous
, for the person
field) or the file contents.
How do we post JSON from command line?
curl -X POST -H 'Content-Type: application/json' -d '{"username":"davidwalsh","password":"something"}' http://domain.tld/login
We use -d
again and just give it the FULL
JSON load. -d
alone would use Content-Type:
application/x-www-form-urlencoded
like a HTML form. But the Content-Type
bit
overrides it.
Note the necessary double quoting of the key names as well as values in the JSON;
POST / HTTP/1.1
Host: example.com
User-Agent: curl/7.64.1
Accept: */*
Content-Type: application/json
Content-Length: 48
* upload completely sent off: 48 out of 48 bytes
Aside from all this, it's probably easiest to construct a correct curl
request
using the Postman tool.