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 unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org