How do I manually POST JSON data with only an ssh connection (no cURL or other utility) - http

I want to manually POST JSON data using just a keyboard and ssh connection (i.e. without cURL). The cURL functionality I'm trying to replicate which works great is equivalent to:
curl -s -w '\n' -X POST -D - \
-H "Content-type: application/json" \
-d '{"param1":"value1","param2":"value2"}' \
https:///myserver.com/mypath
However, when I connect manually:
openssl s_client -connect myserver.com:443 -quiet
and then enter
POST /mypath HTTP/1.1
Host: myserver.com
Content-type: application/json
Accept: application/json
{
"param1": "value1",
"param2": "value2"
}
I get the message "Json content error HV000116: The object to be validated must not be null." I've tried every variation I can think of with whitespace, and encoding, but I still get the error. I know I'm missing something simple, but what is it?

Doh! Just needed to add the Content-length header and everything worked

Related

How can I convert a HTTP request to curl?

I'm newbie on this so I would like your help, according to CrazyCall docs I want to test those code examples in terminal using CURL, for example this one:
GET /api/v1/users HTTP/1.1
x-api-token: your-secret-api-key
Account: your-account-hash.crazycall.com
Host: api.crazycall.com
I tried to convert to curl and execute like this:
curl -XGET -H 'x-api-token: mdsRFGRV23XXXXXXX' -H 'Account: lopDOPLSVXXXX.crazycall.com' -H 'Host: api.crazycall.com' /api/v1/users
But it shows me a message <url> malformed
I also added "Content-type: application/json" header but it's still the same.
How can I fix it?
Prepand the protocol and domain (https://api.crazycall.com) to your path (/api/v1/users):
curl -X GET -H 'x-api-token: mdsRFGRV23XXXXXXX' -H 'Account: lopDOPLSVXXXX.crazycall.com' -H 'Host: api.crazycall.com' https://api.crazycall.com/api/v1/users

force cURL to send an invalid HTTP header

How can I force cURL to send an invalid HTTP header, as follows:
curl -k 'https://192.168.1.1/' -H 'Host: 192.168.1.1' -H 'blah' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.8'
When I try the above, cURL helpfully leaves out the invalid header.
You can, but it's slightly more convoluted than that. curl will check that you use a colon and avoid passed in headers that don't have colons. But you can trick curl's colon check by passing in a header with embedded CRLF that then creates two header lines, and one of them can then be without colon.
For example like this:
curl -H "`printf "Foo: bar\r\nblah"`" -v localhost
(-v of course lets you see the actual request curl uses)

external_account not accepting dictionary?

I am using stripe to update the card on a managed account external_account, but the error is asking for a token but the docs are saying wither token or dictionary.
https://stripe.com/docs/api#account_create_card
-d external_account={"object":"card", "exp_month":"04", "exp_year":"2019", "number":"5200828282828210"}
Error
{
"error": {
"type": "invalid_request_error",
"message": "Received unknown parameter: number",
"param": "number"
}
}
The reason that your example curl command doesn't work is that the Stripe API requires that the Content-Type header of requests sent to it be application/x-www-form-urlencoded and you are sending a JSON string.
curl https://api.stripe.com/v1/accounts/acct_XXYYZZ/external_accounts \
-u sk_test_AABBCC: \
-d external_account[object]="card" \
-d external_account[number]=5200828282828210 \
-d external_account[exp_month]=04 \
-d external_account[exp_year]=2019 \
-d external_account[cvc]=123
From the curl man-page, the "-d" switch on the curl command "Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded" which what you want, and the square bracket notation is how you send a hash/dictionary as Content-Type: application/x-www-form-urlencoded.

-D- curl parameter

There is a sample in Jira API doc:
curl -D- -X GET -H "Authorization: Basic ZnJlZDpmcmVk" -H "Content-Type: application/json" "http://kelpie9:8081/rest/api/2/issue/QA-31"
What exactly does the -D- parameter mean? There is no description in curl documentation.
I'm also not sure whether -D- and -D mean the same thing.
It dumps headers to stdout.
The -D flag dumps headers to a file, and the following - instructs it to dump to stdout. From the linked spec:
-D, --dump-header
Write the protocol headers to the specified file.
It doesn't specify for this option, but this works like other options that take a filename:
Use "-" as filename to have the output sent to stdout.

Curl-convert to a simple http request?

I have some curl request, in which i would like to build from it a basic POST request-authenticated (with headers etc), i couldn't find any tool that convert that :
curl -X POST 'https://api.twilio.com/2010-04-01/Accounts/xxxxxxxxxxxxx/Calls.json' \
--data-urlencode 'To=xxxxxxx65542' \
--data-urlencode 'From=+xxxxxxx4215' \
-d 'Url=https://api.twilio.com/2010-04-01' \
-d 'Method=GET' \
-d 'FallbackMethod=GET' \
-d 'StatusCallbackMethod=GET' \
-d 'Record=false' \
-u ACbe68cddxxxxxxxxxxxx3aba243cc4cdb:0f442xxxxxxxxxxxxxxxxxxx
So how would my POST request should look like ?
Okay so i was trying to figure out how to send a text message from an ESP8266 nodeMcu v0.9 module. It is capable of working like an arduino with the arduino ide 1.6.4.
Anyways, I found http://textbelt.com and it only shows a simple CURL way of sending the text message.
This is the CURL message it wants you to send
$ curl -X POST http://textbelt.com/text \ -d number=5551234567 \ -d "message=I sent this message for free with textbelt.com"
So to convert to a normal HTTP POST command i did the following. (this works in Arduino IDE)
number and message are String objects.
String messageToSend = "number="+number+"&message="+message;
client.print("POST /text HTTP/1.1\r\n");
client.print("Host: textbelt.com\r\n");
client.print("Content-Type: application/x-www-form-urlencoded\r\n");
client.print("Content-Length: ");
client.print(messageToSend.length());
client.print("\r\n\r\n");
client.print(messageToSend);
At first i tried without the Content-Type but that didn't seem to work. So i had to add the type of content i was sending as well.
If you were to monitor the network traffic with say WireShark you would see
POST /text HTTP/1.1\r\n
Host: textbelt.com\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 48\r\n
\r\n
number=5551234567&message=this is a text message
I may have been able to use less text with text/plain as the content-type but i think it may need the application urlencoded type to work.
Hope this helps someone else trying to convert curl to http.
From the cURL man page :
-H, --header (HTTP) Extra header to use when getting a web page. You may specify any number of extra headers. Note that if you
should add a custom header that has the same name as one of the
internal ones curl would use, your externally set header will be
used instead of the internal one. This allows you to make even
trickier stuff than curl would nor‐ mally do. You should not replace
internally set headers without knowing perfectly well what you're
doing. Remove an internal header by giving a replacement without
content on the right side of the colon, as in: -H "Host:". If you send
the custom header with no-value then its header must be terminated
with a semicolon, such as -H "X-Custom- Header;" to send
"X-Custom-Header:".
curl will make sure that each header you add/replace is sent with the
proper end-of-line marker, you should thus not add that as a part of
the header content: do not add newlines or carriage returns, they will
only mess things up for you.
See also the -A, --user-agent and -e, --referer options.
This option can be used multiple times to add/replace/remove multiple
headers.
Amazon AWS makes heavy use of headers for authentication. A quick Google should lead to many examples such as this one from http://tmont.com/blargh/2014/1/uploading-to-s3-in-bash :
curl -X PUT -T "${file}" \
-H "Host: ${bucket}.s3.amazonaws.com" \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Authorization: AWS ${s3Key}:${signature}" \
https://${bucket}.s3.amazonaws.com/${file}
All you need to do is adapt the AWS examples for your twilio use.
To make the example into a POST, just change PUT to POST and add your POST fields -d "field1=val1&field2=val2&field3=val3"
You can specify the headers using --header and the type of request (POST) by using -X / --request parameters.
Example:
curl --request POST --header "X-MyHeader: MyAuthenticatedHeader" www.stackoverflow.com
In your case it should be:
curl -X POST 'https://api.twilio.com/2010-04-01/Accounts/xxxxxxxxxxxxx/Calls.json' \
--header 'X-MyHeader: MyAuthenticatedHeader' \
--data-urlencode 'To=xxxxxxx65542' \
--data-urlencode 'From=+xxxxxxx4215' \
-d 'Url=https://api.twilio.com/2010-04-01' \
-d 'Method=GET' \
-d 'FallbackMethod=GET' \
-d 'StatusCallbackMethod=GET' \
-d 'Record=false' \
-u ACbe68cddxxxxxxxxxxxx3aba243cc4cdb:0f442xxxxxxxxxxxxxxxxxxx

Resources