From: markt Date: Tue, 25 May 2010 13:53:14 +0000 (+0000) Subject: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49095 X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=d375722372befef7f6fb41397c691abd19e23e29;p=tomcat7.0 Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49095 AprEndpoint does not wakeup accepts with deferred accept or BSD filters Based on a patch provided by Ruediger Pluem git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@948043 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/tomcat/util/net/AprEndpoint.java b/java/org/apache/tomcat/util/net/AprEndpoint.java index 0e2a92c21..511b46adf 100644 --- a/java/org/apache/tomcat/util/net/AprEndpoint.java +++ b/java/org/apache/tomcat/util/net/AprEndpoint.java @@ -17,6 +17,8 @@ package org.apache.tomcat.util.net; +import java.io.PrintWriter; +import java.net.InetSocketAddress; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -578,6 +580,59 @@ public class AprEndpoint extends AbstractEndpoint { /** + * Unlock the server socket accept using a bogus connection. + */ + @Override + protected void unlockAccept() { + java.net.Socket s = null; + InetSocketAddress saddr = null; + try { + // Need to create a connection to unlock the accept(); + if (getAddress() == null) { + saddr = new InetSocketAddress("localhost", getPort()); + } else { + saddr = new InetSocketAddress(getAddress(),getPort()); + } + s = new java.net.Socket(); + s.setSoTimeout(getSocketProperties().getSoTimeout()); + // TODO Consider hard-coding to s.setSoLinger(true,0) + s.setSoLinger(getSocketProperties().getSoLingerOn(),getSocketProperties().getSoLingerTime()); + if (log.isDebugEnabled()) { + log.debug("About to unlock socket for:"+saddr); + } + s.connect(saddr,getSocketProperties().getUnlockTimeout()); + /* + * In the case of a deferred accept / accept filters we need to + * send data to wake up the accept. Send OPTIONS * to bypass even + * BSD accept filters. The Acceptor will discard it. + */ + if (deferAccept) { + PrintWriter pw; + + pw = new PrintWriter(s.getOutputStream()); + pw.print("OPTIONS * HTTP/1.0\r\n" + + "User-Agent: Tomcat wakeup connection\r\n\r\n"); + pw.flush(); + } + if (log.isDebugEnabled()) { + log.debug("Socket unlock completed for:"+saddr); + } + } catch(Exception e) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("endpoint.debug.unlock", "" + getPort()), e); + } + } finally { + if (s != null) { + try { + s.close(); + } catch (Exception e) { + // Ignore + } + } + } + } + + /** * Pause the endpoint, which will make it stop accepting new sockets. */ @Override @@ -823,6 +878,15 @@ public class AprEndpoint extends AbstractEndpoint { try { // Accept the next incoming connection from the server socket long socket = Socket.accept(serverSock); + /* + * In the case of a deferred accept unlockAccept needs to + * send data. This data will be rubbish, so destroy the + * socket and don't process it. + */ + if (deferAccept && (paused || !running)) { + Socket.destroy(socket); + continue; + } // Hand this socket off to an appropriate processor if (!processSocketWithOptions(socket)) { // Close socket and pool right away