Fix for bug #288514: AbstractConnector does not handle InterruptedExceptions on shutdown.

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@810 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Simone Bordet 2009-09-03 16:37:47 +00:00
parent 37d55422e6
commit c5b769634d
2 changed files with 127 additions and 122 deletions

View File

@ -5,6 +5,7 @@ jetty-7.0.0.RC6-SNAPSHOT
+ JETTY-1086 Use UncheckedPrintWriter + JETTY-1086 Use UncheckedPrintWriter
+ JETTY-1090 resolve potential infinite loop with webdav listener + JETTY-1090 resolve potential infinite loop with webdav listener
+ JETTY-1093 Request.toString throws exception when size exceeds 4k + JETTY-1093 Request.toString throws exception when size exceeds 4k
+ 288514 AbstractConnector does not handle InterruptedExceptions on shutdown
jetty-7.0.0.RC5 27 August 2009 jetty-7.0.0.RC5 27 August 2009
+ 286911 Clean out cache when recycling HTTP fields + 286911 Clean out cache when recycling HTTP fields
@ -13,7 +14,7 @@ jetty-7.0.0.RC5 27 August 2009
+ JETTY-960 Support for ldaps + JETTY-960 Support for ldaps
+ JETTY-1081 Handle null content type in GzipFilter + JETTY-1081 Handle null content type in GzipFilter
+ JETTY-1084 Disable GzipFilter for HEAD requests + JETTY-1084 Disable GzipFilter for HEAD requests
+ JETTY-1085 Allow url sessionID if cookie invalid + JETTY-1085 Allow url sessionID if cookie invalid
+ JETTY-1086 Added UncheckedPrintWriter to avoid ignored EOFs + JETTY-1086 Added UncheckedPrintWriter to avoid ignored EOFs
+ JETTY-1087 Chunked SSL non blocking input + JETTY-1087 Chunked SSL non blocking input
+ 287496 Use start.ini always and added --exec + 287496 Use start.ini always and added --exec
@ -28,7 +29,7 @@ jetty-7.0.0.RC4 18 August 2009
+ 279820 Fixed HotSwapHandler + 279820 Fixed HotSwapHandler
+ JETTY-1080 Ignore files that would be extracted outside the destination directory when unpacking WARs + JETTY-1080 Ignore files that would be extracted outside the destination directory when unpacking WARs
+ JETTY-1057 XSS error page + JETTY-1057 XSS error page
jetty-7.0.0.RC3 7 August 2009 jetty-7.0.0.RC3 7 August 2009
+ 277403 remove system properties + 277403 remove system properties
+ JETTY-1074 JMX thread manipulation + JETTY-1074 JMX thread manipulation
@ -52,7 +53,7 @@ jetty-7.0.0.RC2 29 June 2009
+ 284981 Implement a cross-origin filter + 284981 Implement a cross-origin filter
+ Improved handling of overlays and resourceCollections + Improved handling of overlays and resourceCollections
+ 285006 fix AbstractConnector NPE during shutdown. + 285006 fix AbstractConnector NPE during shutdown.
jetty-7.0.0.RC1 15 June 2009 jetty-7.0.0.RC1 15 June 2009
+ JETTY-1066 283357 400 response for bad URIs + JETTY-1066 283357 400 response for bad URIs
+ JETTY-1068 Avoid busy flush of async SSL + JETTY-1068 Avoid busy flush of async SSL

View File

@ -4,11 +4,11 @@
// All rights reserved. This program and the accompanying materials // All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0 // are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution. // and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at // The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html // http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at // The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php // http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.server; package org.eclipse.jetty.server;
@ -17,7 +17,6 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import org.eclipse.jetty.http.HttpBuffers; import org.eclipse.jetty.http.HttpBuffers;
@ -42,13 +41,13 @@ import org.eclipse.jetty.util.thread.ThreadPool;
* <li>Base acceptor thread</li> * <li>Base acceptor thread</li>
* <li>Optional reverse proxy headers checking</li> * <li>Optional reverse proxy headers checking</li>
* </ul> * </ul>
* *
* *
*/ */
public abstract class AbstractConnector extends HttpBuffers implements Connector public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
private String _name; private String _name;
private Server _server; private Server _server;
private ThreadPool _threadPool; private ThreadPool _threadPool;
private String _host; private String _host;
@ -67,34 +66,34 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
private String _forwardedServerHeader = "X-Forwarded-Server"; // default to mod_proxy_http header private String _forwardedServerHeader = "X-Forwarded-Server"; // default to mod_proxy_http header
private String _forwardedForHeader = "X-Forwarded-For"; // default to mod_proxy_http header private String _forwardedForHeader = "X-Forwarded-For"; // default to mod_proxy_http header
private boolean _reuseAddress=true; private boolean _reuseAddress=true;
protected int _maxIdleTime=200000; protected int _maxIdleTime=200000;
protected int _lowResourceMaxIdleTime=-1; protected int _lowResourceMaxIdleTime=-1;
protected int _soLingerTime=-1; protected int _soLingerTime=-1;
private transient Thread[] _acceptorThread; private transient Thread[] _acceptorThread;
final Object _statsLock = new Object(); final Object _statsLock = new Object();
transient long _statsStartedAt=-1; transient long _statsStartedAt=-1;
// TODO use concurrents for these! // TODO use concurrents for these!
transient int _requests; transient int _requests;
transient int _connections; // total number of connections made to server transient int _connections; // total number of connections made to server
transient int _connectionsOpen; // number of connections currently open transient int _connectionsOpen; // number of connections currently open
transient int _connectionsOpenMin; // min number of connections open simultaneously transient int _connectionsOpenMin; // min number of connections open simultaneously
transient int _connectionsOpenMax; // max number of connections open simultaneously transient int _connectionsOpenMax; // max number of connections open simultaneously
transient long _connectionsDurationMin; // min duration of a connection transient long _connectionsDurationMin; // min duration of a connection
transient long _connectionsDurationMax; // max duration of a connection transient long _connectionsDurationMax; // max duration of a connection
transient long _connectionsDurationTotal; // total duration of all coneection transient long _connectionsDurationTotal; // total duration of all coneection
transient int _connectionsRequestsMin; // min requests per connection transient int _connectionsRequestsMin; // min requests per connection
transient int _connectionsRequestsMax; // max requests per connection transient int _connectionsRequestsMax; // max requests per connection
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/** /**
*/ */
public AbstractConnector() public AbstractConnector()
{ {
@ -106,13 +105,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
// TODO remove once no overrides established // TODO remove once no overrides established
return null; return null;
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
public Buffer newRequestBuffer(int size) public Buffer newRequestBuffer(int size)
{ {
return new ByteArrayBuffer(size); return new ByteArrayBuffer(size);
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
public Buffer newRequestHeader(int size) public Buffer newRequestHeader(int size)
{ {
@ -124,7 +123,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
return new ByteArrayBuffer(size); return new ByteArrayBuffer(size);
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
public Buffer newResponseHeader(int size) public Buffer newResponseHeader(int size)
{ {
@ -142,7 +141,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
return true; return true;
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/* /*
*/ */
@ -156,7 +155,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_server=server; _server=server;
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/* /*
* @see org.eclipse.jetty.http.HttpListener#getHttpServer() * @see org.eclipse.jetty.http.HttpListener#getHttpServer()
@ -171,11 +170,11 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_threadPool=pool; _threadPool=pool;
} }
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
/** /**
*/ */
public void setHost(String host) public void setHost(String host)
{ {
_host=host; _host=host;
} }
@ -206,7 +205,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
return _port; return _port;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Returns the maxIdleTime. * @return Returns the maxIdleTime.
@ -215,38 +214,38 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
return _maxIdleTime; return _maxIdleTime;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Set the maximum Idle time for a connection, which roughly translates * Set the maximum Idle time for a connection, which roughly translates
* to the {@link Socket#setSoTimeout(int)} call, although with NIO * to the {@link Socket#setSoTimeout(int)} call, although with NIO
* implementations other mechanisms may be used to implement the timeout. * implementations other mechanisms may be used to implement the timeout.
* The max idle time is applied:<ul> * The max idle time is applied:<ul>
* <li>When waiting for a new request to be received on a connection</li> * <li>When waiting for a new request to be received on a connection</li>
* <li>When reading the headers and content of a request</li> * <li>When reading the headers and content of a request</li>
* <li>When writing the headers and content of a response</li> * <li>When writing the headers and content of a response</li>
* </ul> * </ul>
* Jetty interprets this value as the maximum time between some progress being * Jetty interprets this value as the maximum time between some progress being
* made on the connection. So if a single byte is read or written, then the * made on the connection. So if a single byte is read or written, then the
* timeout (if implemented by jetty) is reset. However, in many instances, * timeout (if implemented by jetty) is reset. However, in many instances,
* the reading/writing is delegated to the JVM, and the semantic is more * the reading/writing is delegated to the JVM, and the semantic is more
* strictly enforced as the maximum time a single read/write operation can * strictly enforced as the maximum time a single read/write operation can
* take. Note, that as Jetty supports writes of memory mapped file buffers, * take. Note, that as Jetty supports writes of memory mapped file buffers,
* then a write may take many 10s of seconds for large content written to a * then a write may take many 10s of seconds for large content written to a
* slow device. * slow device.
* <p> * <p>
* Previously, Jetty supported separate idle timeouts and IO operation timeouts, * Previously, Jetty supported separate idle timeouts and IO operation timeouts,
* however the expense of changing the value of soTimeout was significant, so * however the expense of changing the value of soTimeout was significant, so
* these timeouts were merged. With the advent of NIO, it may be possible to * these timeouts were merged. With the advent of NIO, it may be possible to
* again differentiate these values (if there is demand). * again differentiate these values (if there is demand).
* *
* @param maxIdleTime The maxIdleTime to set. * @param maxIdleTime The maxIdleTime to set.
*/ */
public void setMaxIdleTime(int maxIdleTime) public void setMaxIdleTime(int maxIdleTime)
{ {
_maxIdleTime = maxIdleTime; _maxIdleTime = maxIdleTime;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Returns the maxIdleTime. * @return Returns the maxIdleTime.
@ -255,7 +254,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
return _lowResourceMaxIdleTime; return _lowResourceMaxIdleTime;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param maxIdleTime The maxIdleTime to set. * @param maxIdleTime The maxIdleTime to set.
@ -264,7 +263,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_lowResourceMaxIdleTime = maxIdleTime; _lowResourceMaxIdleTime = maxIdleTime;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Returns the soLingerTime. * @return Returns the soLingerTime.
@ -291,7 +290,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_acceptQueueSize = acceptQueueSize; _acceptQueueSize = acceptQueueSize;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Returns the number of acceptor threads. * @return Returns the number of acceptor threads.
@ -309,7 +308,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_acceptors = acceptors; _acceptors = acceptors;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param soLingerTime The soLingerTime to set or -1 to disable. * @param soLingerTime The soLingerTime to set or -1 to disable.
@ -318,23 +317,23 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_soLingerTime = soLingerTime; _soLingerTime = soLingerTime;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected void doStart() throws Exception protected void doStart() throws Exception
{ {
if (_server==null) if (_server==null)
throw new IllegalStateException("No server"); throw new IllegalStateException("No server");
// open listener port // open listener port
open(); open();
super.doStart(); super.doStart();
if (_threadPool==null) if (_threadPool==null)
_threadPool=_server.getThreadPool(); _threadPool=_server.getThreadPool();
if (_threadPool!=_server.getThreadPool() && (_threadPool instanceof LifeCycle)) if (_threadPool!=_server.getThreadPool() && (_threadPool instanceof LifeCycle))
((LifeCycle)_threadPool).start(); ((LifeCycle)_threadPool).start();
// Start selector thread // Start selector thread
synchronized(this) synchronized(this)
{ {
@ -349,22 +348,22 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
} }
} }
} }
Log.info("Started {}",this); Log.info("Started {}",this);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected void doStop() throws Exception protected void doStop() throws Exception
{ {
try{close();} catch(IOException e) {Log.warn(e);} try{close();} catch(IOException e) {Log.warn(e);}
if (_threadPool==_server.getThreadPool()) if (_threadPool==_server.getThreadPool())
_threadPool=null; _threadPool=null;
else if (_threadPool instanceof LifeCycle) else if (_threadPool instanceof LifeCycle)
((LifeCycle)_threadPool).stop(); ((LifeCycle)_threadPool).stop();
super.doStop(); super.doStop();
Thread[] acceptors=null; Thread[] acceptors=null;
synchronized(this) synchronized(this)
{ {
@ -381,7 +380,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
} }
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void join() throws InterruptedException public void join() throws InterruptedException
{ {
@ -395,7 +394,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected void configure(Socket socket) protected void configure(Socket socket)
throws IOException throws IOException
{ {
try try
{ {
socket.setTcpNoDelay(true); socket.setTcpNoDelay(true);
@ -426,15 +425,15 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
throws IOException throws IOException
{ {
HttpFields httpFields = request.getConnection().getRequestFields(); HttpFields httpFields = request.getConnection().getRequestFields();
// Retrieving headers from the request // Retrieving headers from the request
String forwardedHost = getLeftMostValue(httpFields.getStringField(getForwardedHostHeader())); String forwardedHost = getLeftMostValue(httpFields.getStringField(getForwardedHostHeader()));
String forwardedServer = getLeftMostValue(httpFields.getStringField(getForwardedServerHeader())); String forwardedServer = getLeftMostValue(httpFields.getStringField(getForwardedServerHeader()));
String forwardedFor = getLeftMostValue(httpFields.getStringField(getForwardedForHeader())); String forwardedFor = getLeftMostValue(httpFields.getStringField(getForwardedForHeader()));
if (_hostHeader!=null) if (_hostHeader!=null)
{ {
// Update host header // Update host header
httpFields.put(HttpHeaders.HOST_BUFFER, _hostHeader); httpFields.put(HttpHeaders.HOST_BUFFER, _hostHeader);
request.setServerName(null); request.setServerName(null);
request.setServerPort(-1); request.setServerPort(-1);
@ -442,7 +441,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
} }
else if (forwardedHost != null) else if (forwardedHost != null)
{ {
// Update host header // Update host header
httpFields.put(HttpHeaders.HOST_BUFFER, forwardedHost); httpFields.put(HttpHeaders.HOST_BUFFER, forwardedHost);
request.setServerName(null); request.setServerName(null);
request.setServerPort(-1); request.setServerPort(-1);
@ -453,12 +452,12 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
// Use provided server name // Use provided server name
request.setServerName(forwardedServer); request.setServerName(forwardedServer);
} }
if (forwardedFor != null) if (forwardedFor != null)
{ {
request.setRemoteAddr(forwardedFor); request.setRemoteAddr(forwardedFor);
InetAddress inetAddress = null; InetAddress inetAddress = null;
if (_useDNS) if (_useDNS)
{ {
try try
@ -470,7 +469,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
Log.ignore(e); Log.ignore(e);
} }
} }
request.setRemoteHost(inetAddress==null?forwardedFor:inetAddress.getHostName()); request.setRemoteHost(inetAddress==null?forwardedFor:inetAddress.getHostName());
} }
} }
@ -479,9 +478,9 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
protected String getLeftMostValue(String headerValue) { protected String getLeftMostValue(String headerValue) {
if (headerValue == null) if (headerValue == null)
return null; return null;
int commaIndex = headerValue.indexOf(','); int commaIndex = headerValue.indexOf(',');
if (commaIndex == -1) if (commaIndex == -1)
{ {
// Single value // Single value
@ -495,13 +494,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void persist(EndPoint endpoint) public void persist(EndPoint endpoint)
throws IOException throws IOException
{ {
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see org.eclipse.jetty.server.Connector#getConfidentialPort() * @see org.eclipse.jetty.server.Connector#getConfidentialPort()
*/ */
public int getConfidentialPort() public int getConfidentialPort()
@ -511,16 +510,16 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see org.eclipse.jetty.server.Connector#getConfidentialScheme() * @see org.eclipse.jetty.server.Connector#getConfidentialScheme()
*/ */
public String getConfidentialScheme() public String getConfidentialScheme()
{ {
return _confidentialScheme; return _confidentialScheme;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request) * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request)
*/ */
public boolean isIntegral(Request request) public boolean isIntegral(Request request)
@ -529,25 +528,25 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see org.eclipse.jetty.server.Connector#getConfidentialPort() * @see org.eclipse.jetty.server.Connector#getConfidentialPort()
*/ */
public int getIntegralPort() public int getIntegralPort()
{ {
return _integralPort; return _integralPort;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see org.eclipse.jetty.server.Connector#getIntegralScheme() * @see org.eclipse.jetty.server.Connector#getIntegralScheme()
*/ */
public String getIntegralScheme() public String getIntegralScheme()
{ {
return _integralScheme; return _integralScheme;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request) * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request)
*/ */
public boolean isConfidential(Request request) public boolean isConfidential(Request request)
@ -590,7 +589,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_integralScheme = integralScheme; _integralScheme = integralScheme;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected abstract void accept(int acceptorID) throws IOException, InterruptedException; protected abstract void accept(int acceptorID) throws IOException, InterruptedException;
@ -598,21 +597,21 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
public void stopAccept(int acceptorID) throws Exception public void stopAccept(int acceptorID) throws Exception
{ {
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public boolean getResolveNames() public boolean getResolveNames()
{ {
return _useDNS; return _useDNS;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void setResolveNames(boolean resolve) public void setResolveNames(boolean resolve)
{ {
_useDNS=resolve; _useDNS=resolve;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Is reverse proxy handling on? * Is reverse proxy handling on?
* @return true if this connector is checking the x-forwarded-for/host/server headers * @return true if this connector is checking the x-forwarded-for/host/server headers
*/ */
@ -620,7 +619,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
return _forwarded; return _forwarded;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Set reverse proxy handling * Set reverse proxy handling
@ -632,15 +631,15 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
Log.debug(this+" is forwarded"); Log.debug(this+" is forwarded");
_forwarded=check; _forwarded=check;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String getHostHeader() public String getHostHeader()
{ {
return _hostHeader; return _hostHeader;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Set a forced valued for the host header to control what is returned * Set a forced valued for the host header to control what is returned
* by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}. * by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
* This value is only used if {@link #isForwarded()} is true. * This value is only used if {@link #isForwarded()} is true.
@ -650,13 +649,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_hostHeader=hostHeader; _hostHeader=hostHeader;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String getForwardedHostHeader() public String getForwardedHostHeader()
{ {
return _forwardedHostHeader; return _forwardedHostHeader;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param forwardedHostHeader The header name for forwarded hosts (default x-forwarded-host) * @param forwardedHostHeader The header name for forwarded hosts (default x-forwarded-host)
@ -665,13 +664,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_forwardedHostHeader=forwardedHostHeader; _forwardedHostHeader=forwardedHostHeader;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String getForwardedServerHeader() public String getForwardedServerHeader()
{ {
return _forwardedServerHeader; return _forwardedServerHeader;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param forwardedHostHeader The header name for forwarded server (default x-forwarded-server) * @param forwardedHostHeader The header name for forwarded server (default x-forwarded-server)
@ -680,13 +679,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_forwardedServerHeader=forwardedServerHeader; _forwardedServerHeader=forwardedServerHeader;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String getForwardedForHeader() public String getForwardedForHeader()
{ {
return _forwardedForHeader; return _forwardedForHeader;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @param forwardedHostHeader The header name for forwarded for (default x-forwarded-for) * @param forwardedHostHeader The header name for forwarded for (default x-forwarded-for)
@ -695,7 +694,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_forwardedForHeader=forwardedRemoteAddressHeade; _forwardedForHeader=forwardedRemoteAddressHeade;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public String toString() public String toString()
{ {
@ -703,39 +702,39 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
int dot = name.lastIndexOf('.'); int dot = name.lastIndexOf('.');
if (dot>0) if (dot>0)
name=name.substring(dot+1); name=name.substring(dot+1);
return name+"@"+(getHost()==null?"0.0.0.0":getHost())+":"+(getLocalPort()<=0?getPort():getLocalPort()); return name+"@"+(getHost()==null?"0.0.0.0":getHost())+":"+(getLocalPort()<=0?getPort():getLocalPort());
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private class Acceptor implements Runnable private class Acceptor implements Runnable
{ {
int _acceptor=0; int _acceptor=0;
Acceptor(int id) Acceptor(int id)
{ {
_acceptor=id; _acceptor=id;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void run() public void run()
{ {
Thread current = Thread.currentThread(); Thread current = Thread.currentThread();
String name; String name;
synchronized(AbstractConnector.this) synchronized(AbstractConnector.this)
{ {
if (_acceptorThread==null) if (_acceptorThread==null)
return; return;
_acceptorThread[_acceptor]=current; _acceptorThread[_acceptor]=current;
name =_acceptorThread[_acceptor].getName(); name =_acceptorThread[_acceptor].getName();
current.setName(name+" - Acceptor"+_acceptor+" "+AbstractConnector.this); current.setName(name+" - Acceptor"+_acceptor+" "+AbstractConnector.this);
} }
int old_priority=current.getPriority(); int old_priority=current.getPriority();
try try
{ {
current.setPriority(old_priority-_acceptorPriorityOffset); current.setPriority(old_priority-_acceptorPriorityOffset);
@ -743,7 +742,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
try try
{ {
accept(_acceptor); accept(_acceptor);
} }
catch(EofException e) catch(EofException e)
{ {
@ -753,6 +752,11 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
Log.ignore(e); Log.ignore(e);
} }
catch (InterruptedException x)
{
// Connector has been stopped
Log.ignore(x);
}
catch(ThreadDeath e) catch(ThreadDeath e)
{ {
throw e; throw e;
@ -764,7 +768,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
} }
} }
finally finally
{ {
current.setPriority(old_priority); current.setPriority(old_priority);
current.setName(name); current.setName(name);
try try
@ -776,7 +780,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
Log.warn(e); Log.warn(e);
} }
synchronized(AbstractConnector.this) synchronized(AbstractConnector.this)
{ {
if (_acceptorThread!=null) if (_acceptorThread!=null)
@ -799,8 +803,8 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
{ {
_name = name; _name = name;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -848,56 +852,56 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Number of connections accepted by the server since * @return Number of connections accepted by the server since
* statsReset() called. Undefined if setStatsOn(false). * statsReset() called. Undefined if setStatsOn(false).
*/ */
public int getConnections() {return _connections;} public int getConnections() {return _connections;}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Number of connections currently open that were opened * @return Number of connections currently open that were opened
* since statsReset() called. Undefined if setStatsOn(false). * since statsReset() called. Undefined if setStatsOn(false).
*/ */
public int getConnectionsOpen() {return _connectionsOpen;} public int getConnectionsOpen() {return _connectionsOpen;}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Maximum number of connections opened simultaneously * @return Maximum number of connections opened simultaneously
* since statsReset() called. Undefined if setStatsOn(false). * since statsReset() called. Undefined if setStatsOn(false).
*/ */
public int getConnectionsOpenMax() {return _connectionsOpenMax;} public int getConnectionsOpenMax() {return _connectionsOpenMax;}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Average duration in milliseconds of open connections * @return Average duration in milliseconds of open connections
* since statsReset() called. Undefined if setStatsOn(false). * since statsReset() called. Undefined if setStatsOn(false).
*/ */
public long getConnectionsDurationAve() {return _connections==0?0:(_connectionsDurationTotal/_connections);} public long getConnectionsDurationAve() {return _connections==0?0:(_connectionsDurationTotal/_connections);}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Maximum duration in milliseconds of an open connection * @return Maximum duration in milliseconds of an open connection
* since statsReset() called. Undefined if setStatsOn(false). * since statsReset() called. Undefined if setStatsOn(false).
*/ */
public long getConnectionsDurationMax() {return _connectionsDurationMax;} public long getConnectionsDurationMax() {return _connectionsDurationMax;}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Average number of requests per connection * @return Average number of requests per connection
* since statsReset() called. Undefined if setStatsOn(false). * since statsReset() called. Undefined if setStatsOn(false).
*/ */
public int getConnectionsRequestsAve() {return _connections==0?0:(_requests/_connections);} public int getConnectionsRequestsAve() {return _connections==0?0:(_requests/_connections);}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Maximum number of requests per connection * @return Maximum number of requests per connection
* since statsReset() called. Undefined if setStatsOn(false). * since statsReset() called. Undefined if setStatsOn(false).
*/ */
public int getConnectionsRequestsMax() {return _connectionsRequestsMax;} public int getConnectionsRequestsMax() {return _connectionsRequestsMax;}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Reset statistics. /** Reset statistics.
*/ */
@ -906,11 +910,11 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
_statsStartedAt=_statsStartedAt==-1?-1:System.currentTimeMillis(); _statsStartedAt=_statsStartedAt==-1?-1:System.currentTimeMillis();
_connections=0; _connections=0;
_connectionsOpenMin=_connectionsOpen; _connectionsOpenMin=_connectionsOpen;
_connectionsOpenMax=_connectionsOpen; _connectionsOpenMax=_connectionsOpen;
_connectionsOpen=0; _connectionsOpen=0;
_connectionsDurationMin=0; _connectionsDurationMin=0;
_connectionsDurationMax=0; _connectionsDurationMax=0;
_connectionsDurationTotal=0; _connectionsDurationTotal=0;
@ -920,7 +924,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
_connectionsRequestsMin=0; _connectionsRequestsMin=0;
_connectionsRequestsMax=0; _connectionsRequestsMax=0;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void setStatsOn(boolean on) public void setStatsOn(boolean on)
{ {
@ -930,25 +934,25 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
statsReset(); statsReset();
_statsStartedAt=on?System.currentTimeMillis():-1; _statsStartedAt=on?System.currentTimeMillis():-1;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return True if statistics collection is turned on. * @return True if statistics collection is turned on.
*/ */
public boolean getStatsOn() public boolean getStatsOn()
{ {
return _statsStartedAt!=-1; return _statsStartedAt!=-1;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return Timestamp stats were started at. * @return Timestamp stats were started at.
*/ */
public long getStatsOnMs() public long getStatsOnMs()
{ {
return (_statsStartedAt!=-1)?(System.currentTimeMillis()-_statsStartedAt):0; return (_statsStartedAt!=-1)?(System.currentTimeMillis()-_statsStartedAt):0;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected void connectionOpened(HttpConnection connection) protected void connectionOpened(HttpConnection connection)
{ {
@ -961,16 +965,16 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
_connectionsOpenMax=_connectionsOpen; _connectionsOpenMax=_connectionsOpen;
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected void connectionClosed(HttpConnection connection) protected void connectionClosed(HttpConnection connection)
{ {
if (_statsStartedAt>=0) if (_statsStartedAt>=0)
{ {
long duration=System.currentTimeMillis()-connection.getTimeStamp(); long duration=System.currentTimeMillis()-connection.getTimeStamp();
int requests=connection.getRequests(); int requests=connection.getRequests();
synchronized(_statsLock) synchronized(_statsLock)
{ {
_requests+=requests; _requests+=requests;
@ -991,7 +995,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
_connectionsRequestsMax=requests; _connectionsRequestsMax=requests;
} }
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */