Peter Rifel wrote:
-----Original Message-----
From: Konstantin Preißer [kpreis...@apache.org]
Sent: Thursday, December 26, 2013 1:28 PM
To: 'Tomcat Users List'
Subject: RE: Request Timeout and empty post data issue

Hi,

-----Original Message-----
From: Peter Rifel [mailto:pri...@mixpo.com]
Sent: Thursday, December 26, 2013 9:45 PM
To: users@tomcat.apache.org
Subject: Request Timeout and empty post data issue

Hello,

I'm currently running Tomcat 7.0.42 on Ubuntu 12.04 with OpenJDK 1.7.0_25.
I'm using Apache Tomcat Native library 1.1.27 with APR version 1.4.6.

I'm noticing in my access logs that some of our POST requests don't have any
POST data and all have response times of a few ms over 20000ms.  I'm trying
to figure out whether this issue is client side or server side.  The response
code and response size for these requests are normal.  Can anyone tell me
under what circumstances this would happen?  I noticed that our connector's
connectionTimeout is set to 20000ms, but it wouldn't make sense for that
value to be a part of this issue because a connection timeout only occurs
when the URI hasn't been received by tomcat in that amount of time, which
is clearly not happening here (I was able to confirm this with telnet; a
connection timeout will not write anything to the access logs).

The "request" is making it to my servlet (logging confirms this) but for some
reason tomcat doesn't see any request parameters and all of the response
times in our access logs are just above 20 seconds.  Does this mean that my
servlet is taking 20 seconds to process the request?  Is there some other
timeout value somewhere that defaults to 20 seconds?  Is there a way for
me to see exactly what is taking so long?  Its incredibly hard to debug this
because we cant reproduce this bug on our own without any post data and
<1% of our production traffic is having this issue.  To try and gather more info
on this, I added a servlet filter that logs all of our POST request parameters 
to
the access log and I can confirm that there are no parameters on these
specific requests.

The lack of post data makes me think its a client issue, but that doesn't
explain why all of these requests take ~20 seconds to be processed.

I'd appreciate any ideas on what could cause this.
Did you try to set the "connectionTimeout" to some other value to see if the 
requests still take ~ 20s?

I just tested with Tomcat 7.0.47 and HTTP APR connector, and for me the 
"connectionTimeout" value is also applied when reading the POST data: When the 
client does not send a byte in this interval (20s), then this will trigger some timeout 
error.

E.g., if you send the following POST request without a body (2x CR LF after the 
last header):

POST /MyWebapp/PostServlet HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 999
Content-Type: application/x-www-form-urlencoded


Then after the connectionTimeout interval, an java.net.SocketTimeoutException occurs at 
org.apache.catalina.connector.CoyoteInputStream.read (e.g. when you directly read the 
Request input stream), so that Tomcat doesn't wait forever for further data when the 
client is already gone. Note that the exception did not occur when I called  
request.getParameter("xxx") - it just returned null.

It could be possible that a client sends a request with complete headers, but 
when sending the POST body the client waits too long so that Tomcat applies the 
connectionTimeout before the full request body is received. The request will 
then be logged as the request headers where completely received.


Regards,
Konstantin Preißer


Konstantin,

I changed the connectionTimeout and that value is being reflected in our access logs. So this means that tomcat is not receiving a body with the POST request, indicating a client-side or network problem?

It could also of course be a malicious client, doing this just to bother you.
(a form of DoS attack).

We never read the input stream directly, we only use getParameter so that would explain why our servlet isn't throwing a SocketTimeoutException.

Calling getParameters(), as far as I know, forces Tomcat to read the /whole/ request body, to parse the parameters before returning from getParameters().

That is why I was a bit curious about how you managed to determine, in the servlet filter, that there were no parameters.
Somehow it seems to me that there is still an unexplained phenomenon there, as 
follows :

Suppose that there is supposed to be a body with parameters, the total length of that body being given by the Content-length header. Your code calls getParameters() for the first time. The underlying Tomcat code reads the body. Either this body can be read completely (up to Content-length) and parsed into parameters, and the getParameter() call returns. Or else, the read of the POST body blocks for lack of data, before Content-length has been reached. In that case, the call to getParameter() should not return. And if that situation lasts long enough, a time-out should occur and some exception should be thrown.

So, unless I am missing something (which is very possible, as I did not consult the underlying code), the only way that the servlet filter could determine that there are no parameters, would be if there was no body (Content-length = 0). Otherwise, it would be faced with the timeout before the return from getParameters(), no ?

It would be nice if the connectionTimeout documentation could mention this scenario as well.

Thank you for your quick response!

Peter
Peter
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to