-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Jose,
On 1/14/15 4:03 PM, Christopher Schultz wrote: > Jose, > > On 1/14/15 3:54 PM, Jose María Zaragoza wrote: >> 2015-01-14 20:05 GMT+01:00 Christopher Schultz >> <ch...@christopherschultz.net>: Jose, > >> On 1/14/15 8:27 AM, Jose María Zaragoza wrote: >>>>> 2015-01-14 12:46 GMT+01:00 André Warnier <a...@ice-sa.com>: >>>>>> Jose María Zaragoza wrote: >>>>>>> >>>>>>> Hello: >>>>>>> >>>>>>> I would like to create a web filter to forward some >>>>>>> requests to another webserver, >>>>>>> >>>>>>> The filter receives an >>>>>>> "application/x-www-form-urlencoded" request , inspects >>>>>>> the value of a parameter and chooses to forward to >>>>>>> another remote webserver ( as a proxy ) >>>>> >>>>> >>>>> Thanks >>>>> >>>>> I agree with you . I'll try to use an Apache httpd >>>>> front-end >>>>> >>>>> Anyway, I've seen that if I execute >>>>> >>>>> Map<String, String[]> parameter = ((HttpServletRequest) >>>>> request).getParameterMap(); >>>>> >>>>> , then request.getInputStream is empty >>>>> >>>>> >>>>> But if I execute >>>>> >>>>> Map<String, String[]> parameter = ((HttpServletRequest) >>>>> request).getParameterMap(); chain.doFilter(request, >>>>> response); >>>>> >>>>> , the next filter in the chain receives the body ( as I >>>>> expect it ) >>>>> >>>>> I don't understand this behaviour > >> I think that might be a bug... calling >> HttpServletRequest.getParameter* should cause the request entity >> to be parsed, as long as the content type is >> application/x-www-form-urlencoded. I think getParameterMap >> counts, but I'd have to review the spec & javadoc (where some fun >> spec requirements are hidden!). > >> Anyhow, when you call HttpServletRequest.getParameter*, the >> container *must* consume the request, according to the spec. > > >>> Thanks. > >>> In my case, all requests to be forwarded are POST requests ( >>> and content type is application/x-www-form-urlencoded ) >>> According to your reply, if I've got a chain of filters and the >>> first one calls getParameterMap , do the next filters lose the >>> content of the payload ? > > Correct. Once the request entity has been read (which happens when > you call request.getParameter*), it's no longer available to the > application. > >>> I tested to call several times to getParameterMap method on >>> the same webfilter and it always returned the right values. >>> Looks like getParameterMap doesn't consume() payload, but ... >>> if I call getInputStream() after getParameterMap() , the stream >>> is empty > >>> I'm using Tomcat 7.0.50 and I cannot understand the logic of >>> this > > Interesting. I find that surprising... I'll look into that. Maybe I misunderstood you, but it sounded like it you called getParameterMap() and then tried to read the InputStream to read the request entity, you were still able to read it. I just did a simple test and, of course, that's not the case at all. When you call any of the family of getParameter* methods, the entity will be parsed and saved by the container for the life of the request. It doesn't matter how many times you call getParameter*, the entity will only be parsed once, and once it's been parsed, it will no longer be available to any other code: filter, servlet, etc. If you call HttpServletRequest.getInputStream or HttpServletRequest.getReader *before* any call to getParameter*, then the container will not even attempt to parse the request entity and everything will return null (or an empty map for the case getParameterMap). If you call getInputStream/getReader, the container concludes that the application (filter, servlet, whatever) has assumed responsibility for handling the post data and therefore doesn't do anything with it itself. So, back to your proxy servlet. If you want to read POST data to decide how to route the request, you'll have to do it by handling the request entity yourself. If you don't do it yourself, you won't be able to reconstruct the exact byte stream that the client sent, which is part of the deal when you are a proxy. If you don't want to be a formal proxy, then you can cheat and use getParameter* and then do a messy re-construction of the original request and send *that* to the other back-end server. Most proxies make their decisions based upon information found in the HTTP headers to avoid this exact problem. If you *must* make your decisions based upon the contents of the message, then you will have to handle a lot of buffering and plumbing code to make it all work. - -chris -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 Comment: GPGTools - http://gpgtools.org iQIcBAEBCAAGBQJUt985AAoJEBzwKT+lPKRYoHEQAMm5FBnv+mKu0V6ZObzyYCZt 6YzeNnk+rgR7sEAHNBJ2rOiMp/JEydgT896yw1qN+YUiYT33Mf0RMiYsJKhUaf/P KGjuRoHT60AibP2r+mi1LY5o3Wt+EKZ/lFIGBBCyfPDElYq7iokjYZDfedg1TiIg DBjucF29K+mVaq8wFBXHVK64bJo9Jfj87YO5x8syDJFgV57mELAMofKv5+3yL8Lz 3n7TcEJr2uoxZj8qVpRWmvdSkBN/p4drXW/kDtDf/IbPz3Lf0WC97Opj0QxuoeuX aKwi94AyUH5fNai/0pSaTFQmnaqwhKDXaJhaaAv0YHcN/StyRO+JNz6rkCshxRD7 MvhzudpLDPbrZjN0McuEY9H43qqzNoAzh17i97PcEmHC2ZZcGtPzW/tWFV6D0x+b xnqu5+ysNKbl3mmZd92FD954lGWNUlLGKtODOdHmmu1zDRyIt/txS6f3T2ySFZJz nzz/t0BO70fZI5ST5FvZbmtqQvv6WXVJ/4Gfhr7rb4VoMRTWMSTlvpRyI3fhdglx ruDaZnvP26bLERgwNr6NPH80Tlv6SkXxtHljIdC2w9iBmNlJ/QI5T1kO5SFFpvOW BYg+8ZcB/JWvvS593x9IAocD/OVnarJPanWKmIoR/3Ms4NJKWiWfE0mtlOjZrCpb Q33GfkPl5NOWNXMUyY3u =FOgg -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org