From cc75967308f14069169bd91d60439d42c6a57be3 Mon Sep 17 00:00:00 2001 From: markt Date: Thu, 21 Apr 2011 19:02:46 +0000 Subject: [PATCH] Fix TODO - take account of time waiting for a thread when calculating timeouts. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1095794 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/coyote/http11/Http11Processor.java | 42 +++++++++++++++++++--- webapps/docs/changelog.xml | 5 +++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java index 5fd2b0164..80c3910e5 100644 --- a/java/org/apache/coyote/http11/Http11Processor.java +++ b/java/org/apache/coyote/http11/Http11Processor.java @@ -17,6 +17,7 @@ package org.apache.coyote.http11; +import java.io.EOFException; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; @@ -184,15 +185,48 @@ public class Http11Processor extends AbstractHttp11Processor { // Parsing the request header try { - //TODO - calculate timeout based on length in queue (System.currentTimeMills() - wrapper.getLastAccess() is the time in queue) + int standardTimeout = 0; if (keptAlive) { if (keepAliveTimeout > 0) { - socket.getSocket().setSoTimeout(keepAliveTimeout); + standardTimeout = keepAliveTimeout; + } else if (soTimeout > 0) { + standardTimeout = soTimeout; } - else if (soTimeout > 0) { - socket.getSocket().setSoTimeout(soTimeout); + } + /* + * When there is no data in the buffer and this is not the first + * request on this connection and timeouts are being used the + * first read for this request may need a different timeout to + * take account of time spent waiting for a processing thread. + * + * This is a little hacky but better than exposing the socket + * and the timeout info to the InputBuffer + */ + if (inputBuffer.lastValid == 0 && + socketWrapper.getLastAccess() > -1 && + standardTimeout > 0) { + + long queueTime = System.currentTimeMillis() - + socketWrapper.getLastAccess(); + int firstReadTimeout; + if (queueTime >= standardTimeout) { + // Queued for longer than timeout but there might be + // data so use shortest possible timeout + firstReadTimeout = 1; + } else { + // Cast is safe since queueTime must be less than + // standardTimeout which is an int + firstReadTimeout = standardTimeout - (int) queueTime; + } + socket.getSocket().setSoTimeout(firstReadTimeout); + if (!inputBuffer.fill()) { + throw new EOFException(sm.getString("iib.eof.error")); } } + if (standardTimeout > 0) { + socket.getSocket().setSoTimeout(standardTimeout); + } + inputBuffer.parseRequestLine(false); if (endpoint.isPaused()) { // 503 - Service unavailable diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 95f499651..62dc2b60a 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -111,6 +111,11 @@ information was also added to the documentation on how to select an appropriate value. + + Take account of time spent waiting for a processing thread when + calculating connection and keep-alive timeouts for the HTTP BIO + connector. (markt) + -- 2.11.0