how to post with curl to REST/JSON service? - json

I have tried out the sample REST JSON service at
http://www.javacodegeeks.com/2013/04/spring-mvc-easy-rest-based-json-services-with-responsebody.html
and the JQuery client can successfully post a person object to the service! Yahoo!
How do I do the same thing with cURL?
Here is my attempt:
curl -i -X POST -H "Content-Type: application/json; charset=UTF-8" -H "Accept: application/json" -d "{'name':'siegfried','age':26}" http://localhost:8080/api/person
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 71 100 42 100 29 39 26 0:00:01 0:00:01 --:--:-- 40
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 42
Server: Jetty(6.1.25)
Saved person: Person [name=null, age=null]
Compilation finished at Sun Dec 08 22:14:05
It is not parsing the data! How do I make it parse my json data?
I've been google searching for hours and trying out many combinations of escaping quotes and apostrophes and the like and nothing seems to work.
Thanks
siegfried

The -d will send your data as a post, you do not need to declare POST.
man curl gives the description on how to use -d. If anyone else would need it.
A simple Sinatra server http://www.sinatrarb.com, or something like it, can be used to debug your curls as well as a mock server
Is there a possibility that the problem is on the server-side, if you run it on local host you should have access to it, right?

I found the problem!
The spring #ResponseBody uses JSON for get but uses URL Encoding for POST.
See the jQuery POST method for http://codetutr.com/2013/04/09/spring-mvc-easy-rest-based-json-services-with-responsebody/
Why the inconsistency? This drove me nuts!
Well, I still don't have a cURL command. But I do have java and groovy clients that can now POST and GET. I should have a cURL soon.

Related

Ricoh Theta Z1 Doesn't Accept My Request to Change File Format

I am using a Ricoh Theta Z1 updated to the most recent firmware (1.60.1). I am trying to debug an Android application, but I found that one of our commands was repeatedly failing, so I connected to the camera directly from my dev box and tested the protocol directly via curl.
It's my understanding from the documentation that this command should work:
$ curl -X POST -H "Content-Type: application/json; charset=UTF-8" -d '{"name":"camera.setOptions", "parameters":{"options":{"captureMode":"image","fileFormat":{"height":3360,"type":"jpeg","width":6720}}}}' http://192.168.1.1/osc/commands/execute
But when I run this command I get this response:
{"error":{"code":"invalidParameterValue","message":"Any input parameter or option name is recognized, but its value is invalid."},"name":"camera.setOptions","state":"error"}
This in spite of the fact that when I ask the camera about its options, it responds with the exact block it has just told me wouldn't parse:
$ curl -X POST -H "Content-Type: application/json; charset=UTF-8" -d '{"name":"camera.getOptions", "parameters":{"optionNames":["clientVersion","captureMode","fileFormat"]}}' http://192.168.1.1/osc/commands/execute
gets this response:
{"name":"camera.getOptions","results":{"options":{"captureMode":"image","clientVersion":2,"fileFormat":{"height":3360,"type":"jpeg","width":6720}}},"state":"done"}
Furthermore, when I run the first command and omit the fileFormat parameter, the command executes just fine.
Any ideas what I am doing wrong here?
After a bunch of trial and error, I discovered that it is possible to use camera.setOptions to set the file format on the camera, but only if the fileFormat block is the only member of the options block. That is to say, this command:
$ curl -X POST -H "Content-Type: application/json; charset=UTF-8" -d '{"name":"camera.setOptions", "parameters":{"options":{"fileFormat":{"height":3360,"type":"jpeg","width":6720}}}}' http://192.168.1.1/osc/commands/execute
will succeed. I think this must be a bug in the Theta Z1 camera, because as far as I can discern from the docs (https://api.ricoh/docs/theta-web-api-v2/commands/camera.set_options/ and https://developers.google.com/streetview/open-spherical-camera/reference/camera/setoptions), there shouldn't be any restriction on what JSON goes into the options block. In any case, the workaround is simple enough: issue one command to set the file format and one or more as necessary to set the other options, and then you're good to go.
FYI, there is a similar bug with dateTimeZone. see this post
https://community.theta360.guide/t/how-setup-datetime-on-theta-camera-using-web-api/6572/3?u=craig
It seems like there are a few options that need to be set as a standalone option.
If you want to set dateTimeZone, it must be the only option set. I reported this to RICOH. I am going to post your findings on the community.theta360.guide forum to make it easier to find. Thanks.

How to pass cyrillic symbols with POST request with flask

I have such a route:
#app.route('/wikidata/api/v1.0/ask', methods=['POST'])
def get_tasks():
print(request.data)
print(request.json)
return jsonify(1)
I send a request:
curl -i -H "Content-Type:application/json" -X POST -d "{\"название\": \"значение?\",\"param1\": \"Q29424\"}" http://localhost:8529/wikidata/api/v1.0/ask
and get the error:
HTTP/1.0 400 BAD REQUEST
Content-Type: text/html
Content-Length: 223
Server: Werkzeug/0.14.1 Python/3.6.5
Date: Fri, 15 Feb 2019 08:34:27 GMT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>Failed to decode JSON object: 'utf-8' codec can't decode byte 0xed in position 2: invalid continuation byte</p>
Meanwhile print(request.data) shows that request.data is b'{"\xed\xe0\xe7\xe2\xe0\xed\xe8\xe5": "\xe7\xed\xe0\xf7\xe5\xed\xe8\xe5?","param1": "Q29424"}'
The only thing that helped so far is
decoded_data = request.data.decode('windows-1251')
question = json.loads(decoded_data)
I'm looking a way to send a request properly (or configure server) so that I can use request.json without errors.
Thank you.
That's a Windows specific issue likely due to the default charset in the Windows console prompt. The cyrillic characters in your command line are misinterpreted with a non UTF-8 compatible charset.
Since you already use Python, the easiest way IMHO to send your request is to use the requests module (that you can install using pip install requests). Then type this command in a python file, using UTF-8 as charset:
import requests
requests.post("http://localhost:8529/wikidata/api/v1.0/ask", json={"название": "значение?","param1": "Q29424"})
Run it and it will have the same effect as your curl command line, only with proper cyrillic characters handling.

Issue adding attachments to documents in CouchDB

I'm having problems adding attachments in CouchDB. First off, when I ran the test suite in Futon I got two errors - one in attachments, and another in replication. The error specific to attachments isn't particularly helpful -
name
attachments
status
error
duration
6112
details
0
Exception raised: {}
Some internet commentary says that a few errors in the test suite is perfectly normal, so I moved on. However, attachments are definitely not working properly, either via Futon or Curl. In Futon, the file will generally attach, but only after I click cancel on the upload - i.e. it hangs on the upload progress bar indefinitely until I click cancel. I'm accessing futon on a remote machine via ssh -L5984:127.0.0.1:5984 root#myServer and then pointing Firefox at localhost:5984/_utils/. I don't know if that could be making a difference.
When I try to upload via Curl, using the command
curl -vX PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af/ artwork.jpg?rev=9--43332bfae07884c683b50ffd4b8ee18c --data-binary #artwork.jpg -H "Content-Type: image/jpg"
I get:
Host: 127.0.0.1:5984
Accept: /
Content-Type: image/jpg
Content-Length: 11205
Expect: 100-continue
< HTTP/1.1 100 Continue
< HTTP/1.1 400 Bad Request
* HTTP error before end of send, stop sending
{"error":"bad_request","reason":"invalid UTF-8 JSON"}
The log file shows:
[debug] [<0.103.0>] 'PUT' /albums/6e1295ed6c29495e54cc05947f18c8af/ {1,1}
Headers: [{'Accept',"*/*"},
{'Content-Length',"11205"},
{'Content-Type',"image/jpg"},
{"Expect","100-continue"},
{'Host',"127.0.0.1:5984"},
{'User-Agent',"curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3"}]
[debug] [<0.103.0>] OAuth Params: []
[error] [<0.103.0>] attempted upload of invalid JSON (set log_level to debug to log it)
Followed by a huge block -
[debug] [<0.103.0>] Invalid JSON:
<<255,216,255,224,0,16,74,70,73,70,0,1,1,0,0,1,0,1,0,0,255,219,0,132, ... , etc
The final two lines in the log that are relevant to the attempted upload are
[info] [<0.103.0>] 127.0.0.1 - - 'PUT' /albums/6e1295ed6c29495e54cc05947f18c8af/ 400
[debug] [<0.103.0>] httpd 400 error response: {"error":"bad_request","reason":"invalid UTF-8 JSON"}
Does anyone have any idea what is going on here? I tried wrapping the string in the curl request around ' ' in case bash was eating the quotes, it made no difference.
There is a spurious space in your curl command after the slash between the doc id and the attachement:
...f18c8af/ artwork.jpg?...
^
Does it work when you remove it?
There were two problems. The first was the spurious space that Simon pointed out - tyvm. The other problem was where the rev-x details are placed. I was using the format in the book http://guide.couchdb.org/editions/1/en/api.html.
Original command:
curl -vX PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af/ artwork.jpg?rev=9--43332bfae07884c683b50ffd4b8ee18c --data-binary #artwork.jpg -H "Content-Type: image/jpg"
Working command (space removed & rev placed in the correct order):
curl -vX PUT http://127.0.0.1:5984/albums/6e1295ed6c29495e54cc05947f18c8af/attachment?rev=9-43332bfae07884c683b50ffd4b8ee18c --data-binary #artwork.jpg -H "Content-Type: image/jpg"

WSO2 Data Services JSON issue

I hope you can help me getting JSON REST WSO2 Data Service work.
I use v 3.0.1 and sample data service. I suspect that I do smth wrong...
I created a resource 'products' that is bound to productsSQL query.
XML REST request work perfectly, but not JSON:
curl --request GET
http://myserver.com:9763/services/samples/RDBMSSample.HTTPEndpoint/products
-H Content-Type:"application/json"
returns
> "Fault":{"faultcode":"","faultstring":"No JSON message received
> through HTTP GET or POST","detail":""}}
From the source code looks like it expects to have some request body in request url (which is strange), so the next query is
curl --request GET
http://myserver.com:9763/services/samples/RDBMSSample.HTTPEndpoint/products?q=emptyquery
-H Content-Type:"application/json"
This one hangs and on server after several minutes I get the following exception:
> Feb 24, 2013 8:08:13 PM
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor run SEVERE:
> java.lang.ThreadDeath at java.lang.Thread.stop(Thread.java:776) at
> org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.handleStuckThread(CarbonStuckThreadDetectionValve.java:121)
> at
> org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.backgroundProcess(CarbonStuckThreadDetectionValve.java:175)
> at
> org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1387)
> at
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1566)
> at
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1576)
> at
> org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1555)
> at java.lang.Thread.run(Thread.java:680)
The following query works, however:
curl --data '{"employeesbynumber":{"employeenumber":{"$":"1002"}}}'
http://myserver.com:9763/services/samples/RDBMSSample/ --header
Content-Type:"application/json" --header
SOAPAction:"urn:employeesByNumber"
So after several hours debugging WSO2 DSS and Axis2 code there is a fix:
Reason: WSO2 still runs on Axis 1.6.1 which had some critical bugs in JSONOMBuilder and JSONDataSource (which seem to have been fixed in 1.6.2). Specifically it required all GET requests to have input parameter and also wrapped in a root element + some other issues. The fact is that inside, AXIS2 maps JSON payload to SOAP body, so needs to have root element..
Solution More of a workaround: For GET requests pass request body with parameters wrapped in a root element (and of course url encoded). Even if you do not have parameters - pass them anyway.
So the following queries work:
curl --request GET http://192.168.1.10:9763/services/samples/RDBMSSample.HTTPEndpoint/employees?q=%7B%22request%22%3A%7B%22employeeNumber%22%3A%221%22%7D%7D%20 -H Content-Type:"application/json"
And this one for query without parameter but passing dummy one anyway:
curl --request GET http://192.168.1.10:9763/ervices/samples/RDBMSSample.HTTPEndpoint/products?q=%7B%22request%22%3A%7B%22employeeNumber%22%3A%221%22%7D%7D%20 -H Content-Type:"application/json"
Hope WSO2 guys will update to latest Axis2 soon...
I think the way you call REST cal from curl is wrong if you want to play with curl you can use the reference [1].
the correct message would be
curl -i -H "Accept: application/json" http://myserver.com:9763/services/samples/RDBMSSample.HTTPEndpoint/products
Else there is a good Google chrome plugin "Advanced REST client" you can simply use it for invoke REST services.
[1]. http://blogs.plexibus.com/2009/01/15/rest-esting-with-curl/

Chrome freezes when playing videos from Rackspace cloudfiles

Can't seem to get chrome to play videos with html5 video tag when I host them on a Rackspace cloudfiles server.
Works perfectly on the regular hosting, but as soon as I link the video with the rackspace cdn url, Chrome freezes (total freeze, website UI completely blocked - after a while Chrome pops a message saying "The following page has become unresponsive bla bla bla").
The video file is fine as it's same as when I link to the regular hosting.
Did a bit of spying on the requests, and I initially thought the problem was that the webm files were serverd by default as application/octet-stream mime-type. I lodged a ticket to rackspace and they gave me a way to force the mime-type when uploading the file. Did that, and the file is now correctly sent as video/webm.. but Chrome still freezes.
Any idea what could be going wrong here?
EDIT: using iheartvideo, loading the video from rackspace triggers a MEDIA_ERR_SRC_NOT_SUPPORTED. Same video off local web server works totally fine (??)
EDIT 2: Happens on both mac and windows with latest mainstream chrome
EDIT 3: curl -I results:
Rackspace (no worky):
HTTP/1.1 200 OK
Server: nginx/0.7.65
Content-Type: video/webm
Last-Modified: Thu, 24 Feb 2011 23:45:12 GMT
ETag: 7029f83b241aa691859012dfa047e20d
Content-Length: 20173074
Cache-Control: public, max-age=900
Expires: Fri, 25 Feb 2011 01:32:11 GMT
Date: Fri, 25 Feb 2011 01:17:11 GMT
Connection: keep-alive
Web Server (worky)
HTTP/1.1 200 OK
Date: Fri, 25 Feb 2011 01:17:51 GMT
Server: Apache
Last-Modified: Thu, 24 Feb 2011 03:56:26 GMT
ETag: "11a0b47-133d112-49cff32940e80"
Accept-Ranges: bytes
Content-Length: 20173074
Content-Type: text/plain
EDIT 4: For those interested, this is what the rackscape crew told me to do to set a webm content type on a file:
The file browser is not smart enough
to determine the content type
video/webm. Unfortunately, there is
not a way to change the content type
of a file that has already been
uploaded.
You'll need to use one of the API to
re-upload your files with the correct
content type.
You can also use curl from a
linux/MacOS command line if available.
Using your username and api key run
this command...
curl -I -X GET -H "X-Auth-User: USERNAME" -H "X-Auth-Key: API_KEY" https://auth.api.rackspacecloud.com/v1.0
From the output there are 2 important
values.
X-Storage-Url: https://storage101.......
X-Storage-Token: Long hash
You can upload the files with,
curl -X PUT -T test.webm -H "Content-Type: video/webm" -H "Content-Length: FILESIZEINBYTE" -H "X-Auth-Token: TOKEN FROM RESPONSE ABOVE" https://STORAGE URL FROM RESPONSE ABOVE/test.webm
You must specify the content type, and
you must give the correct length of
bytes of what is being uploaded. If
not you will get an invalid request
error.
I work quite a bit with the Rackspace API.
Their API actually allows you to set a container as streaming enabled. My first instinct tells me that you haven't done this.
I stream various file types and they all work an absolute treat.
There is more information about CDN Streaming Enabled containers here:
http://docs.rackspace.com/files/api/v1/cf-devguide/content/Streaming-CDN-Enabled_Containers-d1f3721.html
Hopefully this helps, but if not let me know and I don't mind putting some PHP example code together to help you along.
Its all quite easy, but getting your head around the various API operations that Rackspace have implemented can sometimes be a daunting task.
I don't have a concrete answer, just some thoughts:
what about in other browsers?
it works on the web server with the content type above is text/plain so why force to video/webm?
can Rackspace provide you (or can you find on their site or someone else's) some sample content that does play so you can inspect it?
You could try the free trial from Brightcove or Bitgravity and see if that works...