diff --git a/VERSION.txt b/VERSION.txt index d650e20b248..3af797c424f 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -5,6 +5,7 @@ jetty-7.0.0.RC6-SNAPSHOT + JETTY-1086 Use UncheckedPrintWriter + JETTY-1090 resolve potential infinite loop with webdav listener + 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 + 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-1081 Handle null content type in GzipFilter + 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-1087 Chunked SSL non blocking input + 287496 Use start.ini always and added --exec @@ -28,7 +29,7 @@ jetty-7.0.0.RC4 18 August 2009 + 279820 Fixed HotSwapHandler + JETTY-1080 Ignore files that would be extracted outside the destination directory when unpacking WARs + JETTY-1057 XSS error page - + jetty-7.0.0.RC3 7 August 2009 + 277403 remove system properties + JETTY-1074 JMX thread manipulation @@ -52,7 +53,7 @@ jetty-7.0.0.RC2 29 June 2009 + 284981 Implement a cross-origin filter + Improved handling of overlays and resourceCollections + 285006 fix AbstractConnector NPE during shutdown. - + jetty-7.0.0.RC1 15 June 2009 + JETTY-1066 283357 400 response for bad URIs + JETTY-1068 Avoid busy flush of async SSL diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java index 779832998f6..0a031197441 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java @@ -4,11 +4,11 @@ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // 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 // The Apache License v2.0 is available at // 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; @@ -17,7 +17,6 @@ import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; - import javax.servlet.ServletRequest; import org.eclipse.jetty.http.HttpBuffers; @@ -42,13 +41,13 @@ import org.eclipse.jetty.util.thread.ThreadPool; *
  • Base acceptor thread
  • *
  • Optional reverse proxy headers checking
  • * - * - * + * + * */ public abstract class AbstractConnector extends HttpBuffers implements Connector { private String _name; - + private Server _server; private ThreadPool _threadPool; 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 _forwardedForHeader = "X-Forwarded-For"; // default to mod_proxy_http header private boolean _reuseAddress=true; - - protected int _maxIdleTime=200000; - protected int _lowResourceMaxIdleTime=-1; - protected int _soLingerTime=-1; - + + protected int _maxIdleTime=200000; + protected int _lowResourceMaxIdleTime=-1; + protected int _soLingerTime=-1; + private transient Thread[] _acceptorThread; - + final Object _statsLock = new Object(); transient long _statsStartedAt=-1; - + // TODO use concurrents for these! transient int _requests; transient int _connections; // total number of connections made to server - + transient int _connectionsOpen; // number of connections currently open transient int _connectionsOpenMin; // min number of connections open simultaneously transient int _connectionsOpenMax; // max number of connections open simultaneously - + transient long _connectionsDurationMin; // min duration of a connection transient long _connectionsDurationMax; // max duration of a connection transient long _connectionsDurationTotal; // total duration of all coneection - + transient int _connectionsRequestsMin; // min requests per connection transient int _connectionsRequestsMax; // max requests per connection - + /* ------------------------------------------------------------------------------- */ - /** + /** */ public AbstractConnector() { @@ -106,13 +105,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector // TODO remove once no overrides established return null; } - + /* ------------------------------------------------------------------------------- */ public Buffer newRequestBuffer(int size) { return new ByteArrayBuffer(size); } - + /* ------------------------------------------------------------------------------- */ public Buffer newRequestHeader(int size) { @@ -124,7 +123,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { return new ByteArrayBuffer(size); } - + /* ------------------------------------------------------------------------------- */ public Buffer newResponseHeader(int size) { @@ -142,7 +141,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { return true; } - + /* ------------------------------------------------------------------------------- */ /* */ @@ -156,7 +155,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _server=server; } - + /* ------------------------------------------------------------------------------- */ /* * @see org.eclipse.jetty.http.HttpListener#getHttpServer() @@ -171,11 +170,11 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _threadPool=pool; } - + /* ------------------------------------------------------------------------------- */ /** */ - public void setHost(String host) + public void setHost(String host) { _host=host; } @@ -206,7 +205,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector return _port; } - + /* ------------------------------------------------------------ */ /** * @return Returns the maxIdleTime. @@ -215,38 +214,38 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { return _maxIdleTime; } - + /* ------------------------------------------------------------ */ /** * Set the maximum Idle time for a connection, which roughly translates - * to the {@link Socket#setSoTimeout(int)} call, although with NIO - * implementations other mechanisms may be used to implement the timeout. + * to the {@link Socket#setSoTimeout(int)} call, although with NIO + * implementations other mechanisms may be used to implement the timeout. * The max idle time is applied: * 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, * 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 * 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. *

    * Previously, Jetty supported separate idle timeouts and IO operation timeouts, * 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 * again differentiate these values (if there is demand). - * + * * @param maxIdleTime The maxIdleTime to set. */ public void setMaxIdleTime(int maxIdleTime) { _maxIdleTime = maxIdleTime; } - + /* ------------------------------------------------------------ */ /** * @return Returns the maxIdleTime. @@ -255,7 +254,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { return _lowResourceMaxIdleTime; } - + /* ------------------------------------------------------------ */ /** * @param maxIdleTime The maxIdleTime to set. @@ -264,7 +263,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _lowResourceMaxIdleTime = maxIdleTime; } - + /* ------------------------------------------------------------ */ /** * @return Returns the soLingerTime. @@ -291,7 +290,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _acceptQueueSize = acceptQueueSize; } - + /* ------------------------------------------------------------ */ /** * @return Returns the number of acceptor threads. @@ -309,7 +308,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _acceptors = acceptors; } - + /* ------------------------------------------------------------ */ /** * @param soLingerTime The soLingerTime to set or -1 to disable. @@ -318,23 +317,23 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _soLingerTime = soLingerTime; } - + /* ------------------------------------------------------------ */ protected void doStart() throws Exception { if (_server==null) throw new IllegalStateException("No server"); - + // open listener port open(); - + super.doStart(); - + if (_threadPool==null) _threadPool=_server.getThreadPool(); if (_threadPool!=_server.getThreadPool() && (_threadPool instanceof LifeCycle)) ((LifeCycle)_threadPool).start(); - + // Start selector thread synchronized(this) { @@ -349,22 +348,22 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector } } } - + Log.info("Started {}",this); } - + /* ------------------------------------------------------------ */ protected void doStop() throws Exception { try{close();} catch(IOException e) {Log.warn(e);} - + if (_threadPool==_server.getThreadPool()) _threadPool=null; else if (_threadPool instanceof LifeCycle) ((LifeCycle)_threadPool).stop(); - + super.doStop(); - + Thread[] acceptors=null; synchronized(this) { @@ -381,7 +380,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector } } } - + /* ------------------------------------------------------------ */ public void join() throws InterruptedException { @@ -395,7 +394,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector /* ------------------------------------------------------------ */ protected void configure(Socket socket) throws IOException - { + { try { socket.setTcpNoDelay(true); @@ -426,15 +425,15 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector throws IOException { HttpFields httpFields = request.getConnection().getRequestFields(); - + // Retrieving headers from the request String forwardedHost = getLeftMostValue(httpFields.getStringField(getForwardedHostHeader())); String forwardedServer = getLeftMostValue(httpFields.getStringField(getForwardedServerHeader())); String forwardedFor = getLeftMostValue(httpFields.getStringField(getForwardedForHeader())); - + if (_hostHeader!=null) { - // Update host header + // Update host header httpFields.put(HttpHeaders.HOST_BUFFER, _hostHeader); request.setServerName(null); request.setServerPort(-1); @@ -442,7 +441,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector } else if (forwardedHost != null) { - // Update host header + // Update host header httpFields.put(HttpHeaders.HOST_BUFFER, forwardedHost); request.setServerName(null); request.setServerPort(-1); @@ -453,12 +452,12 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector // Use provided server name request.setServerName(forwardedServer); } - + if (forwardedFor != null) { request.setRemoteAddr(forwardedFor); InetAddress inetAddress = null; - + if (_useDNS) { try @@ -470,7 +469,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector Log.ignore(e); } } - + request.setRemoteHost(inetAddress==null?forwardedFor:inetAddress.getHostName()); } } @@ -479,9 +478,9 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector protected String getLeftMostValue(String headerValue) { if (headerValue == null) return null; - + int commaIndex = headerValue.indexOf(','); - + if (commaIndex == -1) { // Single value @@ -495,13 +494,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector /* ------------------------------------------------------------ */ public void persist(EndPoint endpoint) throws IOException - { + { } - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ - /* + /* * @see org.eclipse.jetty.server.Connector#getConfidentialPort() */ public int getConfidentialPort() @@ -511,16 +510,16 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ - /* + /* * @see org.eclipse.jetty.server.Connector#getConfidentialScheme() */ public String getConfidentialScheme() { return _confidentialScheme; } - + /* ------------------------------------------------------------ */ - /* + /* * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.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() */ public int getIntegralPort() { return _integralPort; } - + /* ------------------------------------------------------------ */ - /* + /* * @see org.eclipse.jetty.server.Connector#getIntegralScheme() */ public String getIntegralScheme() { return _integralScheme; } - + /* ------------------------------------------------------------ */ - /* + /* * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request) */ public boolean isConfidential(Request request) @@ -590,7 +589,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _integralScheme = integralScheme; } - + /* ------------------------------------------------------------ */ 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 boolean getResolveNames() { return _useDNS; } - + /* ------------------------------------------------------------ */ public void setResolveNames(boolean resolve) { _useDNS=resolve; } - + /* ------------------------------------------------------------ */ - /** + /** * Is reverse proxy handling on? * @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; } - + /* ------------------------------------------------------------ */ /** * Set reverse proxy handling @@ -632,15 +631,15 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector Log.debug(this+" is forwarded"); _forwarded=check; } - + /* ------------------------------------------------------------ */ public String getHostHeader() { return _hostHeader; } - + /* ------------------------------------------------------------ */ - /** + /** * Set a forced valued for the host header to control what is returned * by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}. * This value is only used if {@link #isForwarded()} is true. @@ -650,13 +649,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _hostHeader=hostHeader; } - + /* ------------------------------------------------------------ */ public String getForwardedHostHeader() { return _forwardedHostHeader; } - + /* ------------------------------------------------------------ */ /** * @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; } - + /* ------------------------------------------------------------ */ public String getForwardedServerHeader() { return _forwardedServerHeader; } - + /* ------------------------------------------------------------ */ /** * @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; } - + /* ------------------------------------------------------------ */ public String getForwardedForHeader() { return _forwardedForHeader; } - + /* ------------------------------------------------------------ */ /** * @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; } - + /* ------------------------------------------------------------ */ public String toString() { @@ -703,39 +702,39 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector int dot = name.lastIndexOf('.'); if (dot>0) name=name.substring(dot+1); - + return name+"@"+(getHost()==null?"0.0.0.0":getHost())+":"+(getLocalPort()<=0?getPort():getLocalPort()); } - - + + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ private class Acceptor implements Runnable { int _acceptor=0; - + Acceptor(int id) { _acceptor=id; } - + /* ------------------------------------------------------------ */ public void run() - { + { Thread current = Thread.currentThread(); String name; synchronized(AbstractConnector.this) { if (_acceptorThread==null) return; - + _acceptorThread[_acceptor]=current; name =_acceptorThread[_acceptor].getName(); current.setName(name+" - Acceptor"+_acceptor+" "+AbstractConnector.this); } int old_priority=current.getPriority(); - + try { current.setPriority(old_priority-_acceptorPriorityOffset); @@ -743,7 +742,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { try { - accept(_acceptor); + accept(_acceptor); } catch(EofException e) { @@ -753,6 +752,11 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { Log.ignore(e); } + catch (InterruptedException x) + { + // Connector has been stopped + Log.ignore(x); + } catch(ThreadDeath e) { throw e; @@ -764,7 +768,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector } } finally - { + { current.setPriority(old_priority); current.setName(name); try @@ -776,7 +780,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { Log.warn(e); } - + synchronized(AbstractConnector.this) { if (_acceptorThread!=null) @@ -799,8 +803,8 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _name = name; } - - + + /* ------------------------------------------------------------ */ /** @@ -848,56 +852,56 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector /* ------------------------------------------------------------ */ - /** + /** * @return Number of connections accepted by the server since * statsReset() called. Undefined if setStatsOn(false). */ public int getConnections() {return _connections;} /* ------------------------------------------------------------ */ - /** + /** * @return Number of connections currently open that were opened * since statsReset() called. Undefined if setStatsOn(false). */ public int getConnectionsOpen() {return _connectionsOpen;} /* ------------------------------------------------------------ */ - /** + /** * @return Maximum number of connections opened simultaneously * since statsReset() called. Undefined if setStatsOn(false). */ public int getConnectionsOpenMax() {return _connectionsOpenMax;} /* ------------------------------------------------------------ */ - /** + /** * @return Average duration in milliseconds of open connections * since statsReset() called. Undefined if setStatsOn(false). */ public long getConnectionsDurationAve() {return _connections==0?0:(_connectionsDurationTotal/_connections);} /* ------------------------------------------------------------ */ - /** + /** * @return Maximum duration in milliseconds of an open connection * since statsReset() called. Undefined if setStatsOn(false). */ public long getConnectionsDurationMax() {return _connectionsDurationMax;} /* ------------------------------------------------------------ */ - /** + /** * @return Average number of requests per connection * since statsReset() called. Undefined if setStatsOn(false). */ public int getConnectionsRequestsAve() {return _connections==0?0:(_requests/_connections);} /* ------------------------------------------------------------ */ - /** + /** * @return Maximum number of requests per connection * since statsReset() called. Undefined if setStatsOn(false). */ public int getConnectionsRequestsMax() {return _connectionsRequestsMax;} - + /* ------------------------------------------------------------ */ /** Reset statistics. */ @@ -906,11 +910,11 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector _statsStartedAt=_statsStartedAt==-1?-1:System.currentTimeMillis(); _connections=0; - + _connectionsOpenMin=_connectionsOpen; _connectionsOpenMax=_connectionsOpen; _connectionsOpen=0; - + _connectionsDurationMin=0; _connectionsDurationMax=0; _connectionsDurationTotal=0; @@ -920,7 +924,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector _connectionsRequestsMin=0; _connectionsRequestsMax=0; } - + /* ------------------------------------------------------------ */ public void setStatsOn(boolean on) { @@ -930,25 +934,25 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector statsReset(); _statsStartedAt=on?System.currentTimeMillis():-1; } - + /* ------------------------------------------------------------ */ - /** + /** * @return True if statistics collection is turned on. */ public boolean getStatsOn() { return _statsStartedAt!=-1; } - + /* ------------------------------------------------------------ */ - /** + /** * @return Timestamp stats were started at. */ public long getStatsOnMs() { return (_statsStartedAt!=-1)?(System.currentTimeMillis()-_statsStartedAt):0; } - + /* ------------------------------------------------------------ */ protected void connectionOpened(HttpConnection connection) { @@ -961,16 +965,16 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector _connectionsOpenMax=_connectionsOpen; } } - + /* ------------------------------------------------------------ */ protected void connectionClosed(HttpConnection connection) - { + { if (_statsStartedAt>=0) { long duration=System.currentTimeMillis()-connection.getTimeStamp(); int requests=connection.getRequests(); - - + + synchronized(_statsLock) { _requests+=requests; @@ -991,7 +995,7 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector _connectionsRequestsMax=requests; } } - + } /* ------------------------------------------------------------ */