From 968a2ac95b9bbf5c8af0b1e708f2bc741532e39d Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 00:09:34 +1100 Subject: [PATCH 01/18] 368240: Added concept of join to AggregateLifeCycle. Used by HttpClient and AbstractConnector --- .../org/eclipse/jetty/client/HttpClient.java | 177 +++++++---- .../eclipse/jetty/client/SelectConnector.java | 6 +- .../org/eclipse/jetty/http/HttpBuffers.java | 164 ++-------- .../eclipse/jetty/http/HttpBuffersImpl.java | 233 ++++++++++++++ .../org/eclipse/jetty/io/AbstractBuffers.java | 8 +- .../org/eclipse/jetty/io/PooledBuffers.java | 9 + .../eclipse/jetty/io/nio/SelectorManager.java | 3 + .../jetty/rewrite/handler/ProxyRuleTest.java | 4 +- .../jetty/server/AbstractConnector.java | 127 ++++++-- .../server/nio/AbstractNIOConnector.java | 12 +- .../server/nio/SelectChannelConnector.java | 39 +-- .../server/ssl/SslSelectChannelConnector.java | 3 +- .../util/component/AggregateLifeCycle.java | 291 ++++++++++++++---- .../jetty/util/ssl/SslContextFactory.java | 8 +- .../component/AggregateLifeCycleTest.java | 106 +++++++ 15 files changed, 863 insertions(+), 327 deletions(-) create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffersImpl.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index 21e8b0f89e9..baad2e962f7 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -29,7 +29,9 @@ import org.eclipse.jetty.client.security.Authentication; import org.eclipse.jetty.client.security.RealmResolver; import org.eclipse.jetty.client.security.SecurityListener; import org.eclipse.jetty.http.HttpBuffers; +import org.eclipse.jetty.http.HttpBuffersImpl; import org.eclipse.jetty.http.HttpSchemes; +import org.eclipse.jetty.io.Buffers; import org.eclipse.jetty.io.Buffers.Type; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.AttributesMap; @@ -66,7 +68,7 @@ import org.eclipse.jetty.util.thread.Timeout; * @see HttpExchange * @see HttpDestination */ -public class HttpClient extends HttpBuffers implements Attributes, Dumpable +public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attributes, Dumpable { public static final int CONNECTOR_SOCKET = 0; public static final int CONNECTOR_SELECT_CHANNEL = 2; @@ -91,43 +93,46 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable private int _maxRedirects = 20; private LinkedList _registeredListeners; - private SslContextFactory _sslContextFactory; + private final SslContextFactory _sslContextFactory; private RealmResolver _realmResolver; private AttributesMap _attributes=new AttributesMap(); + private final HttpBuffersImpl _buffers= new HttpBuffersImpl(); /* ------------------------------------------------------------------------------- */ private void setBufferTypes() { if (_connectorType==CONNECTOR_SOCKET) { - setRequestBufferType(Type.BYTE_ARRAY); - setRequestHeaderType(Type.BYTE_ARRAY); - setResponseBufferType(Type.BYTE_ARRAY); - setResponseHeaderType(Type.BYTE_ARRAY); + _buffers.setRequestBufferType(Type.BYTE_ARRAY); + _buffers.setRequestHeaderType(Type.BYTE_ARRAY); + _buffers.setResponseBufferType(Type.BYTE_ARRAY); + _buffers.setResponseHeaderType(Type.BYTE_ARRAY); } else { - setRequestBufferType(Type.DIRECT); - setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT); - setResponseBufferType(Type.DIRECT); - setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT); + _buffers.setRequestBufferType(Type.DIRECT); + _buffers.setRequestHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT); + _buffers.setResponseBufferType(Type.DIRECT); + _buffers.setResponseHeaderType(_useDirectBuffers?Type.DIRECT:Type.INDIRECT); } + } /* ------------------------------------------------------------------------------- */ public HttpClient() { this(new SslContextFactory()); - setBufferTypes(); } /* ------------------------------------------------------------------------------- */ public HttpClient(SslContextFactory sslContextFactory) { _sslContextFactory = sslContextFactory; + addBean(_sslContextFactory); + addBean(_buffers); setBufferTypes(); } @@ -149,25 +154,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable _connectBlocking = connectBlocking; } - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.Dumpable#dump() - */ - public String dump() - { - return AggregateLifeCycle.dump(this); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.util.component.Dumpable#dump(java.lang.Appendable, java.lang.String) - */ - public void dump(Appendable out, String indent) throws IOException - { - out.append(String.valueOf(this)).append("\n"); - AggregateLifeCycle.dump(out,indent,Arrays.asList(_threadPool,_connector),_destinations.values()); - } - /* ------------------------------------------------------------------------------- */ public void send(HttpExchange exchange) throws IOException { @@ -190,6 +176,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable pool.setDaemon(true); pool.setName("HttpClient"); _threadPool = pool; + addBean(_threadPool,true); } return _threadPool; @@ -201,7 +188,9 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable */ public void setThreadPool(ThreadPool threadPool) { + removeBean(_threadPool); _threadPool = threadPool; + addBean(_threadPool); } @@ -338,6 +327,7 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable } + /* ------------------------------------------------------------ */ /** * Registers a listener that can listen to the stream of execution between the client and the * server and influence events. Sequential calls to the method wrapper sequentially wrap the preceding @@ -422,7 +412,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable protected void doStart() throws Exception { setBufferTypes(); - super.doStart(); _timeoutQ.setDuration(_timeout); _timeoutQ.setNow(); @@ -432,24 +421,12 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable if (_threadPool == null) getThreadPool(); - if (_threadPool instanceof LifeCycle) - { - ((LifeCycle)_threadPool).start(); - } - - _sslContextFactory.start(); - - if (_connectorType == CONNECTOR_SELECT_CHANNEL) - { - - _connector = new SelectConnector(this); - } - else - { - _connector = new SocketConnector(this); - } - _connector.start(); - + + _connector=(_connectorType == CONNECTOR_SELECT_CHANNEL)?new SelectConnector(this):new SocketConnector(this); + addBean(_connector,true); + + super.doStart(); + _threadPool.dispatch(new Runnable() { public void run() @@ -480,14 +457,6 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable @Override protected void doStop() throws Exception { - _connector.stop(); - _connector = null; - _sslContextFactory.stop(); - - if (_threadPool instanceof LifeCycle) - { - ((LifeCycle)_threadPool).stop(); - } for (HttpDestination destination : _destinations.values()) { destination.close(); @@ -496,6 +465,8 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable _timeoutQ.cancelAll(); _idleTimeoutQ.cancelAll(); super.doStop(); + _connector = null; + removeBean(_connector); } /* ------------------------------------------------------------ */ @@ -667,6 +638,98 @@ public class HttpClient extends HttpBuffers implements Attributes, Dumpable _maxRedirects = redirects; } + + + public int getRequestBufferSize() + { + return _buffers.getRequestBufferSize(); + } + + public void setRequestBufferSize(int requestBufferSize) + { + _buffers.setRequestBufferSize(requestBufferSize); + } + + public int getRequestHeaderSize() + { + return _buffers.getRequestHeaderSize(); + } + + public void setRequestHeaderSize(int requestHeaderSize) + { + _buffers.setRequestHeaderSize(requestHeaderSize); + } + + public int getResponseBufferSize() + { + return _buffers.getResponseBufferSize(); + } + + public void setResponseBufferSize(int responseBufferSize) + { + _buffers.setResponseBufferSize(responseBufferSize); + } + + public int getResponseHeaderSize() + { + return _buffers.getResponseHeaderSize(); + } + + public void setResponseHeaderSize(int responseHeaderSize) + { + _buffers.setResponseHeaderSize(responseHeaderSize); + } + + public Type getRequestBufferType() + { + return _buffers.getRequestBufferType(); + } + + public Type getRequestHeaderType() + { + return _buffers.getRequestHeaderType(); + } + + public Type getResponseBufferType() + { + return _buffers.getResponseBufferType(); + } + + public Type getResponseHeaderType() + { + return _buffers.getResponseHeaderType(); + } + + public void setRequestBuffers(Buffers requestBuffers) + { + _buffers.setRequestBuffers(requestBuffers); + } + + public void setResponseBuffers(Buffers responseBuffers) + { + _buffers.setResponseBuffers(responseBuffers); + } + + public Buffers getRequestBuffers() + { + return _buffers.getRequestBuffers(); + } + + public Buffers getResponseBuffers() + { + return _buffers.getResponseBuffers(); + } + + public void setMaxBuffers(int maxBuffers) + { + _buffers.setMaxBuffers(maxBuffers); + } + + public int getMaxBuffers() + { + return _buffers.getMaxBuffers(); + } + /* ------------------------------------------------------------ */ @Deprecated public String getTrustStoreLocation() diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java index b3c93a7dee8..892991bd964 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java @@ -97,9 +97,9 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector, if (_httpClient.isConnectBlocking()) { - channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout()); - channel.configureBlocking(false); - _selectorManager.register( channel, destination ); + channel.socket().connect(address.toSocketAddress(), _httpClient.getConnectTimeout()); + channel.configureBlocking(false); + _selectorManager.register( channel, destination ); } else { diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java index 28c5ad13bdf..a502e72567f 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffers.java @@ -19,211 +19,85 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle; /* ------------------------------------------------------------ */ /** Abstract Buffer pool. - * simple unbounded pool of buffers for header, request and response sizes. - * */ -public class HttpBuffers extends AbstractLifeCycle +public interface HttpBuffers { - private int _requestBufferSize=16*1024; - private int _requestHeaderSize=6*1024; - private int _responseBufferSize=32*1024; - private int _responseHeaderSize=6*1024; - private int _maxBuffers=1024; - - private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY; - private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY; - private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY; - private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY; - - private Buffers _requestBuffers; - private Buffers _responseBuffers; - - - public HttpBuffers() - { - super(); - } - /** * @return the requestBufferSize */ - public int getRequestBufferSize() - { - return _requestBufferSize; - } + public int getRequestBufferSize(); /** * @param requestBufferSize the requestBufferSize to set */ - public void setRequestBufferSize(int requestBufferSize) - { - _requestBufferSize = requestBufferSize; - } + public void setRequestBufferSize(int requestBufferSize); /** * @return the requestHeaderSize */ - public int getRequestHeaderSize() - { - return _requestHeaderSize; - } + public int getRequestHeaderSize(); /** * @param requestHeaderSize the requestHeaderSize to set */ - public void setRequestHeaderSize(int requestHeaderSize) - { - _requestHeaderSize = requestHeaderSize; - } + public void setRequestHeaderSize(int requestHeaderSize); /** * @return the responseBufferSize */ - public int getResponseBufferSize() - { - return _responseBufferSize; - } + public int getResponseBufferSize(); /** * @param responseBufferSize the responseBufferSize to set */ - public void setResponseBufferSize(int responseBufferSize) - { - _responseBufferSize = responseBufferSize; - } + public void setResponseBufferSize(int responseBufferSize); /** * @return the responseHeaderSize */ - public int getResponseHeaderSize() - { - return _responseHeaderSize; - } + public int getResponseHeaderSize(); /** * @param responseHeaderSize the responseHeaderSize to set */ - public void setResponseHeaderSize(int responseHeaderSize) - { - _responseHeaderSize = responseHeaderSize; - } + public void setResponseHeaderSize(int responseHeaderSize); /** * @return the requestBufferType */ - public Buffers.Type getRequestBufferType() - { - return _requestBufferType; - } - - /** - * @param requestBufferType the requestBufferType to set - */ - protected void setRequestBufferType(Buffers.Type requestBufferType) - { - _requestBufferType = requestBufferType; - } + public Buffers.Type getRequestBufferType(); /** * @return the requestHeaderType */ - public Buffers.Type getRequestHeaderType() - { - return _requestHeaderType; - } - - /** - * @param requestHeaderType the requestHeaderType to set - */ - protected void setRequestHeaderType(Buffers.Type requestHeaderType) - { - _requestHeaderType = requestHeaderType; - } + public Buffers.Type getRequestHeaderType(); /** * @return the responseBufferType */ - public Buffers.Type getResponseBufferType() - { - return _responseBufferType; - } - - /** - * @param responseBufferType the responseBufferType to set - */ - protected void setResponseBufferType(Buffers.Type responseBufferType) - { - _responseBufferType = responseBufferType; - } + public Buffers.Type getResponseBufferType(); /** * @return the responseHeaderType */ - public Buffers.Type getResponseHeaderType() - { - return _responseHeaderType; - } - - /** - * @param responseHeaderType the responseHeaderType to set - */ - protected void setResponseHeaderType(Buffers.Type responseHeaderType) - { - _responseHeaderType = responseHeaderType; - } + public Buffers.Type getResponseHeaderType(); /** * @param requestBuffers the requestBuffers to set */ - public void setRequestBuffers(Buffers requestBuffers) - { - _requestBuffers = requestBuffers; - } + public void setRequestBuffers(Buffers requestBuffers); /** * @param responseBuffers the responseBuffers to set */ - public void setResponseBuffers(Buffers responseBuffers) - { - _responseBuffers = responseBuffers; - } + public void setResponseBuffers(Buffers responseBuffers); - @Override - protected void doStart() - throws Exception - { - _requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers()); - _responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers()); - super.doStart(); - } - - @Override - protected void doStop() - throws Exception - { - _requestBuffers=null; - _responseBuffers=null; - } + public Buffers getRequestBuffers(); - public Buffers getRequestBuffers() - { - return _requestBuffers; - } - + public Buffers getResponseBuffers(); - public Buffers getResponseBuffers() - { - return _responseBuffers; - } + public void setMaxBuffers(int maxBuffers); - public void setMaxBuffers(int maxBuffers) - { - _maxBuffers = maxBuffers; - } - - public int getMaxBuffers() - { - return _maxBuffers; - } + public int getMaxBuffers(); } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffersImpl.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffersImpl.java new file mode 100644 index 00000000000..43db337e73c --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpBuffersImpl.java @@ -0,0 +1,233 @@ +// ======================================================================== +// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// 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 +// 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. +// ======================================================================== + +package org.eclipse.jetty.http; + +import org.eclipse.jetty.io.Buffers; +import org.eclipse.jetty.io.BuffersFactory; +import org.eclipse.jetty.util.component.AbstractLifeCycle; + +/* ------------------------------------------------------------ */ +/** Abstract Buffer pool. + * simple unbounded pool of buffers for header, request and response sizes. + * + */ +public class HttpBuffersImpl extends AbstractLifeCycle implements HttpBuffers +{ + private int _requestBufferSize=16*1024; + private int _requestHeaderSize=6*1024; + private int _responseBufferSize=32*1024; + private int _responseHeaderSize=6*1024; + private int _maxBuffers=1024; + + private Buffers.Type _requestBufferType=Buffers.Type.BYTE_ARRAY; + private Buffers.Type _requestHeaderType=Buffers.Type.BYTE_ARRAY; + private Buffers.Type _responseBufferType=Buffers.Type.BYTE_ARRAY; + private Buffers.Type _responseHeaderType=Buffers.Type.BYTE_ARRAY; + + private Buffers _requestBuffers; + private Buffers _responseBuffers; + + + public HttpBuffersImpl() + { + super(); + } + + /** + * @return the requestBufferSize + */ + public int getRequestBufferSize() + { + return _requestBufferSize; + } + + /** + * @param requestBufferSize the requestBufferSize to set + */ + public void setRequestBufferSize(int requestBufferSize) + { + _requestBufferSize = requestBufferSize; + } + + /** + * @return the requestHeaderSize + */ + public int getRequestHeaderSize() + { + return _requestHeaderSize; + } + + /** + * @param requestHeaderSize the requestHeaderSize to set + */ + public void setRequestHeaderSize(int requestHeaderSize) + { + _requestHeaderSize = requestHeaderSize; + } + + /** + * @return the responseBufferSize + */ + public int getResponseBufferSize() + { + return _responseBufferSize; + } + + /** + * @param responseBufferSize the responseBufferSize to set + */ + public void setResponseBufferSize(int responseBufferSize) + { + _responseBufferSize = responseBufferSize; + } + + /** + * @return the responseHeaderSize + */ + public int getResponseHeaderSize() + { + return _responseHeaderSize; + } + + /** + * @param responseHeaderSize the responseHeaderSize to set + */ + public void setResponseHeaderSize(int responseHeaderSize) + { + _responseHeaderSize = responseHeaderSize; + } + + /** + * @return the requestBufferType + */ + public Buffers.Type getRequestBufferType() + { + return _requestBufferType; + } + + /** + * @param requestBufferType the requestBufferType to set + */ + public void setRequestBufferType(Buffers.Type requestBufferType) + { + _requestBufferType = requestBufferType; + } + + /** + * @return the requestHeaderType + */ + public Buffers.Type getRequestHeaderType() + { + return _requestHeaderType; + } + + /** + * @param requestHeaderType the requestHeaderType to set + */ + public void setRequestHeaderType(Buffers.Type requestHeaderType) + { + _requestHeaderType = requestHeaderType; + } + + /** + * @return the responseBufferType + */ + public Buffers.Type getResponseBufferType() + { + return _responseBufferType; + } + + /** + * @param responseBufferType the responseBufferType to set + */ + public void setResponseBufferType(Buffers.Type responseBufferType) + { + _responseBufferType = responseBufferType; + } + + /** + * @return the responseHeaderType + */ + public Buffers.Type getResponseHeaderType() + { + return _responseHeaderType; + } + + /** + * @param responseHeaderType the responseHeaderType to set + */ + public void setResponseHeaderType(Buffers.Type responseHeaderType) + { + _responseHeaderType = responseHeaderType; + } + + /** + * @param requestBuffers the requestBuffers to set + */ + public void setRequestBuffers(Buffers requestBuffers) + { + _requestBuffers = requestBuffers; + } + + /** + * @param responseBuffers the responseBuffers to set + */ + public void setResponseBuffers(Buffers responseBuffers) + { + _responseBuffers = responseBuffers; + } + + @Override + protected void doStart() + throws Exception + { + _requestBuffers=BuffersFactory.newBuffers(_requestHeaderType,_requestHeaderSize,_requestBufferType,_requestBufferSize,_requestBufferType,getMaxBuffers()); + _responseBuffers=BuffersFactory.newBuffers(_responseHeaderType,_responseHeaderSize,_responseBufferType,_responseBufferSize,_responseBufferType,getMaxBuffers()); + super.doStart(); + } + + @Override + protected void doStop() + throws Exception + { + _requestBuffers=null; + _responseBuffers=null; + } + + public Buffers getRequestBuffers() + { + return _requestBuffers; + } + + + public Buffers getResponseBuffers() + { + return _responseBuffers; + } + + public void setMaxBuffers(int maxBuffers) + { + _maxBuffers = maxBuffers; + } + + public int getMaxBuffers() + { + return _maxBuffers; + } + + public String toString() + { + return _requestBuffers+"/"+_responseBuffers; + } +} diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java index ef828361357..bc24d078ae9 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java @@ -2,6 +2,7 @@ package org.eclipse.jetty.io; import org.eclipse.jetty.io.nio.DirectNIOBuffer; import org.eclipse.jetty.io.nio.IndirectNIOBuffer; +import org.omg.stub.java.rmi._Remote_Stub; public abstract class AbstractBuffers implements Buffers { @@ -141,5 +142,10 @@ public abstract class AbstractBuffers implements Buffers } return false; } - + + /* ------------------------------------------------------------ */ + public String toString() + { + return this.getClass().getSimpleName()+"["+_headerSize+","+_bufferSize+"]"; + } } \ No newline at end of file diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java b/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java index 90f297e73d4..9c476312544 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java @@ -92,4 +92,13 @@ public class PooledBuffers extends AbstractBuffers _others.add(buffer); } } + + public String toString() + { + return this.getClass().getSimpleName()+ + "["+ + _headers.size()+"/"+_maxSize+"@"+_headerSize+","+ + _buffers.size()+"/"+_maxSize+"@"+_bufferSize+","+ + _others.size()+"/"+_maxSize+"@-]"; + } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java index eaeabc88624..dd101e9fbc1 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java @@ -938,6 +938,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa final ArrayList dump = new ArrayList(selector.keys().size()*2); dump.add(where); + /* final CountDownLatch latch = new CountDownLatch(1); addChange(new ChangeTask() @@ -957,6 +958,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa { LOG.ignore(e); } + */ + AggregateLifeCycle.dump(out,indent,dump); } } diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java index 9cb9def596a..85cab0f2ba0 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java @@ -31,6 +31,7 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.util.log.Log; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -87,7 +88,8 @@ public class ProxyRuleTest @Test public void testProxy() throws Exception { - + Log.getLogger("org.eclipse.jetty.client").setDebugEnabled(true); + ContentExchange exchange = new ContentExchange(true); exchange.setMethod(HttpMethods.GET); String body = "BODY"; 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 6f349ca4f8b..acc51a1c4cb 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 @@ -22,9 +22,12 @@ import java.util.concurrent.atomic.AtomicLong; import javax.servlet.ServletRequest; import org.eclipse.jetty.http.HttpBuffers; +import org.eclipse.jetty.http.HttpBuffersImpl; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.http.HttpSchemes; +import org.eclipse.jetty.io.Buffers; +import org.eclipse.jetty.io.Buffers.Type; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EofException; @@ -51,7 +54,7 @@ import org.eclipse.jetty.util.thread.ThreadPool; * * */ -public abstract class AbstractConnector extends HttpBuffers implements Connector, Dumpable +public abstract class AbstractConnector extends AggregateLifeCycle implements HttpBuffers, Connector, Dumpable { private static final Logger LOG = Log.getLogger(AbstractConnector.class); @@ -95,11 +98,14 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector /** duration of a connection */ private final SampleStatistic _connectionDurationStats = new SampleStatistic(); + protected final HttpBuffersImpl _buffers = new HttpBuffersImpl(); + /* ------------------------------------------------------------ */ /** */ public AbstractConnector() { + addBean(_buffers); } /* ------------------------------------------------------------ */ @@ -125,7 +131,9 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector /* ------------------------------------------------------------ */ public void setThreadPool(ThreadPool pool) { + removeBean(_threadPool); _threadPool = pool; + addBean(_threadPool); } /* ------------------------------------------------------------ */ @@ -299,12 +307,13 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector // open listener port open(); - super.doStart(); - if (_threadPool == null) + { _threadPool = _server.getThreadPool(); - if (_threadPool != _server.getThreadPool() && (_threadPool instanceof LifeCycle)) - ((LifeCycle)_threadPool).start(); + addBean(_threadPool,false); + } + + super.doStart(); // Start selector thread synchronized (this) @@ -333,9 +342,6 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector LOG.warn(e); } - if (_threadPool != _server.getThreadPool() && _threadPool instanceof LifeCycle) - ((LifeCycle)_threadPool).stop(); - super.doStop(); Thread[] acceptors = null; @@ -785,6 +791,98 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector { _forwardedSslSessionIdHeader = forwardedSslSessionId; } + + + + public int getRequestBufferSize() + { + return _buffers.getRequestBufferSize(); + } + + public void setRequestBufferSize(int requestBufferSize) + { + _buffers.setRequestBufferSize(requestBufferSize); + } + + public int getRequestHeaderSize() + { + return _buffers.getRequestHeaderSize(); + } + + public void setRequestHeaderSize(int requestHeaderSize) + { + _buffers.setRequestHeaderSize(requestHeaderSize); + } + + public int getResponseBufferSize() + { + return _buffers.getResponseBufferSize(); + } + + public void setResponseBufferSize(int responseBufferSize) + { + _buffers.setResponseBufferSize(responseBufferSize); + } + + public int getResponseHeaderSize() + { + return _buffers.getResponseHeaderSize(); + } + + public void setResponseHeaderSize(int responseHeaderSize) + { + _buffers.setResponseHeaderSize(responseHeaderSize); + } + + public Type getRequestBufferType() + { + return _buffers.getRequestBufferType(); + } + + public Type getRequestHeaderType() + { + return _buffers.getRequestHeaderType(); + } + + public Type getResponseBufferType() + { + return _buffers.getResponseBufferType(); + } + + public Type getResponseHeaderType() + { + return _buffers.getResponseHeaderType(); + } + + public void setRequestBuffers(Buffers requestBuffers) + { + _buffers.setRequestBuffers(requestBuffers); + } + + public void setResponseBuffers(Buffers responseBuffers) + { + _buffers.setResponseBuffers(responseBuffers); + } + + public Buffers getRequestBuffers() + { + return _buffers.getRequestBuffers(); + } + + public Buffers getResponseBuffers() + { + return _buffers.getResponseBuffers(); + } + + public void setMaxBuffers(int maxBuffers) + { + _buffers.setMaxBuffers(maxBuffers); + } + + public int getMaxBuffers() + { + return _buffers.getMaxBuffers(); + } /* ------------------------------------------------------------ */ @Override @@ -1118,17 +1216,4 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector oldValue = valueHolder.get(); } } - - /* ------------------------------------------------------------ */ - public String dump() - { - return AggregateLifeCycle.dump(this); - } - - /* ------------------------------------------------------------ */ - public void dump(Appendable out, String indent) throws IOException - { - out.append(String.valueOf(this)).append("\n"); - } - } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java index 4fc4d1a301c..2083c5d3714 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java @@ -27,10 +27,10 @@ import org.eclipse.jetty.server.AbstractConnector; public abstract class AbstractNIOConnector extends AbstractConnector implements NIOConnector { { - setRequestBufferType(Type.DIRECT); - setRequestHeaderType(Type.INDIRECT); - setResponseBufferType(Type.DIRECT); - setResponseHeaderType(Type.INDIRECT); + _buffers.setRequestBufferType(Type.DIRECT); + _buffers.setRequestHeaderType(Type.INDIRECT); + _buffers.setResponseBufferType(Type.DIRECT); + _buffers.setResponseHeaderType(Type.INDIRECT); } /* ------------------------------------------------------------------------------- */ @@ -46,8 +46,8 @@ public abstract class AbstractNIOConnector extends AbstractConnector implements */ public void setUseDirectBuffers(boolean direct) { - setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT); - setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT); + _buffers.setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT); + _buffers.setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java index b6165d45fdf..9cf3ede1fef 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java @@ -82,6 +82,7 @@ public class SelectChannelConnector extends AbstractNIOConnector public SelectChannelConnector() { _manager.setMaxIdleTime(getMaxIdleTime()); + addBean(_manager,true); setAcceptors(Math.max(1,(Runtime.getRuntime().availableProcessors()+3)/4)); } @@ -111,7 +112,11 @@ public class SelectChannelConnector extends AbstractNIOConnector synchronized(this) { if (_acceptChannel != null) - _acceptChannel.close(); + { + removeBean(_acceptChannel); + if (_acceptChannel.isOpen()) + _acceptChannel.close(); + } _acceptChannel = null; _localPort=-2; } @@ -177,6 +182,8 @@ public class SelectChannelConnector extends AbstractNIOConnector _localPort=_acceptChannel.socket().getLocalPort(); if (_localPort<=0) throw new IOException("Server channel not bound"); + + addBean(_acceptChannel); } } @@ -250,7 +257,6 @@ public class SelectChannelConnector extends AbstractNIOConnector _manager.setLowResourcesMaxIdleTime(getLowResourcesMaxIdleTime()); super.doStart(); - _manager.start(); } /* ------------------------------------------------------------ */ @@ -260,20 +266,7 @@ public class SelectChannelConnector extends AbstractNIOConnector @Override protected void doStop() throws Exception { - synchronized(this) - { - if(_manager.isRunning()) - { - try - { - _manager.stop(); - } - catch (Exception e) - { - LOG.warn(e); - } - } - } + close(); super.doStop(); } @@ -297,20 +290,6 @@ public class SelectChannelConnector extends AbstractNIOConnector return new AsyncHttpConnection(SelectChannelConnector.this,endpoint,getServer()); } - /* ------------------------------------------------------------ */ - public void dump(Appendable out, String indent) throws IOException - { - super.dump(out, indent); - ServerSocketChannel channel; - synchronized (this) - { - channel=_acceptChannel; - } - if (channel==null) - AggregateLifeCycle.dump(out,indent,Arrays.asList(null,"CLOSED",_manager)); - else - AggregateLifeCycle.dump(out,indent,Arrays.asList(channel,channel.isOpen()?"OPEN":"CLOSED",_manager)); - } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java index 1986e7bc08d..e7746cbb5c6 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java @@ -57,6 +57,7 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements public SslSelectChannelConnector(SslContextFactory sslContextFactory) { _sslContextFactory = sslContextFactory; + addBean(_sslContextFactory); setUseDirectBuffers(false); setSoLingerTime(30000); } @@ -597,7 +598,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements protected void doStart() throws Exception { _sslContextFactory.checkKeyStore(); - _sslContextFactory.start(); SSLEngine sslEngine = _sslContextFactory.newSslEngine(); @@ -627,7 +627,6 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements @Override protected void doStop() throws Exception { - _sslContextFactory.stop(); _sslBuffers=null; super.doStop(); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java index 8e14c84b7d0..281779a5241 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java @@ -12,92 +12,242 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; /** - * An AggregateLifeCycle is an AbstractLifeCycle with a collection of dependent beans. + * An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans. + *

+ * Beans can be added the AggregateLifeCycle either as joined beans, as disjoint beans. A joined bean is started, stopped and destroyed with the aggregate. + * A disjointed bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally. + *

+ * When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be a disjoined bean. + * Otherwise the methods {@link #addBean(LifeCycle, boolean)}, {@link #join(LifeCycle)} and {@link #disjoin(LifeCycle)} can be used to + * explicitly control the life cycle relationship. *

- * Dependent beans are started and stopped with the {@link LifeCycle} and if they are destroyed if they are also {@link Destroyable}. - * */ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable { private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class); - private final List _dependentBeans=new CopyOnWriteArrayList(); + private final List _beans=new CopyOnWriteArrayList(); - public void destroy() + private class Bean { - for (Object o : _dependentBeans) + Bean(Object b) { - if (o instanceof Destroyable) - { - ((Destroyable)o).destroy(); - } + _bean=b; } - _dependentBeans.clear(); + final Object _bean; + volatile boolean _joined=true; } + /* ------------------------------------------------------------ */ + /** + * Start the joined lifecycle beans in the order they were added. + * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() + */ @Override protected void doStart() throws Exception { - for (Object o:_dependentBeans) + for (Bean b:_beans) { - if (o instanceof LifeCycle) - ((LifeCycle)o).start(); + if (b._joined && b._bean instanceof LifeCycle) + { + LifeCycle l=(LifeCycle)b._bean; + if (!l.isRunning()) + l.start(); + } } super.doStart(); } - + + /* ------------------------------------------------------------ */ + /** + * Stop the joined lifecycle beans in the reverse order they were added. + * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() + */ @Override protected void doStop() throws Exception { super.doStop(); - List reverse = new ArrayList(_dependentBeans); + List reverse = new ArrayList(_beans); Collections.reverse(reverse); - for (Object o:reverse) + for (Bean b:reverse) { - if (o instanceof LifeCycle) - ((LifeCycle)o).stop(); + if (b._joined && b._bean instanceof LifeCycle) + { + LifeCycle l=(LifeCycle)b._bean; + if (l.isRunning()) + l.stop(); + } } } + /* ------------------------------------------------------------ */ + /** + * Destroy the joined Destroyable beans in the reverse order they were added. + * @see org.eclipse.jetty.util.component.Destroyable#destroy() + */ + public void destroy() + { + List reverse = new ArrayList(_beans); + Collections.reverse(reverse); + for (Bean b:reverse) + { + if (b._bean instanceof Destroyable && b._joined) + { + Destroyable d=(Destroyable)b._bean; + d.destroy(); + } + } + _beans.clear(); + } + + + /* ------------------------------------------------------------ */ + /** Is the bean contained in the aggregate. + * @param bean + * @return True if the aggregate contains the bean + */ + public boolean contains(Object bean) + { + for (Bean b:_beans) + if (b._bean==bean) + return true; + return false; + } + + /* ------------------------------------------------------------ */ + /** Is the bean joined to the aggregate. + * @param bean + * @return True if the aggregate contains the bean and it is joined + */ + public boolean isJoined(Object bean) + { + for (Bean b:_beans) + if (b._bean==bean) + return b._joined; + return false; + } + /* ------------------------------------------------------------ */ /** * Add an associated bean. - * The bean will be added to this LifeCycle and if it is also a - * {@link LifeCycle} instance, it will be - * started/stopped. Any beans that are also - * {@link Destroyable}, will be destroyed with the server. + * If the bean is a {@link LifeCycle}, it is added as neither joined or disjoint and + * that status will be determined when the Aggregate bean is started. * @param o the bean object to add + * @return true if the bean was added or false if it has already been added. */ public boolean addBean(Object o) { - if (o == null) + if (contains(o)) return false; - boolean added=false; - if (!_dependentBeans.contains(o)) + + Bean b = new Bean(o); + _beans.add(b); + + // extra LifeCycle handling + if (o instanceof LifeCycle) { - _dependentBeans.add(o); - added=true; + LifeCycle l=(LifeCycle)o; + + // If it is running, then assume it is disjoint + if (l.isRunning()) + b._joined=false; + + // else if we are running, then start the bean + else if (isRunning()) + { + try + { + l.start(); + } + catch(Exception e) + { + throw new RuntimeException (e); + } + } } - try + return true; + } + + /* ------------------------------------------------------------ */ + /** Add an associated lifecycle. + * @param o The lifecycle to add + * @param joined True if the LifeCycle is to be joined, otherwise it will be disjoint. + * @return + */ + public boolean addBean(Object o, boolean joined) + { + if (contains(o)) + return false; + + Bean b = new Bean(o); + b._joined=joined; + _beans.add(b); + + if (o instanceof LifeCycle) { - if (isStarted() && o instanceof LifeCycle) - ((LifeCycle)o).start(); + LifeCycle l=(LifeCycle)o; + + if (joined && isRunning()) + { + try + { + l.start(); + } + catch(Exception e) + { + throw new RuntimeException (e); + } + } } - catch (Exception e) + return true; + } + + /* ------------------------------------------------------------ */ + /** + * Join a bean to this aggregate, so that it is started/stopped/destroyed with the + * aggregate lifecycle. + * @param bean The bean to join (must already have been added). + */ + public void join(Object bean) + { + for (Bean b :_beans) { - throw new RuntimeException (e); + if (b._bean==bean) + { + b._joined=true; + return; + } } - return added; + throw new IllegalArgumentException(); } + /* ------------------------------------------------------------ */ + /** + * Disjoin a bean to this aggregate, so that it is not started/stopped/destroyed with the + * aggregate lifecycle. + * @param bean The bean to join (must already have been added). + */ + public void disjoin(Object bean) + { + for (Bean b :_beans) + { + if (b._bean==bean) + { + b._joined=false; + return; + } + } + throw new IllegalArgumentException(); + } + /* ------------------------------------------------------------ */ /** Get dependent beans * @return List of beans. */ public Collection getBeans() { - return _dependentBeans; + return getBeans(Object.class); } /* ------------------------------------------------------------ */ @@ -109,19 +259,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable public List getBeans(Class clazz) { ArrayList beans = new ArrayList(); - Iterator iter = _dependentBeans.iterator(); - while (iter.hasNext()) + for (Bean b:_beans) { - Object o = iter.next(); - if (clazz.isInstance(o)) - beans.add((T)o); + if (clazz.isInstance(b._bean)) + beans.add((T)(b._bean)); } return beans; } /* ------------------------------------------------------------ */ - /** Get dependent bean of a specific class. + /** Get dependent beans of a specific class. * If more than one bean of the type exist, the first is returned. * @see #addBean(Object) * @param clazz @@ -129,23 +277,13 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable */ public T getBean(Class clazz) { - Iterator iter = _dependentBeans.iterator(); - T t=null; - int count=0; - while (iter.hasNext()) + for (Bean b:_beans) { - Object o = iter.next(); - if (clazz.isInstance(o)) - { - count++; - if (t==null) - t=(T)o; - } + if (clazz.isInstance(b._bean)) + return (T)b._bean; } - if (count>1 && LOG.isDebugEnabled()) - LOG.debug("getBean({}) 1 of {}",clazz.getName(),count); - return t; + return null; } /* ------------------------------------------------------------ */ @@ -154,7 +292,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable */ public void removeBeans () { - _dependentBeans.clear(); + _beans.clear(); } /* ------------------------------------------------------------ */ @@ -163,9 +301,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable */ public boolean removeBean (Object o) { - if (o == null) - return false; - return _dependentBeans.remove(o); + Iterator i = _beans.iterator(); + while(i.hasNext()) + { + Bean b=i.next(); + if (b._bean==o) + { + _beans.remove(b); + return true; + } + } + return false; } /* ------------------------------------------------------------ */ @@ -218,7 +364,32 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable public void dump(Appendable out,String indent) throws IOException { dumpThis(out); - dump(out,indent,_dependentBeans); + int size=_beans.size(); + if (size==0) + return; + int i=0; + for (Bean b : _beans) + { + i++; + + if (b._joined) + { + out.append(indent).append(" +- "); + if (b._bean instanceof Dumpable) + ((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | ")); + else + out.append(String.valueOf(b._bean)).append("\n"); + } + else + { + out.append(indent).append(" +~ "); + out.append(String.valueOf(b._bean)).append("\n"); + } + + } + + if (i!=size) + out.append(indent).append(" |\n"); } /* ------------------------------------------------------------ */ diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index 6180022cd7e..d1b8d9bbfac 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -1521,5 +1521,11 @@ public class SslContextFactory extends AbstractLifeCycle sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols())); } - + + /* ------------------------------------------------------------ */ + public String toString() + { + return this.getClass().getSimpleName()+"@"+Integer.toHexString(hashCode())+ + "("+_keyStorePath+","+_trustStorePath+")#"+getState(); + } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java index 3bda2998abc..2b5ec8d6e86 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java @@ -110,6 +110,107 @@ public class AggregateLifeCycleTest } + @Test + public void testDisJoint() throws Exception + { + final AtomicInteger destroyed=new AtomicInteger(); + final AtomicInteger started=new AtomicInteger(); + final AtomicInteger stopped=new AtomicInteger(); + + AggregateLifeCycle a0=new AggregateLifeCycle(); + + AggregateLifeCycle a1=new AggregateLifeCycle() + { + @Override + protected void doStart() throws Exception + { + started.incrementAndGet(); + super.doStart(); + } + + @Override + protected void doStop() throws Exception + { + stopped.incrementAndGet(); + super.doStop(); + } + + @Override + public void destroy() + { + destroyed.incrementAndGet(); + super.destroy(); + } + + }; + + // Start the a1 bean before adding, makes it auto disjoint + a1.start(); + + // Now add it + a0.addBean(a1); + Assert.assertFalse(a0.isJoined(a1)); + + a0.start(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(0,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.start(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(0,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.stop(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(0,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a1.stop(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(1,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.start(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(1,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.join(a1); + Assert.assertTrue(a0.isJoined(a1)); + + a0.stop(); + Assert.assertEquals(1,started.get()); + Assert.assertEquals(1,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + + a0.start(); + Assert.assertEquals(2,started.get()); + Assert.assertEquals(1,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a0.stop(); + Assert.assertEquals(2,started.get()); + Assert.assertEquals(2,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + + a0.disjoin(a1); + Assert.assertFalse(a0.isJoined(a1)); + + a0.destroy(); + Assert.assertEquals(2,started.get()); + Assert.assertEquals(2,stopped.get()); + Assert.assertEquals(0,destroyed.get()); + + a1.destroy(); + Assert.assertEquals(2,started.get()); + Assert.assertEquals(2,stopped.get()); + Assert.assertEquals(1,destroyed.get()); + + } + @Test public void testDumpable() { @@ -159,6 +260,11 @@ public class AggregateLifeCycleTest System.err.println("--"); a2.addBean(aa0); a0.dumpStdErr(); + + System.err.println("--"); + a0.disjoin(aa); + a2.disjoin(aa0); + a0.dumpStdErr(); } } From a7783ae5687acf5d3e0c31441d3a8a46f2ba105f Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 01:04:01 +1100 Subject: [PATCH 02/18] 368240: Fixed the start of dependent beans --- .../eclipse/jetty/client/SelectConnector.java | 33 +++---------------- .../eclipse/jetty/io/nio/SelectorManager.java | 2 -- .../jetty/rewrite/handler/ProxyRule.java | 2 +- .../jetty/rewrite/handler/ProxyRuleTest.java | 4 +-- .../util/component/AggregateLifeCycle.java | 2 +- 5 files changed, 8 insertions(+), 35 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java index 892991bd964..944a8c64f6b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java @@ -35,13 +35,14 @@ import org.eclipse.jetty.io.nio.SslConnection; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.Dumpable; +import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.Timeout; import org.eclipse.jetty.util.thread.Timeout.Task; -class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector, Dumpable +class SelectConnector extends AggregateLifeCycle implements HttpClient.Connector, Dumpable { private static final Logger LOG = Log.getLogger(SelectConnector.class); @@ -49,39 +50,15 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector, private final Manager _selectorManager=new Manager(); private final Map _connectingChannels = new ConcurrentHashMap(); + /* ------------------------------------------------------------ */ /** * @param httpClient the HttpClient this connector is associated to */ SelectConnector(HttpClient httpClient) { _httpClient = httpClient; - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStart() throws Exception - { - super.doStart(); - - _selectorManager.start(); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStop() throws Exception - { - _selectorManager.stop(); - } - - public String dump() - { - return AggregateLifeCycle.dump(this); - } - - public void dump(Appendable out, String indent) throws IOException - { - out.append(String.valueOf(this)).append("\n"); - AggregateLifeCycle.dump(out, indent, Arrays.asList(_selectorManager)); + addBean(_httpClient,false); + addBean(_selectorManager,true); } /* ------------------------------------------------------------ */ diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java index dd101e9fbc1..4059a4db420 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java @@ -938,7 +938,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa final ArrayList dump = new ArrayList(selector.keys().size()*2); dump.add(where); - /* final CountDownLatch latch = new CountDownLatch(1); addChange(new ChangeTask() @@ -958,7 +957,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa { LOG.ignore(e); } - */ AggregateLifeCycle.dump(out,indent,dump); } diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ProxyRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ProxyRule.java index 8e63b8c5a74..841168e0ca5 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ProxyRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ProxyRule.java @@ -55,7 +55,7 @@ public class ProxyRule extends PatternRule private String _hostHeader; private String _proxyTo; - private int _connectorType = 2; + private int _connectorType = HttpClient.CONNECTOR_SELECT_CHANNEL; private String _maxThreads; private String _maxConnections; private String _timeout; diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java index 85cab0f2ba0..9cb9def596a 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java @@ -31,7 +31,6 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.nio.SelectChannelConnector; -import org.eclipse.jetty.util.log.Log; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -88,8 +87,7 @@ public class ProxyRuleTest @Test public void testProxy() throws Exception { - Log.getLogger("org.eclipse.jetty.client").setDebugEnabled(true); - + ContentExchange exchange = new ContentExchange(true); exchange.setMethod(HttpMethods.GET); String body = "BODY"; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java index 281779a5241..75e4a50253b 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java @@ -188,7 +188,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable { LifeCycle l=(LifeCycle)o; - if (joined && isRunning()) + if (joined && isStarted()) { try { From 8fcc22df321ae02cdf1d531cce657cdeb4c607b8 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 01:12:36 +1100 Subject: [PATCH 03/18] 368240: Improved handling of dispatch failure --- .../main/java/org/eclipse/jetty/io/nio/SelectorManager.java | 5 ++++- .../java/org/eclipse/jetty/server/AbstractConnector.java | 3 ++- .../java/org/eclipse/jetty/util/thread/QueuedThreadPool.java | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java index 4059a4db420..a28b46ab824 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectorManager.java @@ -260,7 +260,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa for (int i=0;i Date: Tue, 10 Jan 2012 17:39:17 +0100 Subject: [PATCH 04/18] Cosmetics. --- .../java/org/eclipse/jetty/client/SelectConnector.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java index 944a8c64f6b..363349d150e 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java @@ -18,10 +18,8 @@ import java.net.SocketTimeoutException; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.nio.channels.UnresolvedAddressException; -import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import javax.net.ssl.SSLEngine; import org.eclipse.jetty.io.AsyncEndPoint; @@ -32,10 +30,8 @@ import org.eclipse.jetty.io.nio.AsyncConnection; import org.eclipse.jetty.io.nio.SelectChannelEndPoint; import org.eclipse.jetty.io.nio.SelectorManager; import org.eclipse.jetty.io.nio.SslConnection; -import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; @@ -428,11 +424,10 @@ class SelectConnector extends AggregateLifeCycle implements HttpClient.Connector { return _endp.isCheckForIdle(); } - + public String toString() { return "Upgradable:"+_endp.toString(); } - } } From bb0a3201024263b065c6422eecffbcaf95298b89 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 10 Jan 2012 17:41:32 +0100 Subject: [PATCH 05/18] Improved toString(). --- .../org/eclipse/jetty/io/AbstractBuffers.java | 11 ++- .../org/eclipse/jetty/io/PooledBuffers.java | 22 +++--- .../jetty/server/AbstractConnector.java | 53 ++++++------- .../jetty/util/ssl/SslContextFactory.java | 75 ++++++++++--------- 4 files changed, 78 insertions(+), 83 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java index bc24d078ae9..b94710af5ca 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractBuffers.java @@ -2,7 +2,6 @@ package org.eclipse.jetty.io; import org.eclipse.jetty.io.nio.DirectNIOBuffer; import org.eclipse.jetty.io.nio.IndirectNIOBuffer; -import org.omg.stub.java.rmi._Remote_Stub; public abstract class AbstractBuffers implements Buffers { @@ -59,7 +58,7 @@ public abstract class AbstractBuffers implements Buffers } throw new IllegalStateException(); } - + /* ------------------------------------------------------------ */ /** * Create a new content Buffer @@ -78,7 +77,7 @@ public abstract class AbstractBuffers implements Buffers } throw new IllegalStateException(); } - + /* ------------------------------------------------------------ */ /** * Create a new content Buffer @@ -142,10 +141,10 @@ public abstract class AbstractBuffers implements Buffers } return false; } - + /* ------------------------------------------------------------ */ public String toString() { - return this.getClass().getSimpleName()+"["+_headerSize+","+_bufferSize+"]"; + return String.format("%s [%d,%d]", getClass().getSimpleName(), _headerSize, _bufferSize); } -} \ No newline at end of file +} diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java b/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java index 9c476312544..194eb9bf71b 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/PooledBuffers.java @@ -25,7 +25,7 @@ public class PooledBuffers extends AbstractBuffers _otherBuffers=bufferType==otherType; _maxSize=maxSize; } - + /* ------------------------------------------------------------ */ public Buffer getHeader() { @@ -55,17 +55,17 @@ public class PooledBuffers extends AbstractBuffers return getHeader(); if (_otherBuffers && size==getBufferSize()) return getBuffer(); - + // Look for an other buffer Buffer buffer = _others.poll(); - + // consume all other buffers until one of the right size is found while (buffer!=null && buffer.capacity()!=size) { _size.decrementAndGet(); buffer = _others.poll(); } - + if (buffer==null) buffer=newBuffer(size); else @@ -89,16 +89,16 @@ public class PooledBuffers extends AbstractBuffers else if (isBuffer(buffer)) _buffers.add(buffer); else - _others.add(buffer); + _others.add(buffer); } } - + public String toString() { - return this.getClass().getSimpleName()+ - "["+ - _headers.size()+"/"+_maxSize+"@"+_headerSize+","+ - _buffers.size()+"/"+_maxSize+"@"+_bufferSize+","+ - _others.size()+"/"+_maxSize+"@-]"; + return String.format("%s [%d/%d@%d,%d/%d@%d,%d/%d@-]", + getClass().getSimpleName(), + _headers.size(),_maxSize,_headerSize, + _buffers.size(),_maxSize,_bufferSize, + _others.size(),_maxSize); } } 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 37ae728d121..7a95f4d5fd2 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 @@ -18,7 +18,6 @@ import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.concurrent.atomic.AtomicLong; - import javax.servlet.ServletRequest; import org.eclipse.jetty.http.HttpBuffers; @@ -34,7 +33,6 @@ import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.statistic.CounterStatistic; @@ -87,7 +85,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht protected int _lowResourceMaxIdleTime = -1; protected int _soLingerTime = -1; - private transient Thread[] _acceptorThread; + private transient Thread[] _acceptorThreads; private final AtomicLong _statsStartedAt = new AtomicLong(-1L); @@ -99,7 +97,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht private final SampleStatistic _connectionDurationStats = new SampleStatistic(); protected final HttpBuffersImpl _buffers = new HttpBuffersImpl(); - + /* ------------------------------------------------------------ */ /** */ @@ -312,15 +310,15 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht _threadPool = _server.getThreadPool(); addBean(_threadPool,false); } - + super.doStart(); // Start selector thread synchronized (this) { - _acceptorThread = new Thread[getAcceptors()]; + _acceptorThreads = new Thread[getAcceptors()]; - for (int i = 0; i < _acceptorThread.length; i++) + for (int i = 0; i < _acceptorThreads.length; i++) if (!_threadPool.dispatch(new Acceptor(i))) throw new IllegalStateException("!accepting"); if (_threadPool.isLowOnThreads()) @@ -345,17 +343,16 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht super.doStop(); - Thread[] acceptors = null; + Thread[] acceptors; synchronized (this) { - acceptors = _acceptorThread; - _acceptorThread = null; + acceptors = _acceptorThreads; + _acceptorThreads = null; } if (acceptors != null) { - for (int i = 0; i < acceptors.length; i++) + for (Thread thread : acceptors) { - Thread thread = acceptors[i]; if (thread != null) thread.interrupt(); } @@ -368,12 +365,12 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht Thread[] threads; synchronized(this) { - threads= _acceptorThread; + threads=_acceptorThreads; } if (threads != null) - for (int i = 0; i < threads.length; i++) - if (threads[i] != null) - threads[i].join(); + for (Thread thread : threads) + if (thread != null) + thread.join(); } /* ------------------------------------------------------------ */ @@ -792,8 +789,6 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht { _forwardedSslSessionIdHeader = forwardedSslSessionId; } - - public int getRequestBufferSize() { @@ -889,13 +884,11 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht @Override public String toString() { - String name = this.getClass().getName(); - 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()) + " " - + AbstractLifeCycle.getState(this); + return String.format("%s@%s:%d %s", + getClass().getSimpleName(), + getHost()==null?"0.0.0.0":getHost(), + getLocalPort()<=0?getPort():getLocalPort(), + AbstractLifeCycle.getState(this)); } /* ------------------------------------------------------------ */ @@ -917,11 +910,11 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht String name; synchronized (AbstractConnector.this) { - if (_acceptorThread == null) + if (_acceptorThreads == null) return; - _acceptorThread[_acceptor] = current; - name = _acceptorThread[_acceptor].getName(); + _acceptorThreads[_acceptor] = current; + name = _acceptorThreads[_acceptor].getName(); current.setName(name + " Acceptor" + _acceptor + " " + AbstractConnector.this); } int old_priority = current.getPriority(); @@ -961,8 +954,8 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht synchronized (AbstractConnector.this) { - if (_acceptorThread != null) - _acceptorThread[_acceptor] = null; + if (_acceptorThreads != null) + _acceptorThreads[_acceptor] = null; } } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index d1b8d9bbfac..956c294b885 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -38,7 +38,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; - import javax.net.ssl.CertPathTrustManagerParameters; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; @@ -73,7 +72,7 @@ import org.eclipse.jetty.util.security.Password; public class SslContextFactory extends AbstractLifeCycle { private static final Logger LOG = Log.getLogger(SslContextFactory.class); - + public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM = (Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ? "SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm")); @@ -96,7 +95,7 @@ public class SslContextFactory extends AbstractLifeCycle // private final Set _excludeProtocols = new HashSet(Collections.singleton("SSLv2Hello")); /** Included protocols. */ private Set _includeProtocols = null; - + /** Excluded cipher suites. */ private final Set _excludeCipherSuites = new HashSet(); /** Included cipher suites. */ @@ -178,7 +177,7 @@ public class SslContextFactory extends AbstractLifeCycle /** SSL context */ private SSLContext _context; - + private boolean _trustAll; /* ------------------------------------------------------------ */ @@ -225,7 +224,7 @@ public class SslContextFactory extends AbstractLifeCycle _trustStore==null && _trustStoreInputStream == null && _trustStorePath == null ) { TrustManager[] trust_managers=null; - + if (_trustAll) { LOG.debug("No keystore or trust store configured. ACCEPTING UNTRUSTED CERTIFICATES!!!!!"); @@ -247,7 +246,7 @@ public class SslContextFactory extends AbstractLifeCycle }; trust_managers = new TrustManager[] { trustAllCerts }; } - + SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm); _context = SSLContext.getInstance(_sslProtocol); _context.init(null, trust_managers, secureRandom); @@ -255,7 +254,7 @@ public class SslContextFactory extends AbstractLifeCycle else { // verify that keystore and truststore - // parameters are set up correctly + // parameters are set up correctly checkKeyStore(); KeyStore keyStore = loadKeyStore(); @@ -293,7 +292,7 @@ public class SslContextFactory extends AbstractLifeCycle _context.init(keyManagers,trustManagers,secureRandom); SSLEngine engine=newSslEngine(); - + LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols())); if (LOG.isDebugEnabled()) LOG.debug("Enabled Ciphers {} of {}",Arrays.asList(engine.getEnabledCipherSuites()),Arrays.asList(engine.getSupportedCipherSuites())); @@ -334,7 +333,7 @@ public class SslContextFactory extends AbstractLifeCycle checkNotStarted(); _excludeProtocols.addAll(Arrays.asList(protocol)); } - + /* ------------------------------------------------------------ */ /** * @return The array of protocol names to include in @@ -380,7 +379,7 @@ public class SslContextFactory extends AbstractLifeCycle _excludeCipherSuites.clear(); _excludeCipherSuites.addAll(Arrays.asList(cipherSuites)); } - + /* ------------------------------------------------------------ */ /** * @param cipher Cipher names to add to {@link SSLEngine#setEnabledCipherSuites(String[])} @@ -429,7 +428,7 @@ public class SslContextFactory extends AbstractLifeCycle { return _keyStorePath; } - + /* ------------------------------------------------------------ */ /** * @param keyStorePath @@ -878,7 +877,7 @@ public class SslContextFactory extends AbstractLifeCycle { return (_keyManagerFactoryAlgorithm); } - + /* ------------------------------------------------------------ */ /** * @param algorithm @@ -1094,7 +1093,7 @@ public class SslContextFactory extends AbstractLifeCycle /* ------------------------------------------------------------ */ protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection crls) throws Exception - { + { TrustManager[] managers = null; if (trustStore != null) { @@ -1156,15 +1155,15 @@ public class SslContextFactory extends AbstractLifeCycle * used as truststore. * @throws IllegalStateException if SslContextFactory configuration can't be used. */ - public void checkKeyStore() + public void checkKeyStore() { if (_context != null) return; //nothing to check if using preconfigured context - - + + if (_keyStore == null && _keyStoreInputStream == null && _keyStorePath == null) throw new IllegalStateException("SSL doesn't have a valid keystore"); - + // if the keystore has been configured but there is no // truststore configured, use the keystore as the truststore if (_trustStore == null && _trustStoreInputStream == null && _trustStorePath == null) @@ -1209,7 +1208,7 @@ public class SslContextFactory extends AbstractLifeCycle public String[] selectProtocols(String[] enabledProtocols, String[] supportedProtocols) { Set selected_protocols = new HashSet(); - + // Set the starting protocols - either from the included or enabled list if (_includeProtocols!=null) { @@ -1220,15 +1219,15 @@ public class SslContextFactory extends AbstractLifeCycle } else selected_protocols.addAll(Arrays.asList(enabledProtocols)); - - + + // Remove any excluded protocols if (_excludeProtocols != null) selected_protocols.removeAll(_excludeProtocols); - + return selected_protocols.toArray(new String[selected_protocols.size()]); } - + /* ------------------------------------------------------------ */ /** * Select cipher suites to be used by the connector @@ -1241,7 +1240,7 @@ public class SslContextFactory extends AbstractLifeCycle public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites) { Set selected_ciphers = new HashSet(); - + // Set the starting ciphers - either from the included or enabled list if (_includeCipherSuites!=null) { @@ -1252,8 +1251,8 @@ public class SslContextFactory extends AbstractLifeCycle } else selected_ciphers.addAll(Arrays.asList(enabledCipherSuites)); - - + + // Remove any excluded ciphers if (_excludeCipherSuites != null) selected_ciphers.removeAll(_excludeCipherSuites); @@ -1450,7 +1449,7 @@ public class SslContextFactory extends AbstractLifeCycle { SSLServerSocketFactory factory = _context.getServerSocketFactory(); - SSLServerSocket socket = + SSLServerSocket socket = (SSLServerSocket) (host==null ? factory.createServerSocket(port,backlog): factory.createServerSocket(port,backlog,InetAddress.getByName(host))); @@ -1467,14 +1466,14 @@ public class SslContextFactory extends AbstractLifeCycle return socket; } - + /* ------------------------------------------------------------ */ public SSLSocket newSslSocket() throws IOException { SSLSocketFactory factory = _context.getSocketFactory(); - + SSLSocket socket = (SSLSocket)factory.createSocket(); - + if (getWantClientAuth()) socket.setWantClientAuth(getWantClientAuth()); if (getNeedClientAuth()) @@ -1482,23 +1481,23 @@ public class SslContextFactory extends AbstractLifeCycle socket.setEnabledCipherSuites(selectCipherSuites( socket.getEnabledCipherSuites(), - socket.getSupportedCipherSuites())); + socket.getSupportedCipherSuites())); socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols())); return socket; } - + /* ------------------------------------------------------------ */ public SSLEngine newSslEngine(String host,int port) { SSLEngine sslEngine=isSessionCachingEnabled() ?_context.createSSLEngine(host, port) :_context.createSSLEngine(); - + customize(sslEngine); return sslEngine; } - + /* ------------------------------------------------------------ */ public SSLEngine newSslEngine() { @@ -1518,14 +1517,18 @@ public class SslContextFactory extends AbstractLifeCycle sslEngine.setEnabledCipherSuites(selectCipherSuites( sslEngine.getEnabledCipherSuites(), sslEngine.getSupportedCipherSuites())); - + sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols())); } /* ------------------------------------------------------------ */ public String toString() { - return this.getClass().getSimpleName()+"@"+Integer.toHexString(hashCode())+ - "("+_keyStorePath+","+_trustStorePath+")#"+getState(); + return String.format("%s@%x(%s,%s)#%s", + getClass().getSimpleName(), + hashCode(), + _keyStorePath, + _trustStorePath, + getState()); } } From 297625b44692bd8f86fd1c20675abce2481dc3f2 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 10 Jan 2012 17:42:52 +0100 Subject: [PATCH 06/18] Removed redundant code and cleaned up. --- .../jetty/rewrite/handler/ProxyRuleTest.java | 8 +++---- .../server/nio/AbstractNIOConnector.java | 15 +++++-------- .../server/nio/SelectChannelConnector.java | 22 +------------------ 3 files changed, 9 insertions(+), 36 deletions(-) diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java index 9cb9def596a..b56b1bebc96 100644 --- a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java +++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ProxyRuleTest.java @@ -1,5 +1,3 @@ -package org.eclipse.jetty.rewrite.handler; - //======================================================================== //Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ @@ -12,12 +10,10 @@ package org.eclipse.jetty.rewrite.handler; //http://www.opensource.org/licenses/apache2.0.php //You may elect to redistribute this code under either of these licenses. //======================================================================== - -import static org.junit.Assert.assertEquals; +package org.eclipse.jetty.rewrite.handler; import java.io.IOException; import java.net.URLEncoder; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -35,6 +31,8 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class ProxyRuleTest { private static ProxyRule _rule; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java index 2083c5d3714..8e24a8c5eb5 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/AbstractNIOConnector.java @@ -4,35 +4,31 @@ // 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.nio; import org.eclipse.jetty.io.Buffers.Type; import org.eclipse.jetty.server.AbstractConnector; -/* ------------------------------------------------------------ */ -/** - * - * - */ public abstract class AbstractNIOConnector extends AbstractConnector implements NIOConnector { + public AbstractNIOConnector() { _buffers.setRequestBufferType(Type.DIRECT); _buffers.setRequestHeaderType(Type.INDIRECT); _buffers.setResponseBufferType(Type.DIRECT); _buffers.setResponseHeaderType(Type.INDIRECT); } - + /* ------------------------------------------------------------------------------- */ public boolean getUseDirectBuffers() { @@ -49,5 +45,4 @@ public abstract class AbstractNIOConnector extends AbstractConnector implements _buffers.setRequestBufferType(direct?Type.DIRECT:Type.INDIRECT); _buffers.setResponseBufferType(direct?Type.DIRECT:Type.INDIRECT); } - } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java index 9cf3ede1fef..c5618a6e97c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java @@ -19,7 +19,6 @@ import java.net.Socket; import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; -import java.util.Arrays; import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.io.AsyncEndPoint; @@ -32,9 +31,6 @@ import org.eclipse.jetty.io.nio.SelectorManager; import org.eclipse.jetty.io.nio.SelectorManager.SelectSet; import org.eclipse.jetty.server.AsyncHttpConnection; import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.ThreadPool; /* ------------------------------------------------------------------------------- */ @@ -65,8 +61,6 @@ import org.eclipse.jetty.util.thread.ThreadPool; */ public class SelectChannelConnector extends AbstractNIOConnector { - private static final Logger LOG = Log.getLogger(SelectChannelConnector.class); - protected ServerSocketChannel _acceptChannel; private int _lowResourcesConnections; private int _lowResourcesMaxIdleTime; @@ -126,7 +120,6 @@ public class SelectChannelConnector extends AbstractNIOConnector @Override public void customize(EndPoint endpoint, Request request) throws IOException { - AsyncEndPoint aEndp = ((AsyncEndPoint)endpoint); request.setTimeStamp(System.currentTimeMillis()); endpoint.setMaxIdleTime(_maxIdleTime); super.customize(endpoint, request); @@ -182,9 +175,8 @@ public class SelectChannelConnector extends AbstractNIOConnector _localPort=_acceptChannel.socket().getLocalPort(); if (_localPort<=0) throw new IOException("Server channel not bound"); - - addBean(_acceptChannel); + addBean(_acceptChannel); } } } @@ -259,17 +251,6 @@ public class SelectChannelConnector extends AbstractNIOConnector super.doStart(); } - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.server.server.AbstractConnector#doStop() - */ - @Override - protected void doStop() throws Exception - { - close(); - super.doStop(); - } - /* ------------------------------------------------------------ */ protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException { @@ -336,5 +317,4 @@ public class SelectChannelConnector extends AbstractNIOConnector return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey); } } - } From 3a30b4b7a59e5fda59e79d46f13927cff7b37a64 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 10 Jan 2012 17:44:57 +0100 Subject: [PATCH 07/18] 368240 - Better handling of locally created ThreadPool. --- .../org/eclipse/jetty/client/HttpClient.java | 53 ++++++++----------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index baad2e962f7..671806f4704 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -16,13 +16,11 @@ package org.eclipse.jetty.client; import java.io.IOException; import java.io.InputStream; import java.net.UnknownHostException; -import java.util.Arrays; import java.util.Enumeration; import java.util.LinkedList; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; - import javax.net.ssl.SSLContext; import org.eclipse.jetty.client.security.Authentication; @@ -99,7 +97,7 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri private AttributesMap _attributes=new AttributesMap(); - private final HttpBuffersImpl _buffers= new HttpBuffersImpl(); + private final HttpBuffersImpl _buffers= new HttpBuffersImpl(); /* ------------------------------------------------------------------------------- */ private void setBufferTypes() @@ -133,7 +131,6 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri _sslContextFactory = sslContextFactory; addBean(_sslContextFactory); addBean(_buffers); - setBufferTypes(); } /* ------------------------------------------------------------------------------- */ @@ -169,16 +166,6 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri */ public ThreadPool getThreadPool() { - if (_threadPool==null) - { - QueuedThreadPool pool = new QueuedThreadPool(); - pool.setMaxThreads(16); - pool.setDaemon(true); - pool.setName("HttpClient"); - _threadPool = pool; - addBean(_threadPool,true); - } - return _threadPool; } @@ -418,15 +405,21 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri _idleTimeoutQ.setDuration(_idleTimeout); _idleTimeoutQ.setNow(); - if (_threadPool == null) - getThreadPool(); + if (_threadPool==null) + { + QueuedThreadPool pool = new LocalQueuedThreadPool(); + pool.setMaxThreads(16); + pool.setDaemon(true); + pool.setName("HttpClient"); + _threadPool = pool; + addBean(_threadPool,true); + } - _connector=(_connectorType == CONNECTOR_SELECT_CHANNEL)?new SelectConnector(this):new SocketConnector(this); addBean(_connector,true); - + super.doStart(); - + _threadPool.dispatch(new Runnable() { public void run() @@ -439,7 +432,7 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri { Thread.sleep(200); } - catch (InterruptedException e) + catch (InterruptedException ignored) { } } @@ -447,25 +440,21 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri }); } - /* ------------------------------------------------------------ */ - long getNow() - { - return _timeoutQ.getNow(); - } - /* ------------------------------------------------------------ */ @Override protected void doStop() throws Exception { for (HttpDestination destination : _destinations.values()) - { destination.close(); - } _timeoutQ.cancelAll(); _idleTimeoutQ.cancelAll(); + super.doStop(); - _connector = null; + + if (_threadPool instanceof LocalQueuedThreadPool) + removeBean(_threadPool); + removeBean(_connector); } @@ -638,8 +627,6 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri _maxRedirects = redirects; } - - public int getRequestBufferSize() { return _buffers.getRequestBufferSize(); @@ -902,4 +889,8 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri { _sslContextFactory.setSecureRandomAlgorithm(secureRandomAlgorithm); } + + private static class LocalQueuedThreadPool extends QueuedThreadPool + { + } } From 74317987c4de990de9987455df77c2a0dc4dce89 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 10 Jan 2012 18:08:10 +0100 Subject: [PATCH 08/18] 368240 - Fixed test. --- .../jetty/monitor/AttrEventTriggerTest.java | 192 +++++++++--------- 1 file changed, 95 insertions(+), 97 deletions(-) diff --git a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java b/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java index 5cc7bdfd2d0..c9be35939cd 100644 --- a/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java +++ b/jetty-monitor/src/test/java/org/eclipse/jetty/monitor/AttrEventTriggerTest.java @@ -4,17 +4,15 @@ // 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.monitor; -import static org.junit.Assert.assertEquals; - import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -22,7 +20,6 @@ import java.lang.management.ManagementFactory; import java.util.Collection; import java.util.Iterator; import java.util.TreeSet; - import javax.management.MBeanServer; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -35,13 +32,12 @@ import org.eclipse.jetty.client.security.SimpleRealmResolver; import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.jmx.MBeanContainer; -import org.eclipse.jetty.monitor.JMXMonitor; import org.eclipse.jetty.monitor.jmx.ConsoleNotifier; import org.eclipse.jetty.monitor.jmx.EventNotifier; import org.eclipse.jetty.monitor.jmx.EventState; +import org.eclipse.jetty.monitor.jmx.EventState.TriggerState; import org.eclipse.jetty.monitor.jmx.EventTrigger; import org.eclipse.jetty.monitor.jmx.MonitorAction; -import org.eclipse.jetty.monitor.jmx.EventState.TriggerState; import org.eclipse.jetty.monitor.triggers.AndEventTrigger; import org.eclipse.jetty.monitor.triggers.AttrEventTrigger; import org.eclipse.jetty.monitor.triggers.EqualToAttrEventTrigger; @@ -61,6 +57,8 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; + /* ------------------------------------------------------------ */ /** @@ -81,93 +79,93 @@ public class AttrEventTriggerTest File docRoot = new File("target/test-output/docroot/"); docRoot.mkdirs(); docRoot.deleteOnExit(); - + System.setProperty("org.eclipse.jetty.util.log.DEBUG",""); _server = new Server(); - + SelectChannelConnector connector = new SelectChannelConnector(); _server.addConnector(connector); - + _handler = new TestHandler(); _server.setHandler(_handler); - + MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer); mBeanContainer.addBean(Log.getLog()); _counter = _handler.getRequestCounter(); mBeanContainer.addBean(_counter); - - _server.addBean(mBeanContainer); - _server.getContainer().addEventListener(mBeanContainer); + + _server.addBean(mBeanContainer, true); + _server.getContainer().addEventListener(mBeanContainer); _server.start(); - + startClient(null); - + _monitor = new JMXMonitor(); - - int port = _server.getConnectors()[0].getLocalPort(); + + int port = connector.getLocalPort(); _requestUrl = "http://localhost:"+port+ "/"; } - + @After public void tearDown() throws Exception { stopClient(); - + if (_server != null) { _server.stop(); _server = null; - } + } } - + @Test public void testNoCondition() throws Exception { long requestCount = 10; - - AttrEventTrigger trigger = + + AttrEventTrigger trigger = new AttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter"); EventNotifier notifier = new ConsoleNotifier("%s"); CounterAction action = new CounterAction(trigger, notifier, 500, 100); - + performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(1,requestCount); assertEquals(result, action.getHits()); } - + @Test public void testEqual_TRUE() throws Exception { long requestCount = 10; long testValue = 5; - - EqualToAttrEventTrigger trigger = + + EqualToAttrEventTrigger trigger = new EqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter",testValue); EventNotifier notifier = new ConsoleNotifier("%s"); CounterAction action = new CounterAction(trigger, notifier, 500, 100); performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(testValue); assertEquals(result, action.getHits()); } - + @Test public void testEqual_FALSE() throws Exception { long requestCount = 10; long testValue = 11; - - EqualToAttrEventTrigger trigger = + + EqualToAttrEventTrigger trigger = new EqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testValue); @@ -175,19 +173,19 @@ public class AttrEventTriggerTest CounterAction action = new CounterAction(trigger, notifier, 500, 100); performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(); assertEquals(result, action.getHits()); } - + @Test public void testLowerLimit() throws Exception { long requestCount = 10; long testRangeLow = 5; - - GreaterThanAttrEventTrigger trigger = + + GreaterThanAttrEventTrigger trigger = new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeLow); @@ -195,27 +193,27 @@ public class AttrEventTriggerTest CounterAction action = new CounterAction(trigger, notifier, 500, 100); performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(6,10); assertEquals(result, action.getHits()); } - + @Test public void testLowerLimitIncl() throws Exception { long requestCount = 10; long testRangeLow = 5; - - GreaterThanOrEqualToAttrEventTrigger trigger = + + GreaterThanOrEqualToAttrEventTrigger trigger = new GreaterThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeLow); - + EventNotifier notifier = new ConsoleNotifier("%s"); CounterAction action = new CounterAction(trigger, notifier, 500, 100); - + performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(5,10); assertEquals(result, action.getHits()); } @@ -226,8 +224,8 @@ public class AttrEventTriggerTest { long requestCount = 10; long testRangeHigh = 5; - - LessThanAttrEventTrigger trigger = + + LessThanAttrEventTrigger trigger = new LessThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeHigh); @@ -235,11 +233,11 @@ public class AttrEventTriggerTest CounterAction action = new CounterAction(trigger, notifier, 500, 100); performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(1,4); assertEquals(result, action.getHits()); } - + @Test public void testUpperLimitIncl() @@ -247,8 +245,8 @@ public class AttrEventTriggerTest { long requestCount = 10; long testRangeHigh = 5; - - LessThanOrEqualToAttrEventTrigger trigger = + + LessThanOrEqualToAttrEventTrigger trigger = new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeHigh); @@ -256,11 +254,11 @@ public class AttrEventTriggerTest CounterAction action = new CounterAction(trigger, notifier, 500, 100); performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(1,5); assertEquals(result, action.getHits()); } - + @Test public void testRangeInclusive() throws Exception @@ -268,20 +266,20 @@ public class AttrEventTriggerTest long requestCount = 10; long testRangeLow = 3; long testRangeHigh = 8; - - RangeInclAttrEventTrigger trigger = + + RangeInclAttrEventTrigger trigger = new RangeInclAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeLow, testRangeHigh); - + EventNotifier notifier = new ConsoleNotifier("%s"); CounterAction action = new CounterAction(trigger, notifier, 500, 100); - + performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(testRangeLow,testRangeHigh); assertEquals(result, action.getHits()); } - + @Test public void testInsideRangeExclusive() throws Exception @@ -289,20 +287,20 @@ public class AttrEventTriggerTest long requestCount = 10; long testRangeLow = 3; long testRangeHigh = 8; - - RangeAttrEventTrigger trigger = + + RangeAttrEventTrigger trigger = new RangeAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeLow, testRangeHigh); - + EventNotifier notifier = new ConsoleNotifier("%s"); CounterAction action = new CounterAction(trigger, notifier, 500, 100); - + performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh-1); assertEquals(result, action.getHits()); } - + @Test public void testRangeComposite() throws Exception @@ -310,23 +308,23 @@ public class AttrEventTriggerTest long requestCount = 10; long testRangeLow = 4; long testRangeHigh = 7; - - GreaterThanAttrEventTrigger trigger1 = + + GreaterThanAttrEventTrigger trigger1 = new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeLow); - LessThanOrEqualToAttrEventTrigger trigger2 = + LessThanOrEqualToAttrEventTrigger trigger2 = new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeHigh); AndEventTrigger trigger = new AndEventTrigger(trigger1, trigger2); EventNotifier notifier = new ConsoleNotifier("%s"); CounterAction action = new CounterAction(trigger, notifier, 500, 100); - + performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(testRangeLow+1,testRangeHigh); assertEquals(result, action.getHits()); } - + @Test public void testRangeOuter() throws Exception @@ -334,23 +332,23 @@ public class AttrEventTriggerTest long requestCount = 10; long testRangeLow = 4; long testRangeHigh = 7; - - LessThanOrEqualToAttrEventTrigger trigger1 = + + LessThanOrEqualToAttrEventTrigger trigger1 = new LessThanOrEqualToAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeLow); - GreaterThanAttrEventTrigger trigger2 = + GreaterThanAttrEventTrigger trigger2 = new GreaterThanAttrEventTrigger("org.eclipse.jetty.monitor:type=requestcounter,id=0", "counter", testRangeHigh); OrEventTrigger trigger = new OrEventTrigger(trigger1, trigger2); EventNotifier notifier = new ConsoleNotifier("%s"); CounterAction action = new CounterAction(trigger, notifier, 500, 100); - + performTest(action, requestCount, 1000); - + ResultSet result = new ResultSet(1,testRangeLow,testRangeHigh+1, requestCount); assertEquals(result, action.getHits()); } - + protected void performTest(MonitorAction action, long count, long interval) throws Exception { @@ -363,17 +361,17 @@ public class AttrEventTriggerTest ContentExchange getExchange = new ContentExchange(); getExchange.setURL(_requestUrl); getExchange.setMethod(HttpMethods.GET); - + _client.send(getExchange); int state = getExchange.waitForDone(); - + String content = ""; int responseStatus = getExchange.getResponseStatus(); if (responseStatus == HttpStatus.OK_200) { content = getExchange.getResponseContent(); - } - + } + assertEquals(HttpStatus.OK_200,responseStatus); Thread.sleep(interval); } @@ -382,12 +380,12 @@ public class AttrEventTriggerTest break; } } - + Thread.sleep(interval); _monitor.removeActions(action); } - + protected void startClient(Realm realm) throws Exception { @@ -397,7 +395,7 @@ public class AttrEventTriggerTest _client.setRealmResolver(new SimpleRealmResolver(realm)); _client.start(); } - + protected void stopClient() throws Exception { @@ -412,7 +410,7 @@ public class AttrEventTriggerTest extends AbstractHandler { private RequestCounter _counter = new RequestCounter(); - + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException @@ -421,40 +419,40 @@ public class AttrEventTriggerTest return; } _counter.increment(); - + response.setContentType("text/plain"); response.setStatus(HttpServletResponse.SC_OK); PrintWriter writer = response.getWriter(); writer.println("===TEST RESPONSE==="); baseRequest.setHandled(true); } - + public RequestCounter getRequestCounter() { return _counter; } } - + protected static class ResultSet extends TreeSet - { + { public ResultSet() {} - + public ResultSet(long value) { add(value); } - + public ResultSet(long start, long end) { addEntries(start, end); } - + public ResultSet(long start, long pause, long resume, long end) { addEntries(start, pause); addEntries(resume, end); } - + public void addEntries(long start, long stop) { if (start > 0 && stop > 0) @@ -471,23 +469,23 @@ public class AttrEventTriggerTest return (this.size() == set.size()) && containsAll(set); } } - + protected static class CounterAction extends MonitorAction { private ResultSet _hits = new ResultSet(); - + public CounterAction(EventTrigger trigger, EventNotifier notifier, long interval, long delay) { super(trigger, notifier, interval, delay); } - + public void execute(EventTrigger trigger, EventState state, long timestamp) { if (trigger != null && state != null) { Collection values = state.values(); - + Iterator it = values.iterator(); while(it.hasNext()) { @@ -500,7 +498,7 @@ public class AttrEventTriggerTest } } } - + public ResultSet getHits() { return _hits; From cecfa69a1387822980a51912dcc4a05bb556564c Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 10 Jan 2012 18:10:24 +0100 Subject: [PATCH 09/18] 368189 - WebSocketClientFactory should not manage external thread pool. 368240 - Improve AggregateLifeCycle handling of shared lifecycles Reworked the implementation in order to follow 368240. --- .../jetty/websocket/WebSocketClientFactory.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java index c7c73bc6524..e0ef62e2306 100644 --- a/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java +++ b/jetty-websocket/src/main/java/org/eclipse/jetty/websocket/WebSocketClientFactory.java @@ -45,7 +45,6 @@ import org.eclipse.jetty.io.nio.SslConnection; import org.eclipse.jetty.util.B64Code; import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -68,7 +67,6 @@ public class WebSocketClientFactory extends AggregateLifeCycle private final Queue connections = new ConcurrentLinkedQueue(); private final SslContextFactory _sslContextFactory = new SslContextFactory(); private final ThreadPool _threadPool; - private final boolean _shutdownThreadPool; private final WebSocketClientSelector _selector; private MaskGen _maskGen; private WebSocketBuffers _buffers; @@ -117,16 +115,9 @@ public class WebSocketClientFactory extends AggregateLifeCycle public WebSocketClientFactory(ThreadPool threadPool, MaskGen maskGen, int bufferSize) { if (threadPool == null) - { - _threadPool = new QueuedThreadPool(); - addBean(_threadPool); - _shutdownThreadPool = true; - } - else - { - _threadPool = threadPool; - _shutdownThreadPool = false; - } + threadPool = new QueuedThreadPool(); + _threadPool = threadPool; + addBean(_threadPool); _buffers = new WebSocketBuffers(bufferSize); addBean(_buffers); @@ -224,8 +215,6 @@ public class WebSocketClientFactory extends AggregateLifeCycle { closeConnections(); super.doStop(); - if (_shutdownThreadPool && _threadPool instanceof LifeCycle) - ((LifeCycle)_threadPool).stop(); } /* ------------------------------------------------------------ */ From b6f5edecb59b90a4992b33b01229656fd9ae6344 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 10 Jan 2012 19:02:48 +0100 Subject: [PATCH 10/18] 368240 - Better handling of locally created ThreadPool. Forgot to null out field. --- .../src/main/java/org/eclipse/jetty/client/HttpClient.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index 671806f4704..c52c25c858c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -453,7 +453,10 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri super.doStop(); if (_threadPool instanceof LocalQueuedThreadPool) + { removeBean(_threadPool); + _threadPool = null; + } removeBean(_connector); } From 49b3239aa66e0eb38dda73caaff22f2b615df170 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Tue, 10 Jan 2012 13:45:39 -0600 Subject: [PATCH 11/18] clear up the last of the maven warnings I see --- jetty-jndi/pom.xml | 1 - jetty-nosql/pom.xml | 1 - jetty-osgi/jetty-osgi-equinoxtools/pom.xml | 9 --------- jetty-osgi/test-jetty-osgi/pom.xml | 10 ---------- jetty-server/pom.xml | 1 - tests/test-webapps/test-webapp-rfc2616/pom.xml | 1 - 6 files changed, 23 deletions(-) diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 5eaf6fef291..bd9764512d6 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -66,7 +66,6 @@ javax.mail mail - ${javax-mail-version} javax.activation diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 75b77f019a9..43b99da8fe2 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -68,7 +68,6 @@ junit junit - ${junit4-version} test diff --git a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml index fbb16968697..665b3af9679 100644 --- a/jetty-osgi/jetty-osgi-equinoxtools/pom.xml +++ b/jetty-osgi/jetty-osgi-equinoxtools/pom.xml @@ -10,27 +10,20 @@ Jetty :: OSGi :: Example Equinox Tools Jetty OSGi Example Equinox Tools - v20110513 - 7.4.1.v20110513 - 3.6.0.v20100517 - 3.2.100.v20100503 ${project.groupId}.equinoxtools org.eclipse.jetty jetty-webapp - ${project.version} org.eclipse.jetty jetty-continuation - ${project.version} org.eclipse.jetty jetty-websocket - ${project.version} org.eclipse.jetty @@ -39,12 +32,10 @@ org.eclipse.osgi org.eclipse.osgi - ${osgi-version} org.eclipse.osgi org.eclipse.osgi.services - ${osgi-services-version} diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index f2a0795b5db..eedcb97f358 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -48,13 +48,11 @@ org.eclipse.jetty jetty-webapp - ${project.version} runtime org.eclipse.jetty jetty-deploy - ${project.version} runtime @@ -66,7 +64,6 @@ org.eclipse.jetty jetty-servlet - ${project.version} runtime @@ -78,13 +75,11 @@ org.eclipse.jetty jetty-jmx - ${project.version} runtime org.eclipse.jetty jetty-util - ${project.version} runtime @@ -96,7 +91,6 @@ org.eclipse.jetty jetty-websocket - ${project.version} runtime - - junit.framework.Assert - junit.framework.TestCase - - - junit - junit - - - org.eclipse.jdt.core.compiler - ecj - - ecj - - - org.mortbay.jetty - jsp-2.1-glassfish - - - - - ch.qos.logback - logback-core - - ch.qos.logback.core.joran.JoranConfiguratorBase - - liblogback-java - - - - org.apache.geronimo.specs - geronimo-jaspic_1.0_spec - - - - - org.eclipse.equinox.http - servlet - eclipse-platform - - - org.eclipse.osgi - services - - - - - org.apache.geronimo.specs - geronimo-jta_1.1_spec - libgeronimo-jta-1.1-spec-1.1.1-java - - - - org.eclipse - osgi - - org.osgi.framework.BundleContext - - - - - - org.slf4j - jcl-over-slf4j - libslf4j-java - - - - asm - asm-commons - libasm3-java - - - - ant - ant - ant - ant - - - asm - asm - libasm3-java - - - - asm - asm-tree - libasm3-java - - - - javax.mail - mail - - javax.mail.Authenticator - javax.mail.PasswordAuthentication - javax.mail.Session - - libgnumail-java - sun-mail - - - org.apache.geronimo.specs - geronimo-annotation_1.0_spec - - - - - org.slf4j - log4j-over-slf4j - libslf4j-java - - - - org.testng - testng - testng - - - - org.mortbay.jetty - servlet-api - 3.0.20100224 - - javax.servlet.AsyncContext - javax.servlet.AsyncEvent - javax.servlet.AsyncListener - - - - - - org.slf4j - slf4j-api - - org.slf4j.Logger - - libslf4j-java - - - - org.mortbay.jetty - jetty-util - - - - - javax.activation - activation - libgnujav-java - sun-jaf - - - - - jetty-annotations - jetty-jaspi - jetty-plus - example-jetty-embedded - test-continuation - test-continuation-jetty6 - test-jetty-servlet - - - - jetty-osgi - jetty-osgi-boot - jetty-osgi-boot-jsp - jetty-osgi-boot-logback - jetty-osgi-boot-warurl - jetty-httpservice - - - - jetty-server - jetty-client - jetty-servlet - jetty-webapp - jetty-plus - jetty-all-server - jetty-all - - - test-sessions-common - test-jdbc-sessions - test-hash-sessions - test-integration - test-webapp-rfc2616 - - - - debian/jetty.init - rpm/jetty.init - - - From 2d999a157bc051b79e01cd4724d8f50cc96dca07 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 11 Jan 2012 11:02:36 +1100 Subject: [PATCH 13/18] 368291 Change warning to info for NoSuchFieldException on BeanELResolver.properties --- .../org/eclipse/jetty/servlet/listener/ELContextCleaner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java index 285de0f3035..19c035e5173 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/listener/ELContextCleaner.java @@ -76,7 +76,7 @@ public class ELContextCleaner implements ServletContextListener } catch (NoSuchFieldException e) { - LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e); + LOG.info("Not cleaning cached beans: no such field javax.el.BeanELResolver.properties"); } } From cb22cfdbe51d024718288c9f4092d0be7ac08fa6 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 11:06:14 +1100 Subject: [PATCH 14/18] 368240: renamed to use manage/unmanage instead of join/disjoin --- .../org/eclipse/jetty/client/HttpClient.java | 4 +- .../jetty/deploy/DeploymentManager.java | 6 ++ .../jetty/server/AbstractConnector.java | 5 + .../server/ssl/SslSelectChannelConnector.java | 6 ++ .../util/component/AggregateLifeCycle.java | 94 ++++++++----------- .../component/AggregateLifeCycleTest.java | 14 +-- 6 files changed, 65 insertions(+), 64 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index c52c25c858c..0b5581ed984 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -170,7 +170,9 @@ public class HttpClient extends AggregateLifeCycle implements HttpBuffers, Attri } /* ------------------------------------------------------------ */ - /** + /** Set the ThreadPool. + * The threadpool passed is added via {@link #addBean(Object)} so that + * it's lifecycle may be managed as a {@link AggregateLifeCycle}. * @param threadPool the threadPool to set */ public void setThreadPool(ThreadPool threadPool) diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java index fb8e1a5d36b..afe06a80e1f 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java @@ -139,6 +139,12 @@ public class DeploymentManager extends AggregateLifeCycle } } + /* ------------------------------------------------------------ */ + /** Set the AppProviders. + * The providers passed are added via {@link #addBean(Object)} so that + * their lifecycles may be managed as a {@link AggregateLifeCycle}. + * @param providers + */ public void setAppProviders(Collection providers) { if (isRunning()) 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 7a95f4d5fd2..2dd058a615a 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 @@ -127,6 +127,11 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Ht } /* ------------------------------------------------------------ */ + /** Set the ThreadPool. + * The threadpool passed is added via {@link #addBean(Object)} so that + * it's lifecycle may be managed as a {@link AggregateLifeCycle}. + * @param threadPool the threadPool to set + */ public void setThreadPool(ThreadPool pool) { removeBean(_threadPool); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java index e7746cbb5c6..de82d510de1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ssl/SslSelectChannelConnector.java @@ -33,6 +33,7 @@ import org.eclipse.jetty.io.nio.AsyncConnection; import org.eclipse.jetty.io.nio.SslConnection; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.ssl.SslContextFactory; /* ------------------------------------------------------------ */ @@ -54,6 +55,11 @@ public class SslSelectChannelConnector extends SelectChannelConnector implements } /* ------------------------------------------------------------ */ + /** Construct with explicit SslContextFactory. + * The SslContextFactory passed is added via {@link #addBean(Object)} so that + * it's lifecycle may be managed with {@link AggregateLifeCycle}. + * @param sslContextFactory + */ public SslSelectChannelConnector(SslContextFactory sslContextFactory) { _sslContextFactory = sslContextFactory; diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java index 75e4a50253b..05448362f92 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AggregateLifeCycle.java @@ -14,18 +14,22 @@ import org.eclipse.jetty.util.log.Logger; /** * An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans. *

- * Beans can be added the AggregateLifeCycle either as joined beans, as disjoint beans. A joined bean is started, stopped and destroyed with the aggregate. - * A disjointed bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally. + * Beans can be added the AggregateLifeCycle either as managed beans or as unmanaged beans. A managed bean is started, stopped and destroyed with the aggregate. + * An umanaged bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally. *

- * When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be a disjoined bean. - * Otherwise the methods {@link #addBean(LifeCycle, boolean)}, {@link #join(LifeCycle)} and {@link #disjoin(LifeCycle)} can be used to + * When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be an unmanaged bean. + * Otherwise the methods {@link #addBean(LifeCycle, boolean)}, {@link #manage(LifeCycle)} and {@link #unmanage(LifeCycle)} can be used to * explicitly control the life cycle relationship. *

+ * If adding a bean that is shared between multiple {@link AggregateLifeCycle} instances, then it should be started before being added, so it is unmanged, or + * the API must be used to explicitly set it as unmanaged. + *

*/ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable { private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class); private final List _beans=new CopyOnWriteArrayList(); + private boolean _started=false; private class Bean { @@ -34,12 +38,12 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable _bean=b; } final Object _bean; - volatile boolean _joined=true; + volatile boolean _managed=true; } /* ------------------------------------------------------------ */ /** - * Start the joined lifecycle beans in the order they were added. + * Start the managed lifecycle beans in the order they were added. * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() */ @Override @@ -47,13 +51,15 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable { for (Bean b:_beans) { - if (b._joined && b._bean instanceof LifeCycle) + if (b._managed && b._bean instanceof LifeCycle) { LifeCycle l=(LifeCycle)b._bean; if (!l.isRunning()) l.start(); } } + // indicate that we are started, so that addBean will start other beans added. + _started=true; super.doStart(); } @@ -65,12 +71,13 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable @Override protected void doStop() throws Exception { + _started=false; super.doStop(); List reverse = new ArrayList(_beans); Collections.reverse(reverse); for (Bean b:reverse) { - if (b._joined && b._bean instanceof LifeCycle) + if (b._managed && b._bean instanceof LifeCycle) { LifeCycle l=(LifeCycle)b._bean; if (l.isRunning()) @@ -91,7 +98,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable Collections.reverse(reverse); for (Bean b:reverse) { - if (b._bean instanceof Destroyable && b._joined) + if (b._bean instanceof Destroyable && b._managed) { Destroyable d=(Destroyable)b._bean; d.destroy(); @@ -119,76 +126,51 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable * @param bean * @return True if the aggregate contains the bean and it is joined */ - public boolean isJoined(Object bean) + public boolean isManaged(Object bean) { for (Bean b:_beans) if (b._bean==bean) - return b._joined; + return b._managed; return false; } /* ------------------------------------------------------------ */ /** * Add an associated bean. - * If the bean is a {@link LifeCycle}, it is added as neither joined or disjoint and - * that status will be determined when the Aggregate bean is started. + * If the bean is a {@link LifeCycle}, then it will be managed if it is not + * already started and umanaged if it is already started. The {@link #addBean(Object, boolean)} + * method should be used if this is not correct, or the {@link #manage(Object)} and {@link #unmanage(Object)} + * methods may be used after an add to change the status. * @param o the bean object to add * @return true if the bean was added or false if it has already been added. */ public boolean addBean(Object o) { - if (contains(o)) - return false; - - Bean b = new Bean(o); - _beans.add(b); - - // extra LifeCycle handling - if (o instanceof LifeCycle) - { - LifeCycle l=(LifeCycle)o; - - // If it is running, then assume it is disjoint - if (l.isRunning()) - b._joined=false; - - // else if we are running, then start the bean - else if (isRunning()) - { - try - { - l.start(); - } - catch(Exception e) - { - throw new RuntimeException (e); - } - } - } - - return true; + // beans are joined unless they are started lifecycles + return addBean(o,!((o instanceof LifeCycle)&&((LifeCycle)o).isStarted())); } /* ------------------------------------------------------------ */ /** Add an associated lifecycle. * @param o The lifecycle to add - * @param joined True if the LifeCycle is to be joined, otherwise it will be disjoint. + * @param managed True if the LifeCycle is to be joined, otherwise it will be disjoint. * @return */ - public boolean addBean(Object o, boolean joined) + public boolean addBean(Object o, boolean managed) { if (contains(o)) return false; Bean b = new Bean(o); - b._joined=joined; + b._managed=managed; _beans.add(b); if (o instanceof LifeCycle) { LifeCycle l=(LifeCycle)o; - if (joined && isStarted()) + // Start the bean if we are started + if (managed && _started) { try { @@ -205,17 +187,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable /* ------------------------------------------------------------ */ /** - * Join a bean to this aggregate, so that it is started/stopped/destroyed with the + * Manage a bean by this aggregate, so that it is started/stopped/destroyed with the * aggregate lifecycle. - * @param bean The bean to join (must already have been added). + * @param bean The bean to manage (must already have been added). */ - public void join(Object bean) + public void manage(Object bean) { for (Bean b :_beans) { if (b._bean==bean) { - b._joined=true; + b._managed=true; return; } } @@ -224,17 +206,17 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable /* ------------------------------------------------------------ */ /** - * Disjoin a bean to this aggregate, so that it is not started/stopped/destroyed with the + * Unmanage a bean by this aggregate, so that it is not started/stopped/destroyed with the * aggregate lifecycle. - * @param bean The bean to join (must already have been added). + * @param bean The bean to manage (must already have been added). */ - public void disjoin(Object bean) + public void unmanage(Object bean) { for (Bean b :_beans) { if (b._bean==bean) { - b._joined=false; + b._managed=false; return; } } @@ -372,7 +354,7 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable { i++; - if (b._joined) + if (b._managed) { out.append(indent).append(" +- "); if (b._bean instanceof Dumpable) diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java index 2b5ec8d6e86..495c6fd587f 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/component/AggregateLifeCycleTest.java @@ -149,7 +149,7 @@ public class AggregateLifeCycleTest // Now add it a0.addBean(a1); - Assert.assertFalse(a0.isJoined(a1)); + Assert.assertFalse(a0.isManaged(a1)); a0.start(); Assert.assertEquals(1,started.get()); @@ -176,8 +176,8 @@ public class AggregateLifeCycleTest Assert.assertEquals(1,stopped.get()); Assert.assertEquals(0,destroyed.get()); - a0.join(a1); - Assert.assertTrue(a0.isJoined(a1)); + a0.manage(a1); + Assert.assertTrue(a0.isManaged(a1)); a0.stop(); Assert.assertEquals(1,started.get()); @@ -196,8 +196,8 @@ public class AggregateLifeCycleTest Assert.assertEquals(0,destroyed.get()); - a0.disjoin(a1); - Assert.assertFalse(a0.isJoined(a1)); + a0.unmanage(a1); + Assert.assertFalse(a0.isManaged(a1)); a0.destroy(); Assert.assertEquals(2,started.get()); @@ -262,8 +262,8 @@ public class AggregateLifeCycleTest a0.dumpStdErr(); System.err.println("--"); - a0.disjoin(aa); - a2.disjoin(aa0); + a0.unmanage(aa); + a2.unmanage(aa0); a0.dumpStdErr(); } From d66f45f2daef85c71a1d5d8e4987036fb8f871d9 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 11:16:31 +1100 Subject: [PATCH 15/18] 368240: renamed to use manage/unmanage instead of join/disjoin --- .../main/java/org/eclipse/jetty/client/SelectConnector.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java index 363349d150e..e1c282e74db 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/SelectConnector.java @@ -48,7 +48,8 @@ class SelectConnector extends AggregateLifeCycle implements HttpClient.Connector /* ------------------------------------------------------------ */ /** - * @param httpClient the HttpClient this connector is associated to + * @param httpClient the HttpClient this connector is associated to. It is + * added via the {@link #addBean(Object, boolean)} as an unmanaged bean. */ SelectConnector(HttpClient httpClient) { From d0b81a185c260ffceecb9d7470b3ddfbfeda4c11 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 11:51:04 +1100 Subject: [PATCH 16/18] 367638: 361316: protected multipart filter from DoS --- .../jetty/server/handler/ContextHandler.java | 5 ++++- .../org/eclipse/jetty/servlets/MultiPartFilter.java | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 3538d75f96d..f827bdd9c68 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -75,7 +75,10 @@ import org.eclipse.jetty.util.resource.Resource; *

* If the context init parameter "org.eclipse.jetty.server.context.ManagedAttributes" is set to a comma separated list of names, then they are treated as * context attribute names, which if set as attributes are passed to the servers Container so that they may be managed with JMX. - * + *

+ * The maximum size of a form that can be processed by this context is controlled by the system properties org.eclipse.jetty.server.Request.maxFormKeys + * and org.eclipse.jetty.server.Request.maxFormContentSize. These can also be configured with {@link #setMaxFormContentSize(int)} and {@link #setMaxFormKeys(int)} + * * @org.apache.xbean.XBean description="Creates a basic HTTP context" */ public class ContextHandler extends ScopedHandler implements Attributes, Server.Graceful diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java index 049f37072b1..a2dd4492ed1 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/MultiPartFilter.java @@ -59,6 +59,13 @@ import org.eclipse.jetty.util.TypeUtil; *

* If the init parameter "delete" is set to "true", any files created will be deleted when the * current request returns. + *

+ * The init parameter maxFormKeys sets the maximum number of keys that may be present in a + * form (default set by system property org.eclipse.jetty.server.Request.maxFormKeys or 1000) to protect + * against DOS attacks by bad hash keys. + *

+ * The init parameter deleteFiles controls if uploaded files are automatically deleted after the request + * completes. * */ public class MultiPartFilter implements Filter @@ -69,6 +76,7 @@ public class MultiPartFilter implements Filter private boolean _deleteFiles; private ServletContext _context; private int _fileOutputBuffer = 0; + private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys",1000).intValue(); /* ------------------------------------------------------------------------------- */ /** @@ -82,6 +90,9 @@ public class MultiPartFilter implements Filter if(fileOutputBuffer!=null) _fileOutputBuffer = Integer.parseInt(fileOutputBuffer); _context=filterConfig.getServletContext(); + String mfks = filterConfig.getInitParameter("maxFormKeys"); + if (mfks!=null) + _maxFormKeys=Integer.parseInt(mfks); } /* ------------------------------------------------------------------------------- */ @@ -134,7 +145,7 @@ public class MultiPartFilter implements Filter String content_transfer_encoding=null; - outer:while(!lastPart) + outer:while(!lastPart && params.size()<_maxFormKeys) { String type_content=null; From 2d24eb824070b85baf217da0db3d4777ca19d511 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 12:17:26 +1100 Subject: [PATCH 17/18] 368191: fixed numerical overflow converting seconds to ms --- .../org/eclipse/jetty/nosql/NoSqlSession.java | 2 +- .../jetty/server/handler/DefaultHandler.java | 2 +- .../jetty/server/session/AbstractSession.java | 4 ++-- .../server/session/HashSessionManager.java | 24 +++++++++---------- .../jetty/server/session/HashedSession.java | 2 +- .../server/session/JDBCSessionIdManager.java | 4 ++-- .../server/session/JDBCSessionManager.java | 18 +++++++------- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSession.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSession.java index 76f85ae8a5c..63ac8212242 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSession.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSession.java @@ -79,7 +79,7 @@ public class NoSqlSession extends AbstractSession __log.debug("NoSqlSession:access:active "+_active); if (_active.incrementAndGet()==1) { - int period=_manager.getStalePeriod()*1000; + long period=_manager.getStalePeriod()*1000L; if (period==0) refresh(); else if (period>0) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java index 6ac3dcc2ff2..dba7f5bd117 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java @@ -50,7 +50,7 @@ public class DefaultHandler extends AbstractHandler { private static final Logger LOG = Log.getLogger(DefaultHandler.class); - final long _faviconModified=(System.currentTimeMillis()/1000)*1000; + final long _faviconModified=(System.currentTimeMillis()/1000)*1000L; byte[] _favicon; boolean _serveIcon=true; boolean _showContexts=true; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java index 73a4b6f81b8..690c917393b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java @@ -62,7 +62,7 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI _accessed=_created; _lastAccessed=_created; _requests=1; - _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000:-1; + _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1; if (LOG.isDebugEnabled()) LOG.debug("new session & id "+_nodeId+" "+_clusterId); } @@ -430,7 +430,7 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI /* ------------------------------------------------------------- */ public void setMaxInactiveInterval(int secs) { - _maxIdleMs=(long)secs*1000; + _maxIdleMs=(long)secs*1000L; } /* ------------------------------------------------------------- */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java index 3b59213b516..04cf643c21c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java @@ -53,9 +53,9 @@ public class HashSessionManager extends AbstractSessionManager private Timer _timer; private boolean _timerStop=false; private TimerTask _task; - int _scavengePeriodMs=30000; - int _savePeriodMs=0; //don't do period saves by default - int _idleSavePeriodMs = 0; // don't idle save sessions by default. + long _scavengePeriodMs=30000; + long _savePeriodMs=0; //don't do period saves by default + long _idleSavePeriodMs = 0; // don't idle save sessions by default. private TimerTask _saveTask; File _storeDir; private boolean _lazyLoad=false; @@ -134,7 +134,7 @@ public class HashSessionManager extends AbstractSessionManager */ public int getScavengePeriod() { - return _scavengePeriodMs/1000; + return (int)(_scavengePeriodMs/1000); } @@ -160,7 +160,7 @@ public class HashSessionManager extends AbstractSessionManager if (_idleSavePeriodMs <= 0) return 0; - return _idleSavePeriodMs / 1000; + return (int)(_idleSavePeriodMs / 1000); } /* ------------------------------------------------------------ */ @@ -174,7 +174,7 @@ public class HashSessionManager extends AbstractSessionManager */ public void setIdleSavePeriod(int seconds) { - _idleSavePeriodMs = seconds * 1000; + _idleSavePeriodMs = seconds * 1000L; } /* ------------------------------------------------------------ */ @@ -182,7 +182,7 @@ public class HashSessionManager extends AbstractSessionManager public void setMaxInactiveInterval(int seconds) { super.setMaxInactiveInterval(seconds); - if (_dftMaxIdleSecs>0&&_scavengePeriodMs>_dftMaxIdleSecs*1000) + if (_dftMaxIdleSecs>0&&_scavengePeriodMs>_dftMaxIdleSecs*1000L) setScavengePeriod((_dftMaxIdleSecs+9)/10); } @@ -192,7 +192,7 @@ public class HashSessionManager extends AbstractSessionManager */ public void setSavePeriod (int seconds) { - int period = (seconds * 1000); + long period = (seconds * 1000L); if (period < 0) period=0; _savePeriodMs=period; @@ -235,7 +235,7 @@ public class HashSessionManager extends AbstractSessionManager if (_savePeriodMs<=0) return 0; - return _savePeriodMs/1000; + return (int)(_savePeriodMs/1000); } /* ------------------------------------------------------------ */ @@ -247,8 +247,8 @@ public class HashSessionManager extends AbstractSessionManager if (seconds==0) seconds=60; - int old_period=_scavengePeriodMs; - int period=seconds*1000; + long old_period=_scavengePeriodMs; + long period=seconds*1000L; if (period>60000) period=60000; if (period<1000) @@ -297,7 +297,7 @@ public class HashSessionManager extends AbstractSessionManager for (Iterator i=_sessions.values().iterator(); i.hasNext();) { HashedSession session=i.next(); - long idleTime=session.getMaxInactiveInterval()*1000; + long idleTime=session.getMaxInactiveInterval()*1000L; if (idleTime>0&&session.getAccessed()+idleTime0&&(getMaxInactiveInterval()*1000/10)<_hashSessionManager._scavengePeriodMs) + if (getMaxInactiveInterval()>0&&(getMaxInactiveInterval()*1000L/10)<_hashSessionManager._scavengePeriodMs) _hashSessionManager.setScavengePeriod((secs+9)/10); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java index 5280023e7d1..1647372f198 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java @@ -69,7 +69,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager protected Timer _timer; //scavenge timer protected TimerTask _task; //scavenge task protected long _lastScavengeTime; - protected long _scavengeIntervalMs = 1000 * 60 * 10; //10mins + protected long _scavengeIntervalMs = 1000L * 60 * 10; //10mins protected String _blobType; //if not set, is deduced from the type of the database at runtime protected String _createSessionIdTable; @@ -245,7 +245,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager sec=60; long old_period=_scavengeIntervalMs; - long period=sec*1000; + long period=sec*1000L; _scavengeIntervalMs=period; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java index bcf443eb8d4..931ff5d4484 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java @@ -277,11 +277,11 @@ public class JDBCSessionManager extends AbstractSessionManager super(JDBCSessionManager.this,request); _data = new SessionData(getClusterId(),_jdbcAttributes); if (_dftMaxIdleSecs>0) - _data.setMaxIdleMs(_dftMaxIdleSecs*1000); + _data.setMaxIdleMs(_dftMaxIdleSecs*1000L); _data.setCanonicalContext(canonicalize(_context.getContextPath())); _data.setVirtualHost(getVirtualHost(_context)); int maxInterval=getMaxInactiveInterval(); - _data.setExpiryTime(maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000)); + _data.setExpiryTime(maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L)); } /** @@ -293,7 +293,7 @@ public class JDBCSessionManager extends AbstractSessionManager super(JDBCSessionManager.this,data.getCreated(), accessed, data.getId()); _data=data; if (_dftMaxIdleSecs>0) - _data.setMaxIdleMs(_dftMaxIdleSecs*1000); + _data.setMaxIdleMs(_dftMaxIdleSecs*1000L); _jdbcAttributes.putAll(_data.getAttributeMap()); _data.setAttributeMap(_jdbcAttributes); } @@ -333,7 +333,7 @@ public class JDBCSessionManager extends AbstractSessionManager _data.setAccessed(time); int maxInterval=getMaxInactiveInterval(); - _data.setExpiryTime(maxInterval <= 0 ? 0 : (time + maxInterval*1000)); + _data.setExpiryTime(maxInterval <= 0 ? 0 : (time + maxInterval*1000L)); return true; } return false; @@ -357,7 +357,7 @@ public class JDBCSessionManager extends AbstractSessionManager updateSession(_data); didActivate(); } - else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000)) + else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000L)) { updateSessionAccessTime(_data); } @@ -506,23 +506,23 @@ public class JDBCSessionManager extends AbstractSessionManager LOG.debug("getSession("+idInCluster+"): not in session map,"+ " now="+now+ " lastSaved="+(session==null?0:session._data._lastSaved)+ - " interval="+(_saveIntervalSec * 1000)); + " interval="+(_saveIntervalSec * 1000L)); else LOG.debug("getSession("+idInCluster+"): in session map, "+ " now="+now+ " lastSaved="+(session==null?0:session._data._lastSaved)+ - " interval="+(_saveIntervalSec * 1000)+ + " interval="+(_saveIntervalSec * 1000L)+ " lastNode="+session._data.getLastNode()+ " thisNode="+getSessionIdManager().getWorkerName()+ " difference="+(now - session._data._lastSaved)); } - if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000))) + if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000L))) { LOG.debug("getSession("+idInCluster+"): no session in session map or stale session. Reloading session data from db."); data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context)); } - else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)) + else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000L)) { LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db."); data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context)); From 1697fcfa5a58d57dab0704b32b5a253c93af9af4 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 11 Jan 2012 12:23:04 +1100 Subject: [PATCH 18/18] 368060 do not encode sendRedirect URLs --- .../src/main/java/org/eclipse/jetty/server/Response.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index d5fa8321d62..1befeff5ad7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -466,7 +466,6 @@ public class Response implements HttpServletResponse } } - location=encodeRedirectURL(location); resetBuffer(); setHeader(HttpHeaders.LOCATION,location); setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);