views:

631

answers:

2

I am trying to put some logging to capture the raw http request coming to my application. My Java code is inside a SpringMVC controller. I have access to the "HttpServletRequest" object. But I could not find a way to get the raw http request stream out of it. There is a reader but only reads the post content. What I want is the whole shebang, the url, the headers, the body. Is there an easy way to do this?

Thanks in advance.

+2  A: 

No, servlets provide no api to get at the raw request - you might need a sniffer like wireshark for that.

You can get at the parsed request headers and uri though:

etc.

nos
+2  A: 

No.

The servlet provides no such API, and it would be hard to implement because (basically) you cannot read the same data twice from a Socket. It is not difficult to get header information, but raw headers are impossible to capture within a servlet container. To get the bodies you need to capture them yourself as your application reads/writes the relevant streams.

Your alternatives are:

  1. Write your own server-side implementation of the HTTP protocol. (Probably not right for your application.)

  2. You may be able to get the header information you need with filters, though they don't show the raw requests.

  3. Some servlet containers have request header logging; e.g. with Tomcat there's a beast called the RequestDumperValve that you can configure in your "server.xml" file.

  4. Implement a proxy server that sits between the client and your "real" server.

  5. Packet sniffing.

Which is best depends on what you are really trying to achieve.

FOLLOWUP:

If the "badness" is in the headers, the RequestDumperValve approach is probably the best for debugging. Go to the "$CATALINA_HOME/conf/server.xml" file, search for "RequestDumperValve" and uncomment the element. Then restart Tomcat. You can also do the equivalent in your webapp's "context.xml" file. The dumped requests and responses end up in "logs/catalina.out" by default. Note that this will give a LOT of output, so you don't want to do this in production ... except as a last resort.

If the badness is in the content of a POST or PUT request, you'll need to modify your application to save a copy the content as it reads it from the input stream. I'm not aware of any shortcuts for this.

Also, if you want to leave logging on for long periods, you'll probably need to solve the problem yourself by calling the HttpServletRequest API and logging headers, etc. The RequestDumperValve generates too much output, and dumps ALL requests not just the bad ones.

Stephen C
Thanks for the information. What I want to achieve is simply log the complete request when some error/bad request comes in. I will do what nos suggested.
savanna
If the "badness" is in the headers, the RequestDumperValve approach is probably the best. If the badness is in the content of a POST or PUT request, you'll need to modify your application to save a copy the content as it reads it from the input stream. I'm not aware of any shortcuts for that case.
Stephen C