Author: markt Date: Fri May 25 16:39:46 2012 New Revision: 1342717 URL: http://svn.apache.org/viewvc?rev=1342717&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=53074 Make WebSocket connections use infinite read timeouts by default.
Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java?rev=1342717&r1=1342716&r2=1342717&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java (original) +++ tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java Fri May 25 16:39:46 2012 @@ -43,7 +43,6 @@ public abstract class StreamInbound impl private int outboundCharBufferSize = WsOutbound.DEFAULT_BUFFER_SIZE; - public int getOutboundByteBufferSize() { return outboundByteBufferSize; } @@ -231,4 +230,17 @@ public abstract class StreamInbound impl * connection. */ protected abstract void onTextData(Reader r) throws IOException; + + /** + * This default implementation sets the read timeout to infinite and expects + * the WebSocket application to close the connection when it is no longer + * required. Applications wishing to set an explicit timeout may override + * this method and return a value of their choice. + * + * @return The read timeout in milliseconds or -1 for infinite + */ + @Override + public int getReadTimeout() { + return -1; + } } Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java?rev=1342717&r1=1342716&r2=1342717&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AjpAprProtocol.java Fri May 25 16:39:46 2012 @@ -127,7 +127,8 @@ public class AjpAprProtocol extends Abst recycledProcessors.offer(processor); if (addToPoller) { ((AprEndpoint)proto.endpoint).getPoller().add( - socket.getSocket().longValue(), true); + socket.getSocket().longValue(), + proto.endpoint.getKeepAliveTimeout()); } } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java?rev=1342717&r1=1342716&r2=1342717&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Fri May 25 16:39:46 2012 @@ -231,7 +231,8 @@ public class Http11AprProtocol extends A recycledProcessors.offer(processor); if (addToPoller && proto.endpoint.isRunning()) { ((AprEndpoint)proto.endpoint).getPoller().add( - socket.getSocket().longValue(), true); + socket.getSocket().longValue(), + proto.endpoint.getKeepAliveTimeout()); } } @@ -273,11 +274,13 @@ public class Http11AprProtocol extends A socket.setAsync(true); } else if (processor.isComet() && proto.endpoint.isRunning()) { ((AprEndpoint) proto.endpoint).getCometPoller().add( - socket.getSocket().longValue(), false); + socket.getSocket().longValue(), + proto.endpoint.getSoTimeout()); } else { // Upgraded ((AprEndpoint) proto.endpoint).getPoller().add( - socket.getSocket().longValue(), false); + socket.getSocket().longValue(), + (processor.getUpgradeInbound().getReadTimeout())); } } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java?rev=1342717&r1=1342716&r2=1342717&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java Fri May 25 16:39:46 2012 @@ -31,6 +31,9 @@ public class UpgradeAprProcessor extends UpgradeInbound upgradeInbound) { super(upgradeInbound); + Socket.timeoutSet(wrapper.getSocket().longValue(), + upgradeInbound.getReadTimeout()); + this.socket = wrapper.getSocket().longValue(); } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java?rev=1342717&r1=1342716&r2=1342717&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java Fri May 25 16:39:46 2012 @@ -32,6 +32,12 @@ public class UpgradeBioProcessor extends UpgradeInbound upgradeInbound) throws IOException { super(upgradeInbound); + int timeout = upgradeInbound.getReadTimeout(); + if (timeout < 0) { + timeout = 0; + } + wrapper.getSocket().setSoTimeout(timeout); + this.inputStream = wrapper.getSocket().getInputStream(); this.outputStream = wrapper.getSocket().getOutputStream(); } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java?rev=1342717&r1=1342716&r2=1342717&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java Fri May 25 16:39:46 2012 @@ -33,4 +33,12 @@ public interface UpgradeInbound { SocketState onData() throws IOException; void setUpgradeOutbound(UpgradeOutbound upgradeOutbound); + + /** + * Allow the upgraded protocol to define the read timeout to be used with + * the upgraded connection. + * + * @return The read timeout in milliseconds or -1 for infinite + */ + int getReadTimeout(); } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java?rev=1342717&r1=1342716&r2=1342717&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java Fri May 25 16:39:46 2012 @@ -36,6 +36,8 @@ public class UpgradeNioProcessor extends UpgradeInbound upgradeInbound, NioSelectorPool pool) { super(upgradeInbound); + wrapper.setTimeout(upgradeInbound.getReadTimeout()); + this.nioChannel = wrapper.getSocket(); this.pool = pool; this.maxRead = nioChannel.getBufHandler().getReadBuffer().capacity(); Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1342717&r1=1342716&r2=1342717&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Fri May 25 16:39:46 2012 @@ -1181,14 +1181,16 @@ public class AprEndpoint extends Abstrac } /** - * Add specified socket and associated pool to the poller. The socket will - * be added to a temporary array, and polled first after a maximum amount - * of time equal to pollTime (in most cases, latency will be much lower, - * however). + * Add specified socket and associated pool to the poller. The socket + * will be added to a temporary array, and polled first after a maximum + * amount of time equal to pollTime (in most cases, latency will be much + * lower, however). * - * @param socket to add to the poller + * @param socket to add to the poller + * @param timeout read timeout (in milliseconds) to use with this + * socket. Use -1 for infinite timeout */ - public void add(long socket, boolean keepAlive) { + public void add(long socket, int timeout) { synchronized (this) { // Add socket to the list. Newly added sockets will wait // at most for pollTime before being polled @@ -1202,11 +1204,7 @@ public class AprEndpoint extends Abstrac return; } addSocket[addCount] = socket; - if (keepAlive) { - addSocketTimeout[addCount] = getKeepAliveTimeout(); - } else { - addSocketTimeout[addCount] = getSoTimeout(); - } + addSocketTimeout[addCount] = timeout; addCount++; // TODO: interrupt poll ? this.notify(); @@ -1259,10 +1257,14 @@ public class AprEndpoint extends Abstrac int successCount = 0; try { for (int i = (addCount - 1); i >= 0; i--) { + int timeout = addSocketTimeout[i]; + if (timeout > 0) { + // Convert milliseconds to microseconds + timeout = timeout * 1000; + } int rv = Poll.addWithTimeout( connectionPollset, addSocket[i], - Poll.APR_POLLIN, - addSocketTimeout[i] * 1000); + Poll.APR_POLLIN, timeout); if (rv == Status.APR_SUCCESS) { successCount++; } else { @@ -1644,7 +1646,8 @@ public class AprEndpoint extends Abstrac Socket.timeoutSet(state.socket, socketProperties.getSoTimeout() * 1000); // If all done put the socket back in the poller for // processing of further requests - getPoller().add(state.socket, true); + getPoller().add(state.socket, + getKeepAliveTimeout()); } else { // Close the socket since this is // the end of not keep-alive request. @@ -1737,7 +1740,8 @@ public class AprEndpoint extends Abstrac synchronized (socket) { if (!deferAccept) { if (setSocketOptions(socket.getSocket().longValue())) { - getPoller().add(socket.getSocket().longValue(), false); + getPoller().add(socket.getSocket().longValue(), + getSoTimeout()); } else { // Close socket and pool destroySocket(socket.getSocket().longValue()); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org