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
>
>

Reply via email to