On 23.11.2015 21:14, Roel Storms wrote:
Ok, thank you for the clear response. I see the problem with file type
elements.
If you really have an overwhelming need to pre-check whole POST bodies before passing them
to a Tomcat application, you may want to think about fronting your Tomcat server with an
Apache httpd server. You could then do the checking at the Apache httpd level, before
forwarding the request to Tomcat. And of course not forward it at all if the check fails.
Doing this at the front-end level would not "consume" the request body, as it does when
you do this under Tomcat.
All in all, you would still end up reading the request body twice. But depending on your
use case, it may be worth it.
In your initial post below, you wrote "..some integrity checking on HTTP
requests (the details aren't important)..".
But if you want further help or recommendations, I believe that more details about what
exactly you are trying to achieve and/or check, would be important.
After all, Tomcat is already making a fair amount of checking by default, on any received
HTTP request, before it will forward it to any application. So it would be interesting to
have an idea of which extra checks you want to make.
2015-11-23 17:18 GMT+01:00 André Warnier (tomcat) <a...@ice-sa.com>:
On 23.11.2015 16:31, Mark Thomas wrote:
On 23/11/2015 14:30, Roel Storms wrote:
Hello,
I am working on a Valve that does some integrity checking on HTTP
requests
(the details aren't important) where I need this valve to have access to
the HTTP request body as well. I used request.getInputStream to fetch the
data. However when a web application makes use of my valve, the
getParameter method does not return the parameters submitted via POST
anymore. This is documented behavior according to the spec of
ServletRequest (
https://tomcat.apache.org/tomcat-8.0-doc/servletapi/javax/servlet/ServletRequest.html#getInputStream()
).
I was wondering why it was designed this way,
Given the potential size of a request body, streaming is the only viable
option.
since numerous complaints
have arisen from this behavior and some ugly workarounds have been
devised
which unfortunately stop working from Tomcat 7 (servlet 3.0):
https://stackoverflow.com/questions/10210645/http-servlet-request-lose-params-from-post-body-after-read-it-once
This shows how easily code like this could break.
What that shows is the folks haven't thought through what they are
trying to do. Consider the following:
Tomcat provides request R.
Filter reads request body using R.getInputStream().
Filter caches request body.
Filter wraps request R to provide R', over-riding getInputStream() to
provide the cached body.
Filter passes R' to the application.
Application calls R'.getParameter()
R'.getParameter() calls R.getParameter()
Keep in mind at this point R has zero knowledge of R'.
R calls getInputStream() to read request body but that InputStream has
already been read.
The problem is the wrapper, R'. Over-riding getInputStream() is not
enough. It needs to over-ride every method that may access that
InputStream. Which is non-trivial because it means re-implementing a lot
of functionality the container would normally provide for you out of the
box.
Overwriting getInputStream to return a cached version doesn't work anymore
Nope. That never worked. See my explanation above.
since the parameter attribute isn't populated by using getInputStream. How
exactly it is populated remains a mystery to me. Any advice on how to
solve
this properly?
Write a better wrapper.
Performing an integrity check without getInputStream or getReader but with
getParameters, will not work if the data submitted is not in the expected
format.
See above.
Mark
To emphasize a point made by Mark above : a POST body can potentially
contain one or more <input type="file" ..> elements. So imagine a POST
which contains a 50 MB uploaded file.
You'd need to read it once (for your Valve) and cache it, then re-read the
cached version to parse it for parameters. That would have a serious
impact on performance.
(That's what Mark means by "streaming..").
And because it is a Valve, it would run before the request has been mapped
to any application, so the hit would be for all applications in the server.
(Of course, in some authentication scenarios, this already happens behind
the scenes. But you can avoid it by designing the application accordingly.
See : https://tomcat.apache.org/tomcat-8.0-doc/config/http.html -->
Common Attributes --> maxSavePostSize)
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org