Ok, thank you for the clear response. I see the problem with file type elements.
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 > >