curl PATCH - JSON is sent as Line-based text data - json

Using curl to send a PATCH to my web service and got error:
Bad Request, The request sent by the client was syntactically incorrect. Apache Tomcat/8.0.37
while sending GET and POST using curl have no issue.
Using Swagger sending the same PATCH has no issue. So using WireShark to compare the Swagger (good) case and curl (bad) case.
Swagger (good) case:
curl (bad) case:
In the good case, a 0xA is inserted after "{" and ",". curl doesn't do this and double quotes are missing.
Here is the Swagger UI:
and this is my curl command running on Windows Command Prompt
Chrome app ARC also gets OK response:
Any suggestion is appreciated.

The problem was fixed by following curl:
curl --request PATCH "http://......................" ^
--header "Content-Type: application/json" ^
--header "Accept: application/json" ^
--header "Authorization: ..............." ^
--data "{\"op\":\"add\",\"path\":\"/user\",\"value\":\"%~1\"}"
Because it runs on Windows.

Related

Sending POST Request from bash script

I want to execute a bash script after i make a POST request.So far i am using Postman for sending the request , but i was wondering if i can somehow do it from a bash script as well with a json file as parameter.
I have looked into curl so far but it does not work:
bash file
curl -X POST -d req.json http://localhost:9500
Json file (req.json)
{
"id":5,
"name":"Dan",
"age":33,
"cnp":33,
"children":100,
"isMarried":0
}
I just get the error :
HTTP/1.0 503 Service Unavailable
with the trailing HTML
curl should do the job. This will send a normal POST request using the data in req.json as the body:
curl -X POST -H "Content-Type: application/json" -d #req.json http://localhost:9500
The elements you were missing are -H "Content-Type: application/json" and the # in the data flag. Without the -H flag as above curl will send a content type of application/x-www-form-urlencoded, which most applications won't accept if they expect JSON. The # in the -d flag informs curl that you are passing a file name; otherwise it uses the text itself (i.e. "req.json") as the data.

pushbullet api decoding (v2/push)

I want to use the pushbullet api (v2/push) for pushing messages, but if I include '%' character inside title or body the server gives me the following error:
{"error":{"type":"invalid_request","message":"Failed to decode urlencoded POST form body.","cat":"~(=^‥^)ノ"}}
How can I fix this problem?
request: curl https://api.pushbullet.com/v2/pushes -k -u token: -d type=note -d title="%test" -d body="%%test" -X POST
x-www-form-urlencoded is not the most straightforward of formats. You can probably use curl with the --data-urlencode option. You can also try encoding your values with this tool: http://meyerweb.com/eric/tools/dencoder/
That should produce urlencoded output, for instance your request would look more like:
curl -u token: https://api.pushbullet.com/v2/pushes --header "Content-Type: application/x-www-form-urlencoded" --data-binary 'type=note&title=TITLETEXT&body=%25BODYTEXT'

How to get cURL to output only HTTP response body (JSON) and no other headers etc

I am using curl in a bash script to fetch the response of a service as below,
response=$(curl -isb -H "Accept: application/json" "http://host:8080/some/resource")
Service response is of json type and on browser I could perfectly fine response.
However curl response has other unwanted things (such as set-cookie, content-length header in this case) and sometimes the actual response is eaten up.
Here is the output of echo $response >
Set-Cookie: rack.session=BAh7CEkiD3Nlc3Npb25faWQGOgZFVEkiRWJlY2JiOTE2M2Q1ZWI4NThjMDdi%0AYjRiOWRjMGMxMGEwYTBkMjE3NmJhZDVjYzY4YjY4ZTlmMTE2ZGVkYWE3MTMG%0AOwBGS
SIJY3NyZgY7AEZJIiVhZmQ2MmUyZGMxMzFmOGEwMjg3NDlhNWM3YmVm%0AN2FjNwY7AEZJIg10cmFja2luZwY7AEZ7B0kiFEhUVFBfVVNFUl9BR0VOVAY7%0AAFRJIi00MTc0OGM2MWNkMzljZTYxNzY3ZjU0
Y2I5OTdiYWRkN2MyNTBkYmU4%0ABjsARkkiGUhUVFBfQUNDRVBUX0xBTkdVQUdFBjsAVEkiLWRhMzlhM2VlNWU2%0AYjRiMGQzMjU1YmZlZjk1NjAxODkwYWZkODA3MDkGOwBG%0A--ee97a62095e7d42129
tontent-Length: 354c8; path=/; HttpOnly
This is breaking my response parsing logic.
I have seen this happening intermittently which is weird.
Is there a way to get "only" json response from cURL output?
I went through the curl documentation but could not see any thing/ or I could have missed it.
You are specifying the -i option:
-i, --include
(HTTP) Include the HTTP-header in the output. The HTTP-header includes things like server-name, date of the document, HTTP-version and more...
Simply remove that option from your command line:
response=$(curl -sb -H "Accept: application/json" "http://host:8080/some/resource")
I was executing a get request an also want to see just the response and nothing else, seems like magic is done with -silent,-s option.
From the curl man page:
-s, --silent
Silent or quiet mode. Don't show progress meter or error messages. Makes Curl mute. It will still output the data you ask for, potentially even to the terminal/stdout unless you redirect it.
Below the examples:
curl -s "http://host:8080/some/resource"
curl --silent "http://host:8080/some/resource"
Using custom headers
curl -s -H "Accept: application/json" "http://host:8080/some/resource"
Using POST method with a header
curl -s -X POST -H "Content-Type: application/json" "http://host:8080/some/resource" -d '{ "myBean": {"property": "value"}}'
You can also customize the output for specific values with -w, below the options I use to get just response codes of the curl:
curl -s -o /dev/null -w "%{http_code}" "http://host:8080/some/resource"

How to PUT a json object with an array using curl

I have a series of data to enter into database. The user interface to enter the data isn't good for bulk entry, so I'm trying to formulate a command line equivalent. When I examine the network request of the UI in chrome, I see a PUT request of a json object. When I try to replicate the request
curl -H 'Accept: application/json' -X PUT '{"tags":["tag1","tag2"],"question":"Which band?","answers":[{"id":"a0","answer":"Answer1"},{"id":"a1","answer":"answer2"}]}' http://example.com/service`
I get a error
curl: (3) [globbing] nested braces not supported at pos X
Where X is the character position of first "[".
How can I PUT a json object that includes an array?
Your command line should have a -d/--data inserted before the string you want to send in the PUT, and you want to set the Content-Type and not Accept.
curl -H 'Content-Type: application/json' -X PUT -d '[JSON]' \
http://example.com/service
Using the exact JSON data from the question, the full command line would become:
curl -H 'Content-Type: application/json' -X PUT \
-d '{"tags":["tag1","tag2"],
"question":"Which band?",
"answers":[{"id":"a0","answer":"Answer1"},
{"id":"a1","answer":"answer2"}]}' \
http://example.com/service
Note: JSON data wrapped only for readability, not valid for curl request.
Although the original post had other issues (i.e. the missing "-d"), the error message is more generic.
curl: (3) [globbing] nested braces not supported at pos X
This is because curly braces {} and square brackets [] are special globbing characters in curl.
To turn this globbing off, use the "-g" option.
As an example, the following Solr facet query will fail without the "-g" to turn off curl globbing:
curl -g 'http://localhost:8983/solr/query?json.facet={x:{terms:"myfield"}}'
It should be mentioned that the Accept header tells the server something about what we are accepting back, whereas the relevant header in this context is Content-Type
It's often advisable to specify Content-Type as application/json when sending JSON. For curl the syntax is:
-H 'Content-Type: application/json'
So the complete curl command will be:
curl -H 'Content-Type: application/json' -H 'Accept: application/json' -X PUT -d '{"tags":["tag1","tag2"],"question":"Which band?","answers":[{"id":"a0","answer":"Answer1"},{"id":"a1","answer":"answer2"}]}' http://example.com/service`
The only thing that helped is to use a file of JSON instead of json body text. Based on How to send file contents as body entity using cURL
Try using a single quote instead of double quotes along with -g
Following scenario worked for me
curl -g -d '{"collection":[{"NumberOfParcels":1,"Weight":1,"Length":1,"Width":1,"Height":1}]}" -H "Accept: application/json" -H "Content-Type: application/json" --user test#testmail.com:123456 -X POST https://yoururl.com
WITH
curl -g -d "{'collection':[{'NumberOfParcels':1,'Weight':1,'Length':1,'Width':1,'Height':1}]}" -H "Accept: application/json" -H "Content-Type: application/json" --user test#testmail.com:123456 -X POST https://yoururl.com
This especially resolved my error curl command error : bad url colon is first character

Create new gist with Github API v3 using curl

After fighting for quite some time for posting a private gist to Github using their API V3 I almost gave up. Almost. May be some one have also faced similar problem or know what might be the reasoning of the following behavior:
Right now the curl command looks like following:
curl -H "Authorization: bearer MY_AUTHORIZATION_TOKE" -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"public":false,"files":{"test.txt":{"content":"String file contents"}}}' https://api.github.com/gists
I also tried
curl -H "Authorization: bearer MY_AUTHORIZATION_TOKE" -X POST -d '{"public":false,"files":{"test.txt":{"content":"String file contents"}}}' https://api.github.com/gists
I am able to create gist without authorization token using exactly same data:
curl -X POST -d '{"public":true,"files":{"test.txt":{"content":"String file contents"}}}' https://api.github.com/gists
But in that case it will be anonymous
Same results if I am truing to post it as public
In any case Github returns me
HTTP/1.1 404 Not Found
{
"message": "Not Found"
}
I am pretty sure I am authorized, as curl -H "Authorization: bearer MY_AUTHORIZATION_TOKE" https://api.github.com/user returns me my user details.
Application scope is as:
https://github.com/login/oauth/authorize?client_id=...&scope=gist
So, it should have both read and write permission.
Your OAuth2 token doesn't appear to have the required gist scope.
If you run the curl commands with the -v argument you can see the scope sent to request (X-OAuth-Scopes header) and the scope required for the request (X-Accepted-OAuth-Scopes header) to successfully be performed using the token sent.
If you don't see gist listed in the X-OAuth-Scopes header value then that is your problem.