Dollar sign ($) not escaped in request - paw-app

When creating a HTTP GET request, adding
where={"email":{"$exists":false}}
as text in the body results in
curl "https://---omitted---" \
-H 'X-Parse-Application-Id: ---omitted---' \
-H 'X-Parse-REST-API-Key: ---omitted---' \
-H 'Content-Type: text/plain; charset=utf-8' \
-d "where={\"email\":{\"$exists\":false}}"
This request completes with 200 OK but does not return the expected results. My best guess is that $exists keyword is misinterpreted, as the $ is not escaped and even shows up red in the cURL preview.
When testing with cURL directly, and escaping the keyword, everything works.
If I add a backwards slash (\) before the $, that results in \\$ which doesn't help.
How an I escape the $? URL-Encode doesn't help, and I couldn't find anything else in your documentation.
Cheers, keep up the good work.

Related

How to get the http request to work on my browser

I am using the here-api to get a 7 day forecast for my application. When I copy and paste the code onto my browser from the Here documentation using my app-code and app-id, it says that my app-id and app-code are invalid. I am wondering why this is happening since i have an account with Here and am using the code they provided.
I have already tried switching them.
https://weather.api.here.com/weather/1.0/report.json
?app_id={xxxxxx}
&app_code={xxxxxx}
&product=forecast_7days_simple
&latitude=41.83
&longitude=-87.68
When i enter this request i expected json in return but instead get a page that says my code is invalid. I am using safari but have tried chrome and i still get the same problem
Make sure to remove the curly brackets around the credentials, and to remove newlines (if any) that were added in the documentation for readability.
If you do have valid credentials, the following request should work:
https://weather.api.here.com/weather/1.0/report.json?app_id=xxxx&app_code=yyyy&product=forecast_7days_simple&latitude=41.83&longitude=-87.68
Use the query like below. For any query you can use the swagger here . And, from the "view code" button you can download either the curl or the jQuery snippet.
curl \
-X GET \
-H 'Content-Type: *' \
--get 'https://weather.api.here.com/weather/1.0/report.json' \
--data-urlencode 'product=forecast_7days_simple' \
--data-urlencode 'latitude=52.516' \
--data-urlencode 'longitude=13.389' \
--data-urlencode 'oneobservation=true' \
--data-urlencode 'app_id={YOUR_APP_ID}' \
--data-urlencode 'app_code={YOUR_APP_CODE}'

How can I use the Pingdom API to pause and resume checks from bash?

I'm writing a quick and dirty deployment script and would like to disable and reenable a Pingdom check as part of it. How do I do that using something like cURL?
To pause a check:
curl -X PUT -u 'your#email:yourpassword' -H 'Content-Type: application/json' -H 'App-Key: yourapplicationkey' -d 'paused=true' https://api.pingdom.com/api/2.0/checks/checkid
To resume a check:
curl -X PUT -u 'your#email:yourpassword' -H 'Content-Type: application/json' -H 'App-Key: yourapplicationkey' -d 'paused=false' https://api.pingdom.com/api/2.0/checks/checkid
Replace your#email with your pingdom email.
Replace yourpassword with your pingdom password.
Replace yourapplicationkey with a generated key from the "Sharing" section in your account.
Replace checkid with the numeric ID you see in the browser URL when you click on your check in the Pingdom UI.
You can also use modern way - just API key instead of using also email/password.
First, generate your own API key in https://my.pingdom.com/app/api-tokens and then you can use curl commands like for pausing:
curl -X PUT \
https://api.pingdom.com/api/3.1/checks \
-H 'Authorization:Bearer YOURAPIKEY' \
-d 'paused=true&checkids=777'
or for resuming:
curl -X PUT \
https://api.pingdom.com/api/3.1/checks \
-H 'Authorization:Bearer YOURAPIKEY' \
-d 'paused=false&checkids=777'
Replace YOURAPIKEY with your real API key and 777 with valid check ID.
checkids can be also omitted, then all checks will be modified.

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

How can I rewrite this CURL multipart/form-data request without using -F?

How can I rewrite the following CURL command, so that it doesn't use the -F option, but still generates the exact same HTTP request? i.e. so that it passes the multipart/form-data in the body directly.
curl -X POST -F example=test http://localhost:3000/test
Solved:
curl \
-X POST \
-H "Content-Type: multipart/form-data; boundary=----------------------------4ebf00fbcf09" \
--data-binary #test.txt \
http://localhost:3000/test
Where test.txt contains the following text, and most importantly has CRLF (\r\n) line endings:
------------------------------4ebf00fbcf09
Content-Disposition: form-data; name="example"
test
------------------------------4ebf00fbcf09--
Notes: it is important to use --data-binary instead of plain old -d as the former preserves the line endings (which are very important). Also, note that the boundary in the body starts with an extra --.
I'm going to repeat it because it's so important, but that request-body file must have CRLF line endings. A multi-platform text editor with good line-ending support is jEdit (how to set the line endings in jEdit).
If you're interested in how I worked this out (debugging with a Ruby on Rails app) and not just the final solution, I wrote up my debugging steps on my blog.
You can use the --form argument with an explicitly
curl -H "Content-Type: multipart/related" \
--form "data=#example.jpg;type=image/jpeg" http://localhost:3000/test
Here's an alternative answer with the original CURL statement re-written using -d as a one-liner, without temporary files. Personally I think the temporary files approach is easier to understand, but I'm putting this here for reference as well:
curl -X POST -H "Content-Type: multipart/form-data; boundary=----------------------------4ebf00fbcf09" -d $'------------------------------4ebf00fbcf09\r\nContent-Disposition: form-data; name="example"\r\n\r\ntest\r\n------------------------------4ebf00fbcf09--\r\n' http://localhost:3000/test
Notes: the $'blar' syntax is so that bash will parse the \r\n as a CRLF token. Thanks to this answer for that tip.
This is what I'm using, I think it's clean and doesn't need temporary files nor gobbles up RAM in case you want to upload whole files (so no reading files into memory).
# Set these two.
file='path/to/yourfile.ext'
url='http://endpoint.example.com/foo/bar'
delim="-----MultipartDelimeter$$$RANDOM$RANDOM$RANDOM"
nl=$'\r\n'
mime="$(file -b --mime-type "$file")"
# This is the "body" of the request.
data() {
# Also make sure to set the fields you need.
printf %s "--$delim${nl}Content-Disposition: form-data; name=\"userfile\"${nl}Content-Type: $mime$nl$nl"
cat "$file"
printf %s "$nl--$delim--$nl"
}
# You can later grep this, or something.
response="$(data | curl -# "$url" -H "content-type: multipart/form-data; boundary=$delim" --data-binary #-)"
This is to upload one image file using "Content-Type: multipart/related",
curl --trace trace.txt -X POST -H 'Content-Type: multipart/related; boundary=boundary_1234' --data-binary $'--boundary_1234\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n{\r\n\t"title": "TestFile"\r\n}\r\n\r\n--boundary_1234\r\nContent-Type: image/jpeg\r\n\r\n' --data-binary '#Image0177.jpg' --data-binary $'\r\n--boundary_1234--\r\n' 'http://localhost:3000/google/upload/drive/v2/files?uploadType=multipart'
Here it is how I would do it:
curl https://httpbin.org/post \
-H 'content-type: multipart/form-data; boundary=----FormBoundary123456789' \
--data-binary $'------FormBoundary123456789\r
Content-Disposition: form-data; name="example"\r
\r
test\r
------FormBoundary123456789--\r
'
Or a bit more sophisticated (should be portable to most modern shells):
DELIM=----FormBoundary$RANDOM$RANDOM
curl https://httpbin.org/post \
-H "content-type: multipart/form-data; boundary=$DELIM" \
--data-binary --$DELIM$'\r
Content-Disposition: form-data; name="example"\r
\r
test\r
'--$DELIM--$'\r
'
This is for multipart/form-data request method. for uploading a file add --form filename="#path/image.jpg;type=image/jpeg"
curl --form key="value" --form key="value" http://localhost:3000/test

How to send line break with curl?

I've tried the following to send a line break with curl, but \n is not interpreted by curl.
curl -X PUT -d "my message\n" http://localhost:8000/hello
How can I send a line break with curl?
Sometimes you want to provide the data to be sent verbatim.
The --data-binary option does that.
Your shell is passing \ followed by n rather than a newline to curl rather than "my message\n". Bash has support for another string syntax that supports escape sequences like \n and \t. To use it, start the string with $' and end the string with ':
curl -X PUT -d $'my message\n' http://localhost:8000/hello
See ANSI-C Quoting in the Bash Reference Manual
There's a much easier way!
curl -X PUT -d $'my message\n' http://localhost:8000/hello
This will use ANSI-C Quoting to insert the newline character.
No piping, no data files. See also Sending Newlines with cURL.
The solution for someone who doesn't want to use files, and doesn't want to resort to shell escaping magic is:
curl -X POST --data-binary #- http://url.com <<EOF
line one
line two
EOF
But this is literal newlines in the post data payload, and not in form fields.
Had similar issue. While uploading a CSV file from Mac to cloud storage, new lines were being removed. After downloading it, the entire file looked like a single line. I tried adding different EOL characters \n \r \r\n with no success. Using --data-binary instead of -d solved the issue.
Btw this issue occurred only from Mac. -d worked just fine while making the call from CentOS machine. This very much looks like due to Mac's newline character. But don't feel like debugging any more.
Thanks a lot for your help.
curl -X PUT -d #filename.csv https://cloudstorage -H "content-type: text/csv"
vs
curl -X PUT --data-binary #filename.csv https://cloudstorage -H "content-type: text/csv"
(I ended up here with a slightly different question, so I'm just going to post my answer because it might help future explorers)
My solution applies to people who are sending form-style data, i.e. key/value pairs in a query string. Use the encoded line break, which is %0A, just like how an encoded space is %20. You can use http://meyerweb.com/eric/tools/dencoder/ to convert other symbols.
So if you want to set the key message to the value:
line one
another
you would send
curl --data "message=line%20one%0Aanother" http://localhost:8000/hello
A very easy way, just Shift-Enter in the console for the break. Very readable typing it in too.
curl -d "line1
line2" http-echo.com
Server gets this: line1\nline2
Do this to remove the line break:
curl -d "line1 \
line2" http-echo.com
Server gets this: line1 line2
Not an answer to your question, but I would work around it by creating a temporary file containing the message and line break, and give curl that file to work on:
curl -X PUT -d #message.txt http://localhost:8000/hello
From the manual:
If you start the data with the letter #, the rest should be a file name to read the data from, or - if you want curl to read the data from stdin. The contents of the file must already be URL-encoded. Multiple files can also be specified. Posting data from a file named 'foobar' would thus be done with --data #foobar.
I was using Sendgrid with this code (copied below) originally found here https://sendgrid.com/docs/API_Reference/Web_API_v3/index.html
\n\n worked in Gmail, but \n was ignored. I tried to double the escape and other suggestions. I also tried \r\n and that did not work in Gmail either. Note: I didn't bother to test other email clients, maybe it was a Gmail-specific problem.
curl --request POST \
--url https://api.sendgrid.com/v3/mail/send \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{"personalizations": [{"to": [{"email": "your.email#example.com"}]}],"from": {"email": "example#example.com"},"subject": "Hello, World!","content": [{"type": "text/plain", "value": "Heya!"}]}'
Eventually I gave up looking for a solution and switched the text/plain to text/html and just used <br /> tags.
Someone suggested that Sendgrid converts plaintext to HTML if you have a tracking pixel enabled, which makes sense. Maybe the newlines were destroyed in the plaintext-to-html conversion process. I assume the client wants a tracking pixel, so decided to switch to HTML.

Resources