users@grizzly.java.net

Re: HTTPServlet InputStream/Reader return EOF for POST requests

From: Matthew Swift <matthew.swift_at_gmail.com>
Date: Tue, 28 Aug 2012 17:25:49 +0200

Yes that was it. I'm glad I put the "dumb HTTP newbie" disclaimer at the
start of my email! :-)

Thanks for your help and sorry for the noise.

Cheers,

Matt


On 25 August 2012 09:27, Oleksiy Stashok <oleksiy.stashok_at_oracle.com> wrote:

> Hi Matt,
>
> this might be related (from Servlet spec):
>
> "When Parameters Are Available
> The following are the conditions that must be met before post form data
> will be
> populated to the parameter set:
> 1. The request is an HTTP or HTTPS request.
> 2. The HTTP method is POST.
> 3. The content type is application/x-www-form-urlencoded.
> 4. The servlet has made an initial call of any of the getParameter family
> of methods
> on the request object.
> If the conditions are not met and the post form data is not included in
> the parameter
> set, the post data must still be available to the servlet via the request
> object’s input
> stream. If the conditions are met, post form data will no longer be
> available for
> reading directly from the request object’s input stream.
> "
>
> WBR,
> Alexey.
>
>
> On 08/25/2012 12:21 AM, Matthew Swift wrote:
>
> Hi there,
>
> Please accept my humble apologies if this is a dumb HTTP newbie mistake
> I am making.
>
> I have written a Servlet using Grizzly 2.2.14 and 2.3 which implements
> all basic HTTP methods. Unfortunately, I'm hitting a problem in my
> implementation of the POST method. I issue two requests: one PUT and one
> POST containing the same content, only differing slightly on the
> URL. Here's the PUT using curl with debugging enabled:
>
> $ curl -v --request PUT "
> http://localhost:18890/example/managed/users/1?_pretty-print=true&_debug=true"
> --data '{"userName":"charlie","employeeNumber":3141,"email":"
> charles_at_example.com"}'
> * About to connect() to localhost port 18890 (#0)
> * Trying 127.0.0.1... connected
> > PUT /example/managed/users/1?_pretty-print=true&_debug=true HTTP/1.1
> > 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
> > Host: localhost:18890
> > Accept: */*
> > Content-Length: 74
> > Content-Type: application/x-www-form-urlencoded
> >
> * upload completely sent off: 74out of 74 bytes
> < HTTP/1.1 200 OK
> < Content-Type: application/json;charset=UTF-8
> < server: grizzly/2.3
> < ETag: "1"
> < Date: Fri, 24 Aug 2012 21:52:36 GMT
> < Transfer-Encoding: chunked
> <
> {
> "userName" : "charlie",
> "employeeNumber" : 3141,
> "email" : "charles_at_example.com",
> "_id" : "1",
> "_rev" : "1"
> * Connection #0 to host localhost left intact
> * Closing connection #0
>
>
> And here's the POST which differs only in the URL and the method:
>
> $ curl -v --request POST "
> http://localhost:18890/example/managed/users?_pretty-print=true&_debug=true"
> --data '{"userName":"charlie","employeeNumber":3141,"email":"
> charles_at_example.com"}'
> * About to connect() to localhost port 18890 (#0)
> * Trying 127.0.0.1... connected
> > POST /example/managed/users?_pretty-print=true&_debug=true HTTP/1.1
> > 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
> > Host: localhost:18890
> > Accept: */*
> > Content-Length: 74
> > Content-Type: application/x-www-form-urlencoded
> >
> * upload completely sent off: 74out of 74 bytes
> < HTTP/1.1 500 java.io.EOFException: No content to map to Object due to
> end of input
> < server: grizzly/2.3
> < Date: Fri, 24 Aug 2012 21:55:46 GMT
> < Connection: close
> < Content-Length: 0
> <
> * Closing connection #0
>
>
> At the point where the POST fails both method implementations have done
> the exact same processing, however the POST implementation fails to read
> anything from the HTTP request's InputStream (it's already at EOF). I
> verified using Wireshark that curl is not doing anything sneaky for POST
> operations and it isn't. However, when I dump the HTTP request's headers
> from within the servlet, I see something strange in the POST parameters:
>
> Aug 25, 2012 12:15:25 AM org.glassfish.grizzly.servlet.WebappContext log
> *INFO: [example] Method=PUT*
> Header 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
> Header host=localhost:18890
> Header accept=*/*
> Header content-length=74
> Header content-type=application/x-www-form-urlencoded
> RequestURI=/example/managed/users/1
> ContextPath=/example
> ServletPath=/managed
> PathInfo=/users/1
> QueryString=_pretty-print=true&_debug=true
> Parameter _pretty-print=[true]
> Parameter _debug=[true]
>
>
> Aug 25, 2012 12:16:01 AM org.glassfish.grizzly.servlet.WebappContext log
> *INFO: [example] Method=POST*
> Header 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
> Header host=localhost:18890
> Header accept=*/*
> Header content-length=74
> Header content-type=application/x-www-form-urlencoded
> RequestURI=/example/managed/users
> ContextPath=/example
> ServletPath=/managed
> PathInfo=/users
> QueryString=_pretty-print=true&_debug=true
> Parameter _pretty-print=[true]
> Parameter _debug=[true]
> *Parameter {"userName":"charlie","employeeNumber":3141,"email":"
> charles_at_example.com"}=[]*
>
>
> If the request content has been parsed as a header then it's no wonder
> that the input stream is already at EOF when I want to read from it. Is
> this expected behavior?
>
> I've tried with Grizzly 2.2.x as well as the 2.3 SNAPSHOT and
> combinations of Servlet 2.5 and 3.0.1 but to no avail.
>
> Cheers,
>
> Matt
>
>
>