Hello,

When you try to access the raw InputStream of a x-www-form-urlencoded
servlet request, the stream could have already been indirectly consumed by
a prior access to the parameters (e.g., via
ServletRequest#getParameterMap()) of the request. This feature (bug?) has
already been documented in the section SRV.3.1.1 of the Servlet spec
<https://javaee.github.io/servlet-spec/downloads/servlet-3.1/Final/servlet-3_1-final.pdf>
and there are other people (Bug 47410
<https://bz.apache.org/bugzilla/show_bug.cgi?id=47410>) who have been
bitten by this as well.

This indirect stream consumption makes it, to the best of my knowledge,
impossible to mirror the InputStream, which is exactly what we are trying
to achieve in HRRS <https://github.com/vy/hrrs>. Hence, I try to re-construct
the InputStream from request parameters
<https://github.com/vy/hrrs/blob/master/servlet-filter/src/main/java/com/vlkan/hrrs/servlet/HrrsUrlEncodedFormHelper.java>.
This, as you can imagine, a really nasty hack which I am not fond of
either. Further, to make the things worse, when servlet pushes the form
parameters into request parameter map, it merges them with query parameters
too. Now you need to manually parse both request and query parameters to
figure out the initial form parameters. I am not even talking about lost
parameter ordering. A total shipwreck.

Even if HRRS is the first filter in the list, it is not consuming
InputStream, it is just wrapping the InputStream and passing along the
wrapped request along the chain. Problem is, getParameter() calls in Tomcat
is using an internal reference to the InputStream (that is,
o.a.c.connector.Request#getStream()) and not calling
javax.servlet.ServletRequest#getInputStream(). Hence, InputStream gets
indirectly consumed without the wrapped one getting used at all. Is it
possible to make o.a.c.connector.Request#readPostBody() use
getInputStream() rather than getStream() to solve this problem? Or is there
an easier fix that I am missing?

Best.

Reply via email to