Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify HttpServletRequest body

Tags:

java

http

request

I'm working on legacy code and need to make a patch.

The problem: an ancient application sends bad HTTP POST requests. One of the parameters is not URL encoded. I know that this parameter always comes last and I know it's name. I'm now trying to fix it on the server side which is running inside tomcat.

This parameter is not accessible via standard getParameter method of HttpServletRequest, since it's malformed. Method simply returns null. But when I manually read the whole body of request through ServletInputStream all the other parameters disappear. Looks like underlying classes can't parse contents of ServletInputStream since it's drained out.

So far I've managed to make a wrapper that reads all parameters from body and overrides all parameter access methods. But if any filter in the chain before mine will try to access any parameter, everything will break since ServletInputStream will be empty.

Can I somehow evade this problem? May be there's different approach?

To summarize, If I'll read raw request body in the filter, parameters will disappear from the request. If I read single parameter, ServletInputStream will become empty and manual processing will be impossible. Moreover, it's impossible to read malformed parameter via getParameter method.

like image 728
clorz Avatar asked Mar 25 '09 11:03

clorz


2 Answers

Solution I've found:

It's not enough to just redefine parameter accessing methods. Several things must be done.

  1. A filter is needed where request will be wrapped.
  2. A custom HttpRequestWrapper is needed with all parameter access methods overridden. Request body should be parsed in constructor and stored as a field.
  3. getInputStream and getReader methods should be redefined as well. They return values depend on the stored request body.
  4. Custom class extending ServletInputStream is required since this one is abstract.

This 4 combined will allow you to use getParameter without interference with getInputStream and getReader methods.

Mind that manual request parameter parsing may get complicated with multipart requests. But that's another topic.

To clarify, I redefined parameter accessing methods because my request was damaged as stated in the question. You may not need that.

like image 198
clorz Avatar answered Sep 20 '22 14:09

clorz


Rather than overriding methods, why don't you install a servlet filter which rewrites the request?

Jason Hunter has a pretty good article on filters.

like image 40
Jon Skeet Avatar answered Sep 21 '22 14:09

Jon Skeet