Sending json as data with GET call - java

I can see that the following curl command works remotely:
curl -X GET -d '{"begin":22, "end":33}' http://myRemoteApp.com:8080/publicApi/user/test/data
However as per the docs at http://curl.haxx.se/docs/manpage.html,
-d, --data
(HTTP) 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. Compare to -F, --form.
So how is the GET working with curl if we are using -d to post data ?
Also there is no HttpUrlConnection method OR Restlet method to send json in a GET call. Is there ?

According to the curl documentation, -X forces the method word to be a particular value, regardless of whether it results in a sensible request or not. We can run curl with tracing to see what it actually sends in this case:
$ curl -X GET -d '{"begin":22, "end":33}' --trace-ascii - http://localhost:8080/
== Info: About to connect() to localhost port 8080 (#0)
== Info: Trying ::1... == Info: connected
== Info: Connected to localhost (::1) port 8080 (#0)
=> Send header, 238 bytes (0xee)
0000: GET / HTTP/1.1
0010: User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7
0050: NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
0084: Host: localhost:8080
009a: Accept: */*
00a7: Content-Length: 22
00bb: Content-Type: application/x-www-form-urlencoded
00ec:
=> Send data, 22 bytes (0x16)
0000: {"begin":22, "end":33}
So this command does in fact cause curl to send a GET request with a message body.
This question has some extensive discussion of using GET with a request body. The answers agree that it's not actually illegal to send a GET request with a message body, but you can't expect the server to pay attention to the body. It seems that the specific server which you're using does handle these requests, whether due to a bug, happy accident, or deliberate design decision.

Related

unable to read the original url when host is specified

My code is running on localhost and i am hitting one of my urls as below
curl -k -vv --http1.1 "https://localhost:8443/versa/login" -H 'Host: google.com'
Now i m a trying to read the url in my code using following
StringBuffer url = httpServletRequest.getRequestURL();
The value is always as follows irrespective the protocol used is HTTP/1.1 or HTTP/2
https://google.com/versa/login
How to read the original url here?
You can't. Have a look at the output from curl - it should give the clue [I dropped the HTTPS to HTTP to simplify but same for HTTPS just more debug from CURL]
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8443 (#0)
> GET /versa/login HTTP/1.1
> Host: google.com
> User-Agent: curl/7.64.1
> Accept: */*
The first two lines are just debug. The next 4 is what is sent to the server .. See nothing about port or localhost ..

How to customize response Error 400 Bad Request

I have a web service provided by jetty.
How can i filter URL with illegal characters?
I can not control some return information when the request URL has illegal characters.
actually, i want to return some specific info when the URL is invalid.
for example: i added a filter in my application to validate the URL, if illegal then i will return defined info.
but, I can not filter some URL like "%adsasd", it seem be handled by jetty.
curl -v -X PUT -u user:password 'http://myip.com:8080/%adsasd'
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'user'
> PUT /%adsasd HTTP/1.1
> Authorization: Basic YWRtaW46MTIzNDU2
> User-Agent: curl/7.35.0
> Accept: */*
> Host:127.0.0.1:8080
> < HTTP/1.1 400 Bad Request
< Content-Length: 0
* Server Jetty(9.0.6.v20130930) is not blacklisted
< Server: Jetty(9.0.6.v20130930) <
* Connection #0 to host 127.0.0.1 left intact
The error response from Jetty
HTTP/1.1 400 Bad Request
indicates that Jetty did detect that as a bad URL and rejected it.
As for how to customize this, that is really tricky, mainly due to how early in the processing of this specific request it occurs in.
This kind of error (400 Bad Request) occurs during the parsing of the raw incoming http request, well before the server container has even attempted to figure out what context to talk to.
There is no way to have a custom error handler in a specific webapp context handle this sort of fundamental http error. As the server has yet to figure out what context to even talk to.
There is also no way at the server side (even at a global level) to customize this error message.
If you want such a feature, please file a feature request.

CXF REST service is returning more than 1 http code

When I run my service, which is just a simple POST, I'm getting an HTTP 100 followed by a 200.
Is there any way to get it to just return an HTTP 200?
curl -D- -X POST -H "Content-Type: application/json" -d #input.json http://myserver/contxt/services/rest/service/notify
Returns:
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Date: Thu, 17 Jul 2014 14:20:05 GMT
Content-Type: text/plain
Content-Length: 2
The status code 100 is not the response to the whole request. The server is telling that he has received the headers and the client should proceed sending the request body. Sending the entity with e.g. a Content-Type the server won't accept anyway would be just a waste of bandwidth.
The server should only send the status 100 if he has received the header Expect: 100-continue. cURL is sending this header "for POSTs with unknown sizes". This may be the case for big files.
You can try to explicitly overwrite this header:
curl -H "Expect:" ...

Implementing If-Match HTTP Header in Spring

The ShallowEtagHeaderFilter which is part of Spring processes the If-None-Match header on an Http request. As part of the Http 1.1 spec this returns an Http status of 304 - Not Modified if the contents of the If-None-Match header sent on the request is the same as the Etag header. This is helpful for caching as it means that if the Etag is the same on the client and server then the contents will be identical.
This is fine.
However my question is this - does Spring have support for the If-Match header (again part of HTTP 1.1) rather than If-None-Match because as far as the docs go it looks like the ShallowEtagHeaderFilter only processes the If-None-Match header. I need the If-Match header to prevent simultaneous requests from overwriting the previous one. IE I only want the request to be processed if the Etags are the same and hence they have the latest version of the entity.
It doesn't look like the ShallowEtagHeaderFilter supports If-Match:
curl "Accept: application/json" -H 'If-Match: "somevalue"' -i http://localhost:8080/rest-sec/api/resources/1
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ETag: "03cb37ca667706c68c0aad4cb04c3a211"
Content-Type: application/json;charset=UTF-8
Content-Length: 56
Date: Fri, 11 Jan 2013 14:58:40 GMT
I opened a JIRA issue to track this:
https://jira.springsource.org/browse/SPR-10164

c2dm 401 error when sending messages after receiving id and auth token

I have seen many similiar questions but no good answer despite some of them being accepted.
I have registered for C2DM. I received confirmation email. Then I wrote some simple app to register for C2DM. I get the id (tried on emulator and on real device). Then I got the auth token (with curl) for my email that I used for C2DM registration (the same email that I use in app for acquiring the id).
When I try to do the push (also with curl), I get 401 error (like the auth token is wrong).
I read many tutorials and I am running out of ideas.
Let me try it (with curl only):
At first we are applying for the auth token:
curl.exe -v -k https://www.google.com/accounts/ClientLogin -d Email=xyz#gmail.com -d Passwd=secret -d accountType=GOOGLE -d source=your.registered.domain -d service=ac2dm
In the result your are receiving the auth token:
< HTTP/1.1 200 OK
SID=XXX
LSID=XXX
Auth=XXX
* Connection #0 to host www.google.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
Please note that the Auth response is in the result with an uppercase first letter: "Auth=XXX"!
Now we are using the result for the next request but with lowercase first letter:
curl.exe -v -k --header "Authorization: GoogleLogin auth=XXX" https://android.apis.google.com/c2dm/send -d "registration_id=XXX" -d "data=helloooo" -d collapse_key=Z
And this works! But you are getting a 401 error, if you are using the auth like in the first response (upper case A in "Auth"):
curl.exe" -v -k --header "Authorization: GoogleLogin Auth=XXX" https://android.apis.google.com/c2dm/send -d "registration_id=XXX" -d "data=helloooo" -d collapse_key=Z
So the "auth" of request 2 is case sensitive. I think this is a pitfall 50% of the users are stepping into. Hope that helps.
Maybe this is the problem?
http://groups.google.com/group/vogella/browse_thread/thread/95865344e6d2c734
Basucally, the "sender" parameter that you specifiy on teh Android device must be the same email address that is registred as the sender (server-side).

Categories