From e3132d41d8260915ca79c622f6b720a62dbbc635 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Fri, 3 Aug 2012 18:35:34 +0200 Subject: [PATCH] Jetty9 - Introduced ConnectionFactory for SelectChannelConnector. This change abstracts out the connection creation from the connector itself, so there can be only one connector managing all protocols, depending on the configuration of the connection factories. --- .../eclipse/jetty/embedded/LikeJettyXml.java | 48 +-- .../jetty/embedded/ManyConnectors.java | 16 +- .../jetty/deploy/test/XmlConfiguredJetty.java | 7 +- .../SelectChannelEndPointInterestsTest.java | 16 +- .../io/SelectChannelEndPointSslTest.java | 21 +- .../eclipse/jetty/io/SslConnectionTest.java | 6 +- .../jetty/security/DataConstraintsTest.java | 25 +- .../jetty/server/AbstractConnector.java | 257 ++++++------- ...tor.java => AbstractNetworkConnector.java} | 19 +- .../jetty/server/ConnectionFactory.java | 84 +---- .../jetty/server/ConnectionStatistics.java | 26 +- .../org/eclipse/jetty/server/Connector.java | 223 +++++------- .../jetty/server/HttpConfiguration.java | 27 +- .../server/HttpServerConnectionFactory.java | 69 ++++ .../jetty/server/HttpServerConnector.java | 27 ++ .../eclipse/jetty/server/LocalConnector.java | 57 +-- .../jetty/server/NetworkConnector.java | 56 +++ .../jetty/server/SelectChannelConnector.java | 342 ++++++++++-------- .../java/org/eclipse/jetty/server/Server.java | 20 +- .../server/ssl/SslSelectChannelConnector.java | 4 +- .../server/CheckReverseProxyHeadersTest.java | 14 +- .../jetty/server/HttpConnectionTest.java | 39 +- .../jetty/server/HttpServerTestFixture.java | 29 +- .../org/eclipse/jetty/server/RequestTest.java | 44 +-- .../eclipse/jetty/server/ResponseTest.java | 17 +- .../server/SelectChannelStatisticsTest.java | 9 +- .../SlowClientWithPipelinedRequestTest.java | 19 +- .../server/handler/IPAccessHandlerTest.java | 56 +-- .../jetty/server/ssl/SSLCloseTest.java | 15 +- .../jetty/server/ssl/SSLEngineTest.java | 47 +-- .../SSLSelectChannelConnectorLoadTest.java | 26 +- .../ssl/SelectChannelServerSslTest.java | 46 ++- .../jetty/server/ssl/SslBytesServerTest.java | 24 +- .../ssl/SslSelectChannelTimeoutTest.java | 19 +- .../jetty/server/ssl/SslUploadTest.java | 29 +- .../servlets/GzipWithPipeliningTest.java | 43 ++- .../ServerHTTPAsyncConnectionFactory.java | 44 --- .../eclipse/jetty/spdy/ConnectionFactory.java | 24 -- ...ava => NextProtoNegoServerConnection.java} | 19 +- .../org/eclipse/jetty/spdy/SPDYClient.java | 5 +- .../jetty/spdy/SPDYServerConnector.java | 133 +------ .../ServerSPDYAsyncConnectionFactory.java | 3 +- .../org/eclipse/jetty/spdy/AbstractTest.java | 6 +- .../eclipse/jetty/spdy/SSLEngineLeakTest.java | 2 +- .../eclipse/jetty/spdy/SSLSynReplyTest.java | 2 +- .../jetty/util/ssl/SslContextFactory.java | 20 +- .../jetty/webapp/WebInfConfiguration.java | 147 ++++---- .../io/WebSocketClientSelectorManager.java | 6 +- .../server/WebSocketOverSSLTest.java | 11 +- 49 files changed, 1052 insertions(+), 1196 deletions(-) rename jetty-server/src/main/java/org/eclipse/jetty/server/{AbstractNetConnector.java => AbstractNetworkConnector.java} (83%) create mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnectionFactory.java create mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java create mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java delete mode 100644 jetty-spdy/spdy-jetty-http/src/main/java/org/eclipse/jetty/spdy/http/ServerHTTPAsyncConnectionFactory.java delete mode 100644 jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ConnectionFactory.java rename jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/{NextProtoNegoServerAsyncConnection.java => NextProtoNegoServerConnection.java} (76%) diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java index f5897a5ff8f..a284add2dcc 100644 --- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java +++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java @@ -22,6 +22,8 @@ import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpServerConnectionFactory; import org.eclipse.jetty.server.NCSARequestLog; import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.Server; @@ -44,7 +46,7 @@ public class LikeJettyXml // Setup Threadpool QueuedThreadPool threadPool = new QueuedThreadPool(); threadPool.setMaxThreads(500); - + Server server = new Server(threadPool); server.manage(threadPool); server.setDumpAfterStart(true); @@ -61,33 +63,35 @@ public class LikeJettyXml SelectChannelConnector connector = new SelectChannelConnector(server); connector.setPort(8080); connector.setIdleTimeout(30000); - connector.getConnectionFactory().getHttpConfig().setConfidentialPort(8443); + HttpConfiguration httpConfiguration = new HttpConfiguration(null, false); + httpConfiguration.setConfidentialPort(8443); + connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector, httpConfiguration)); // TODO connector.setStatsOn(false); server.setConnectors(new Connector[] { connector }); - SelectChannelConnector ssl_connector = new SelectChannelConnector(server,true); - ssl_connector.setPort(8443); - SslContextFactory cf = ssl_connector.getConnectionFactory().getSslContextFactory(); - cf.setKeyStorePath(jetty_home + "/etc/keystore"); - cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); - cf.setTrustStore(jetty_home + "/etc/keystore"); - cf.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - cf.setExcludeCipherSuites( - new String[] { - "SSL_RSA_WITH_DES_CBC_SHA", - "SSL_DHE_RSA_WITH_DES_CBC_SHA", - "SSL_DHE_DSS_WITH_DES_CBC_SHA", - "SSL_RSA_EXPORT_WITH_RC4_40_MD5", - "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", - "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", - "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" + SslContextFactory sslContextFactory = new SslContextFactory(); + sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore"); + sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + sslContextFactory.setTrustStore(jetty_home + "/etc/keystore"); + sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + sslContextFactory.setExcludeCipherSuites( + new String[]{ + "SSL_RSA_WITH_DES_CBC_SHA", + "SSL_DHE_RSA_WITH_DES_CBC_SHA", + "SSL_DHE_DSS_WITH_DES_CBC_SHA", + "SSL_RSA_EXPORT_WITH_RC4_40_MD5", + "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", + "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", + "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" }); - // TODO ssl_connector.setStatsOn(false); - server.addConnector(ssl_connector); - ssl_connector.open(); + SelectChannelConnector sslConnector = new SelectChannelConnector(server,sslContextFactory); + sslConnector.setPort(8443); + // TODO sslConnector.setStatsOn(false); + server.addConnector(sslConnector); + sslConnector.open(); HandlerCollection handlers = new HandlerCollection(); ContextHandlerCollection contexts = new ContextHandlerCollection(); diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java index ddf5a79902e..6017520bcbb 100644 --- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java +++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java @@ -38,17 +38,17 @@ public class ManyConnectors connector1.setPort(8888); connector1.setName("admin"); - SelectChannelConnector ssl_connector = new SelectChannelConnector(server,true); String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution"); - System.setProperty("jetty.home",jetty_home); - ssl_connector.setPort(8443); - SslContextFactory cf = ssl_connector.getConnectionFactory().getSslContextFactory(); - cf.setKeyStorePath(jetty_home + "/etc/keystore"); - cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + System.setProperty("jetty.home", jetty_home); + SslContextFactory sslContextFactory = new SslContextFactory(); + sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore"); + sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + SelectChannelConnector sslConnector = new SelectChannelConnector(server,sslContextFactory); + sslConnector.setPort(8443); server.setConnectors(new Connector[] - { connector0, connector1, ssl_connector }); + { connector0, connector1, sslConnector }); server.setHandler(new HelloHandler()); diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java index 395805c151d..9b8abcc23d3 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java @@ -36,6 +36,7 @@ import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; @@ -65,7 +66,7 @@ public class XmlConfiguredJetty Properties properties = new Properties(); String jettyHomeBase = testdir.getDir().getAbsolutePath(); - // Ensure we have a new (pristene) directory to work with. + // Ensure we have a new (pristene) directory to work with. int idx = 0; _jettyHome = new File(jettyHomeBase + "#" + idx); while (_jettyHome.exists()) @@ -412,9 +413,9 @@ public class XmlConfiguredJetty Connector connectors[] = _server.getConnectors(); for (int i = 0; _serverPort<0 && i < connectors.length; i++) { - if (connectors[i] instanceof Connector.NetConnector) + if (connectors[i] instanceof NetworkConnector) { - int port = ((Connector.NetConnector)connectors[i]).getLocalPort(); + int port = ((NetworkConnector)connectors[i]).getLocalPort(); if (port>0) _serverPort=port; } diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java index a5dbb8315f9..7b31765e5dd 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointInterestsTest.java @@ -33,6 +33,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.junit.After; import org.junit.Assert; import org.junit.Test; @@ -86,7 +87,7 @@ public class SelectChannelEndPointInterestsTest super.onOpen(); fillInterested(); } - + @Override public void onFillable() { @@ -98,6 +99,19 @@ public class SelectChannelEndPointInterestsTest selectorManager.start(); } + @After + public void destroy() throws Exception + { + if (selectorManager != null) + selectorManager.stop(); + if (connector != null) + connector.close(); + if (scheduler != null) + scheduler.shutdownNow(); + if (threadPool != null) + threadPool.stop(); + } + @Test public void testReadBlockedThenWriteBlockedThenReadableThenWritable() throws Exception { diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java index d79845914d2..002173895d4 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SelectChannelEndPointSslTest.java @@ -1,11 +1,5 @@ package org.eclipse.jetty.io; -import static org.hamcrest.Matchers.greaterThan; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -13,7 +7,6 @@ import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.concurrent.TimeUnit; - import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult.HandshakeStatus; @@ -28,6 +21,12 @@ import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest { @@ -55,7 +54,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest @Override protected Connection newConnection(SocketChannel channel, EndPoint endpoint) { - SSLEngine engine = __sslCtxFactory.newSslEngine(); + SSLEngine engine = __sslCtxFactory.newSSLEngine(); engine.setUseClientMode(false); SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine); @@ -94,7 +93,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest server.configureBlocking(false); _manager.accept(server); - SSLEngine engine = __sslCtxFactory.newSslEngine(); + SSLEngine engine = __sslCtxFactory.newSSLEngine(); engine.setUseClientMode(true); engine.beginHandshake(); @@ -263,8 +262,8 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest @Test public void checkSslEngineBehaviour() throws Exception { - SSLEngine server = __sslCtxFactory.newSslEngine(); - SSLEngine client = __sslCtxFactory.newSslEngine(); + SSLEngine server = __sslCtxFactory.newSSLEngine(); + SSLEngine client = __sslCtxFactory.newSSLEngine(); ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java index fcc9c4d73ee..0a11e8904df 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java @@ -13,12 +13,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; - import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLSocket; import junit.framework.Assert; - import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.BufferUtil; @@ -52,7 +50,7 @@ public class SslConnectionTest @Override public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment) { - SSLEngine engine = __sslCtxFactory.newSslEngine(); + SSLEngine engine = __sslCtxFactory.newSSLEngine(); engine.setUseClientMode(false); SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine); @@ -120,7 +118,7 @@ public class SslConnectionTest super.onOpen(); fillInterested(); } - + @Override public void onClose() { diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java index 1f1204549e4..d48a20e958b 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/DataConstraintsTest.java @@ -13,12 +13,8 @@ package org.eclipse.jetty.security; -import static org.junit.Assert.assertThat; -import static org.junit.matchers.JUnitMatchers.containsString; - import java.io.IOException; import java.util.Arrays; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -28,6 +24,7 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpServerConnectionFactory; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; @@ -40,6 +37,9 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertThat; +import static org.junit.matchers.JUnitMatchers.containsString; + /** * @version $Revision: 1441 $ $Date: 2010-04-02 12:28:17 +0200 (Fri, 02 Apr 2010) $ */ @@ -57,12 +57,15 @@ public class DataConstraintsTest _server = new Server(); _connector = new LocalConnector(_server); _connector.setIdleTimeout(300000); - _connector.getConnectionFactory().getHttpConfig().setIntegralPort(9998); - _connector.getConnectionFactory().getHttpConfig().setIntegralScheme("FTP"); - _connector.getConnectionFactory().getHttpConfig().setConfidentialPort(9999); - _connector.getConnectionFactory().getHttpConfig().setConfidentialScheme("SPDY"); - _connectorS = new LocalConnector(_server, - new HttpConfiguration(null,false) + HttpConfiguration httpConfiguration = new HttpConfiguration(null, false); + httpConfiguration.setIntegralPort(9998); + httpConfiguration.setIntegralScheme("FTP"); + httpConfiguration.setConfidentialPort(9999); + httpConfiguration.setConfidentialScheme("SPDY"); + _connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(_connector, httpConfiguration)); + + _connectorS = new LocalConnector(_server); + _connectorS.setDefaultConnectionFactory(new HttpServerConnectionFactory(_connectorS, new HttpConfiguration(null,false) { @Override public void customize(Request request) throws IOException @@ -83,7 +86,7 @@ public class DataConstraintsTest { return true; } - }); + })); _server.setConnectors(new Connector[]{_connector,_connectorS}); ContextHandler _context = new ContextHandler(); 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 dc9facc845f..56f73ea798d 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 @@ -15,19 +15,16 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.net.Socket; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; -import javax.net.ssl.SSLEngine; - -import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.StandardByteBufferPool; -import org.eclipse.jetty.io.ssl.SslConnection; -import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Log; @@ -35,49 +32,39 @@ import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; /** - * Abstract Connector implementation. This abstract implementation of the Connector interface provides: - * + *

Partial implementation of {@link Connector}

*/ public abstract class AbstractConnector extends AggregateLifeCycle implements Connector, Dumpable { - protected final Logger LOG = Log.getLogger(getClass()); - + protected final Logger logger = Log.getLogger(getClass()); + // Order is important on server side, so we use a LinkedHashMap + private final Map factories = new LinkedHashMap<>(); private final Statistics _stats = new ConnectionStatistics(); - private final ConnectionFactory _connectionFactory; - private final Thread[] _acceptors; + private final Server _server; + private final SslContextFactory _sslContextFactory; private final Executor _executor; private final ScheduledExecutorService _scheduler; - private final Server _server; private final ByteBufferPool _byteBufferPool; - + private final Thread[] _acceptors; private volatile String _name; - private volatile int _acceptQueueSize = 128; - private volatile boolean _reuseAddress = true; private volatile long _idleTimeout = 200000; - private volatile int _soLingerTime = -1; + private volatile ConnectionFactory defaultConnectionFactory; - /* ------------------------------------------------------------ */ /** * @param server The server this connector will be added to. Must not be null. - * @param connectionFactory ConnectionFactory or null for default - * @param executor An executor for this connector or null to use the servers executor + * @param executor An executor for this connector or null to use the servers executor * @param scheduler A scheduler for this connector or null to use the servers scheduler * @param pool A buffer pool for this connector or null to use a default {@link ByteBufferPool} + * @param sslContextFactory the SSL context factory to make this connector SSL enabled, or null * @param acceptors the number of acceptor threads to use, or 0 for a default value. */ public AbstractConnector( - Server server, - ConnectionFactory connectionFactory, - Executor executor, - ScheduledExecutorService scheduler, - ByteBufferPool pool, int acceptors) + Server server, + Executor executor, + ScheduledExecutorService scheduler, + ByteBufferPool pool, + SslContextFactory sslContextFactory, + int acceptors) { _server=server; _executor=executor!=null?executor:_server.getThreadPool(); @@ -86,23 +73,22 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co @Override public Thread newThread(Runnable r) { - return new Thread(r, "Timer-" + getName()); + return new Thread(r, "Scheduler-" + getName()); } }); _byteBufferPool = pool!=null?pool:new StandardByteBufferPool(); - - _connectionFactory=connectionFactory!=null?connectionFactory:new ConnectionFactory(); - + _sslContextFactory = sslContextFactory; + addBean(_server,false); addBean(_executor,false); addBean(_scheduler,scheduler==null); addBean(_byteBufferPool,pool==null); - addBean(_connectionFactory,connectionFactory!=null); + addBean(_sslContextFactory,true); if (acceptors<=0) acceptors=Math.max(1,(Runtime.getRuntime().availableProcessors()) / 4); if (acceptors > 2 * Runtime.getRuntime().availableProcessors()) - LOG.warn("Acceptors should be <= 2*availableProcessors: " + this); + logger.warn("Acceptors should be <= 2*availableProcessors: " + this); _acceptors = new Thread[acceptors]; } @@ -117,13 +103,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co { return _server; } - - @Override - public ConnectionFactory getConnectionFactory() - { - return _connectionFactory; - } - + @Override public Executor getExecutor() { @@ -136,9 +116,11 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co return _byteBufferPool; } - /** - * @return Returns the maxIdleTime. - */ + public SslContextFactory getSslContextFactory() + { + return _sslContextFactory; + } + @Override public long getIdleTimeout() { @@ -146,52 +128,23 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co } /** - * Set the maximum Idle time for a connection, which roughly translates to the {@link Socket#setSoTimeout(int)} call, although with NIO implementations - * other mechanisms may be used to implement the timeout. The max idle time is applied: + *

Sets the maximum Idle time for a connection, which roughly translates to the {@link Socket#setSoTimeout(int)} + * call, although with NIO implementations other mechanisms may be used to implement the timeout.

+ *

The max idle time is applied:

* - * Jetty interprets this value as the maximum time between some progress being made on the connection. So if a single byte is read or written, then the - * timeout (if implemented by jetty) is reset. However, in many instances, the reading/writing is delegated to the JVM, and the semantic is more strictly - * enforced as the maximum time a single read/write operation can take. Note, that as Jetty supports writes of memory mapped file buffers, then a write may - * take many 10s of seconds for large content written to a slow device. - *

- * Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so - * these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand). + *

This value is interpreted as the maximum time between some progress being made on the connection. + * So if a single byte is read or written, then the timeout is reset.

* - * @param idleTimeout The idleTimeout to set. + * @param idleTimeout the idle timeout */ public void setIdleTimeout(long idleTimeout) { _idleTimeout = idleTimeout; } - /** - * @return Returns the soLingerTime. - */ - public int getSoLingerTime() - { - return _soLingerTime; - } - - /** - * @return Returns the acceptQueueSize. - */ - public int getAcceptQueueSize() - { - return _acceptQueueSize; - } - - /** - * @param acceptQueueSize The acceptQueueSize to set. - */ - public void setAcceptQueueSize(int acceptQueueSize) - { - _acceptQueueSize = acceptQueueSize; - } - /** * @return Returns the number of acceptor threads. */ @@ -201,72 +154,100 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co } - /** - * @param soLingerTime The soLingerTime to set or -1 to disable. - */ - public void setSoLingerTime(int soLingerTime) - { - _soLingerTime = soLingerTime; - } - @Override protected void doStart() throws Exception { super.doStart(); - // Start selector thread - synchronized (this) - { - for (int i = 0; i < _acceptors.length; i++) - getExecutor().execute(new Acceptor(i)); - } + for (int i = 0; i < _acceptors.length; i++) + getExecutor().execute(new Acceptor(i)); - LOG.info("Started {}", this); + logger.info("Started {}", this); } @Override protected void doStop() throws Exception { - super.doStop(); - for (Thread thread : _acceptors) { if (thread != null) thread.interrupt(); } + + super.doStop(); + + logger.info("Stopped {}", this); } public void join() throws InterruptedException { - for (Thread thread : _acceptors) - if (thread != null) - thread.join(); + join(0); } - protected void configure(Socket socket) + public void join(long timeout) throws InterruptedException { - try - { - socket.setTcpNoDelay(true); - if (_soLingerTime >= 0) - socket.setSoLinger(true, _soLingerTime / 1000); - else - socket.setSoLinger(false, 0); - } - catch (Exception e) - { - LOG.ignore(e); - } + for (Thread thread : _acceptors) + if (thread != null) + thread.join(timeout); } protected abstract void accept(int acceptorID) throws IOException, InterruptedException; - /* ------------------------------------------------------------ */ + public ConnectionFactory getConnectionFactory(String protocol) + { + synchronized (factories) + { + return factories.get(protocol); + } + } + + public ConnectionFactory putConnectionFactory(String protocol, ConnectionFactory factory) + { + synchronized (factories) + { + return factories.put(protocol, factory); + } + } + + public ConnectionFactory removeConnectionFactory(String protocol) + { + synchronized (factories) + { + return factories.remove(protocol); + } + } + + public Map getConnectionFactories() + { + synchronized (factories) + { + return new LinkedHashMap<>(factories); + } + } + + public void clearConnectionFactories() + { + synchronized (factories) + { + factories.clear(); + } + } + + public ConnectionFactory getDefaultConnectionFactory() + { + return defaultConnectionFactory; + } + + public void setDefaultConnectionFactory(ConnectionFactory defaultConnectionFactory) + { + this.defaultConnectionFactory = defaultConnectionFactory; + } + private class Acceptor implements Runnable { - int _acceptor = 0; + private final int _acceptor; - Acceptor(int id) + private Acceptor(int id) { _acceptor = id; } @@ -275,22 +256,17 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co public void run() { Thread current = Thread.currentThread(); - String name; + String name = current.getName(); + current.setName(name + " Acceptor" + _acceptor + " " + AbstractConnector.this); + synchronized (AbstractConnector.this) { - if (!isRunning()) - return; - _acceptors[_acceptor] = current; - name = _acceptors[_acceptor].getName(); - current.setName(name + " Acceptor" + _acceptor + " " + AbstractConnector.this); } - int old_priority = current.getPriority(); try { - current.setPriority(old_priority); - while (isRunning() && getTransport() != null) + while (isRunning()) { try { @@ -298,17 +274,16 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co } catch (IOException | InterruptedException e) { - LOG.ignore(e); + logger.ignore(e); } catch (Throwable e) { - LOG.warn(e); + logger.warn(e); } } } finally { - current.setPriority(old_priority); current.setName(name); synchronized (AbstractConnector.this) @@ -350,22 +325,6 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co _stats.connectionClosed(duration, requests, requests); } - /** - * @return True if the the server socket will be opened in SO_REUSEADDR mode. - */ - public boolean getReuseAddress() - { - return _reuseAddress; - } - - /** - * @param reuseAddress True if the the server socket will be opened in SO_REUSEADDR mode. - */ - public void setReuseAddress(boolean reuseAddress) - { - _reuseAddress = reuseAddress; - } - public ScheduledExecutorService getScheduler() { return _scheduler; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java similarity index 83% rename from jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetConnector.java rename to jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java index 96aee4a7500..4bb55203944 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java @@ -20,14 +20,17 @@ import java.util.concurrent.ScheduledExecutorService; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.ssl.SslContextFactory; -public abstract class AbstractNetConnector extends AbstractConnector implements Connector.NetConnector +/** + *

Partial implementation of {@link NetworkConnector}.

+ */ +public abstract class AbstractNetworkConnector extends AbstractConnector implements NetworkConnector { private volatile String _host; private volatile int _port = 0; - public AbstractNetConnector(Server server, ConnectionFactory connectionFactory, Executor executor, ScheduledExecutorService scheduler, ByteBufferPool pool, int acceptors) + public AbstractNetworkConnector(Server server, Executor executor, ScheduledExecutorService scheduler, ByteBufferPool pool, SslContextFactory sslContextFactory, int acceptors) { - super(server,connectionFactory,executor,scheduler,pool, acceptors); + super(server, executor, scheduler, pool, sslContextFactory, acceptors); } public void setHost(String host) @@ -74,14 +77,8 @@ public abstract class AbstractNetConnector extends AbstractConnector implements @Override protected void doStop() throws Exception { - try - { - close(); - } - catch (IOException e) - { - LOG.warn(e); - } + close(); + super.doStop(); int i = getName().lastIndexOf("/"); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java index 587ba965fc9..890a7f0cfe3 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java @@ -1,5 +1,5 @@ // ======================================================================== -// Copyright (c) 2004-2012 Mort Bay Consulting Pty. Ltd. +// Copyright 2011-2012 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 @@ -13,80 +13,22 @@ package org.eclipse.jetty.server; -import java.io.IOException; - -import javax.net.ssl.SSLEngine; +import java.nio.channels.SocketChannel; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.ssl.SslConnection; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.ssl.SslContextFactory; -// TODO This is just a place holder for a real factory -public class ConnectionFactory extends AggregateLifeCycle +/** + *

Factory for {@link Connection}s.

+ */ +public interface ConnectionFactory { - private final boolean _ssl; - private final SslContextFactory _sslContextFactory; - - - // TODO Make this part of pluggable factory - private final HttpConfiguration _httpConfig; - - - ConnectionFactory() - { - this(null,false); - } - - /* ------------------------------------------------------------ */ - /** - * @param sslContextFactory An SslContextFactory to use or null if no ssl is required or to use default {@link SslContextFactory} - * @param ssl If true, then new connections will assumed to be SSL. If false, connections can only become SSL if they upgrade and a SslContextFactory is passed. + /** + *

Creates a new {@link Connection} with the given parameters

+ * @param channel the {@link SocketChannel} associated with the connection + * @param endPoint the {@link EndPoint} associated with the connection + * @param attachment the attachment associated with the connection + * @return a new {@link Connection} */ - ConnectionFactory(SslContextFactory sslContextFactory, boolean ssl) - { - this(null,sslContextFactory,ssl); - } - - ConnectionFactory(HttpConfiguration httpConfig, SslContextFactory sslContextFactory, boolean ssl) - { - _ssl=ssl; - _sslContextFactory=sslContextFactory!=null?sslContextFactory:(ssl?new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH):null); - - addBean(_sslContextFactory,sslContextFactory==null); - - // TODO make this pluggable - _httpConfig = httpConfig!=null?httpConfig:new HttpConfiguration(_sslContextFactory,ssl); - addBean(_httpConfig,httpConfig==null); - - } - - - protected Connection newConnection(Connector connector,EndPoint endp) throws IOException - { - - if (_ssl) - { - SSLEngine engine = _sslContextFactory.createSSLEngine(endp.getRemoteAddress()); - SslConnection ssl_connection = new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endp, engine); - - Connection http_connection = new HttpConnection(_httpConfig,connector,ssl_connection.getDecryptedEndPoint()); - ssl_connection.getDecryptedEndPoint().setConnection(http_connection); - return ssl_connection; - } - return new HttpConnection(_httpConfig,connector,endp); - } - - public SslContextFactory getSslContextFactory() - { - return _sslContextFactory; - } - - public HttpConfiguration getHttpConfig() - { - return _httpConfig; - } - - + public Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionStatistics.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionStatistics.java index 534653d2dee..589f2e4ae70 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionStatistics.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionStatistics.java @@ -28,14 +28,14 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics private final SampleStatistic _messagesOut = new SampleStatistic(); private final SampleStatistic _connectionDurationStats = new SampleStatistic(); - + /* ------------------------------------------------------------ */ @Override public int getBytesIn() { return -1; } - + /* ------------------------------------------------------------ */ @Override @@ -185,7 +185,7 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics return (start != -1)?(System.currentTimeMillis() - start):0; } - + /* ------------------------------------------------------------ */ @Override public void doStart() @@ -193,12 +193,12 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics statsReset(); _statsStartedAt.set(System.currentTimeMillis()); } - + /* ------------------------------------------------------------ */ @Override public void doStop() { - + } /* ------------------------------------------------------------ */ @@ -212,7 +212,7 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics _connectionStats.reset(); _connectionDurationStats.reset(); } - + /* ------------------------------------------------------------ */ @Override public void connectionOpened() @@ -223,19 +223,19 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics /* ------------------------------------------------------------ */ @Override - public void connectionUpgraded(long duration, int msgIn, int msgOut) + public void connectionUpgraded(long duration, int messagesIn, int messagesOut) { - _messagesIn.set(msgIn); - _messagesOut.set(msgOut); + _messagesIn.set(messagesIn); + _messagesOut.set(messagesOut); } /* ------------------------------------------------------------ */ @Override - public void connectionClosed(long duration, int msgIn, int msgOut) + public void connectionClosed(long duration, int messagesIn, int messagesOut) { - _messagesIn.set(msgIn); - _messagesOut.set(msgOut); + _messagesIn.set(messagesIn); + _messagesOut.set(messagesOut); _connectionStats.decrement(); _connectionDurationStats.set(duration); } -} \ No newline at end of file +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java index e29f002003d..3cf2cd84274 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java @@ -13,7 +13,6 @@ package org.eclipse.jetty.server; -import java.io.IOException; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; @@ -21,215 +20,183 @@ import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.ssl.SslContextFactory; -/** HTTP Connector. - * Implementations of this interface provide connectors for the HTTP protocol. - * A connector receives requests (normally from a socket) and calls the - * handle method of the Handler object. These operations are performed using - * threads from the ThreadPool set on the connector. - * - * When a connector is registered with an instance of Server, then the server - * will set itself as both the ThreadPool and the Handler. Note that a connector - * can be used without a Server if a thread pool and handler are directly provided. - * +/** + *

A {@link Connector} accept connections and data from remote peers, + * and allows applications to send data to remote peers, by setting up + * the machinery needed to handle such tasks.

*/ public interface Connector extends LifeCycle { - /* ------------------------------------------------------------ */ /** - * @return the name of the connector. Defaults to the HostName:port + * @return the name of the connector, defaulting to host:port */ - String getName(); + public String getName(); - /* ------------------------------------------------------------ */ - Server getServer(); - - /* ------------------------------------------------------------ */ - ConnectionFactory getConnectionFactory(); - - /* ------------------------------------------------------------ */ - Executor getExecutor(); - - /* ------------------------------------------------------------ */ - ScheduledExecutorService getScheduler(); - - /* ------------------------------------------------------------ */ - ByteBufferPool getByteBufferPool(); - - /* ------------------------------------------------------------ */ /** - * @return Max Idle time for connections in milliseconds + * @return the {@link Server} instance associated with this {@link Connector} */ - long getIdleTimeout(); + public Server getServer(); + + /** + * @return the {@link Executor} used to submit tasks + */ + public Executor getExecutor(); + + /** + * @return the {@link ScheduledExecutorService} used to schedule tasks + */ + public ScheduledExecutorService getScheduler(); + + /** + * @return the {@link ByteBufferPool} to acquire buffers from and release buffers to + */ + public ByteBufferPool getByteBufferPool(); + + /** + * @return the {@link SslContextFactory} associated with this {@link Connector} + */ + public SslContextFactory getSslContextFactory(); + + /** + * @return the dle timeout for connections in milliseconds + */ + public long getIdleTimeout(); - /* ------------------------------------------------------------ */ /** * @return the underlying socket, channel, buffer etc. for the connector. */ - Object getTransport(); + public Object getTransport(); - /* ------------------------------------------------------------ */ - Statistics getStatistics(); + /** + * @return the {@link Statistics} associated with this {@link Connector} + */ + public Statistics getStatistics(); - interface NetConnector extends Connector, AutoCloseable + /** + *

{@link Connector} statistics.

+ */ + public interface Statistics extends LifeCycle { - /* ------------------------------------------------------------ */ /** - * Opens the connector - * @throws IOException + * @return true if gathering of statistics is enabled */ - void open() throws IOException; + public boolean getStatsOn(); - /* ------------------------------------------------------------ */ - void close() throws IOException; - - /* ------------------------------------------------------------ */ /** - * @return The hostname representing the interface to which - * this connector will bind, or null for all interfaces. + *

Resets the statistics.

*/ - String getHost(); + public void statsReset(); - /* ------------------------------------------------------------ */ /** - * @return The configured port for the connector or 0 if any available - * port may be used. - */ - int getPort(); - - /* ------------------------------------------------------------ */ - /** - * @return The actual port the connector is listening on or - * -1 if it has not been opened, or -2 if it has been closed. - */ - int getLocalPort(); - } - - interface Statistics extends LifeCycle - { - /* ------------------------------------------------------------ */ - /** - * @return True if statistics collection is turned on. - */ - boolean getStatsOn(); - - /* ------------------------------------------------------------ */ - /** Reset statistics. - */ - void statsReset(); - - /* ------------------------------------------------------------ */ - /** - * @return Get the number of messages received by this connector - * since last call of statsReset(). If setStatsOn(false) then this - * is undefined. + * @return the number of messages received by this connector + * since last call to {@link #statsReset()}. */ public int getMessagesIn(); - /* ------------------------------------------------------------ */ /** - * @return Get the number of messages sent by this connector - * since last call of statsReset(). If setStatsOn(false) then this - * is undefined. + * @return the number of messages sent by this connector + * since last call to {@link #statsReset()}. */ public int getMessagesOut(); - /* ------------------------------------------------------------ */ /** - * @return Get the number of bytes received by this connector - * since last call of statsReset(). If setStatsOn(false) then this - * is undefined. + * @return the number of bytes received by this connector + * since last call to {@link #statsReset()}. */ public int getBytesIn(); - /* ------------------------------------------------------------ */ /** - * @return Get the number of bytes sent by this connector - * since last call of statsReset(). If setStatsOn(false) then this - * is undefined. + * @return the number of bytes sent by this connector + * since last call to {@link #statsReset()}. */ public int getBytesOut(); - /* ------------------------------------------------------------ */ /** - * @return Returns the connectionsDurationTotal. + * @return the total time connections have been open, in milliseconds, + * since last call to {@link #statsReset()}. */ public long getConnectionsDurationTotal(); - /* ------------------------------------------------------------ */ /** - * @return Number of connections accepted by the server since - * statsReset() called. Undefined if setStatsOn(false). + * @return the number of connections accepted by the server + * since last call to {@link #statsReset()}. */ public int getConnections() ; - /* ------------------------------------------------------------ */ /** - * @return Number of connections currently open that were opened - * since statsReset() called. Undefined if setStatsOn(false). + * @return the number of connections currently open that were opened + * since last call to {@link #statsReset()}. */ public int getConnectionsOpen() ; - /* ------------------------------------------------------------ */ /** - * @return Maximum number of connections opened simultaneously - * since statsReset() called. Undefined if setStatsOn(false). + * @return the max number of connections opened simultaneously + * since last call to {@link #statsReset()}. */ public int getConnectionsOpenMax() ; - /* ------------------------------------------------------------ */ /** - * @return Maximum duration in milliseconds of an open connection - * since statsReset() called. Undefined if setStatsOn(false). + * @return the max time a connection has been open, in milliseconds, + * since last call to {@link #statsReset()}. */ public long getConnectionsDurationMax(); - /* ------------------------------------------------------------ */ /** - * @return Mean duration in milliseconds of open connections - * since statsReset() called. Undefined if setStatsOn(false). + * @return the mean time connections have been open, in milliseconds, + * since last call to {@link #statsReset()}. */ public double getConnectionsDurationMean() ; - /* ------------------------------------------------------------ */ /** - * @return Standard deviation of duration in milliseconds of - * open connections since statsReset() called. Undefined if - * setStatsOn(false). + * @return the standard deviation of the time connections have been open, in milliseconds, + * since last call to {@link #statsReset()}. */ public double getConnectionsDurationStdDev() ; - /* ------------------------------------------------------------ */ /** - * @return Mean number of messages received per connection - * since statsReset() called. Undefined if setStatsOn(false). + * @return the mean number of messages received per connection + * since last call to {@link #statsReset()}. */ public double getConnectionsMessagesInMean() ; - /* ------------------------------------------------------------ */ /** - * @return Standard Deviation of number of messages received per connection - * since statsReset() called. Undefined if setStatsOn(false). + * @return the standard deviation of the number of messages received per connection + * since last call to {@link #statsReset()}. */ public double getConnectionsMessagesInStdDev() ; - /* ------------------------------------------------------------ */ /** - * @return Maximum number of messages received per connection - * since statsReset() called. Undefined if setStatsOn(false). + * @return the max number of messages received by a connection + * since last call to {@link #statsReset()}. */ public int getConnectionsMessagesInMax(); - /* ------------------------------------------------------------ */ /** - * @return Timestamp stats were started at. + * @return the number of milliseconds the statistics have been started or reset */ public long getStatsOnMs(); - void connectionOpened(); + /** + *

Callback method invoked when a new connection is opened.

+ */ + public void connectionOpened(); - void connectionUpgraded(long duration, int requests, int requests2); - - void connectionClosed(long duration, int requests, int requests2); + /** + *

Callback method invoked when a connection is upgraded.

+ * + * @param duration the time the previous connection was opened + * @param messagesIn the number of messages received by the previous connection + * @param messagesOut the number of messages send by the previous connection + */ + public void connectionUpgraded(long duration, int messagesIn, int messagesOut); + /** + *

Callback method invoked when a connection is closed.

+ * + * @param duration the time the connection was opened + * @param messagesIn the number of messages received by the connection + * @param messagesOut the number of messages send by the connection + */ + public void connectionClosed(long duration, int messagesIn, int messagesOut); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java index 075097af7ca..81fb4793235 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java @@ -2,7 +2,6 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.net.InetSocketAddress; - import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLSession; import javax.servlet.ServletRequest; @@ -21,10 +20,10 @@ import org.eclipse.jetty.util.ssl.SslContextFactory; public class HttpConfiguration extends AggregateLifeCycle { static final Logger LOG = Log.getLogger(HttpConfiguration.class); - + private final SslContextFactory _sslContextFactory; private final boolean _ssl; - + private String _integralScheme = HttpScheme.HTTPS.asString(); private int _integralPort = 0; private String _confidentialScheme = HttpScheme.HTTPS.asString(); @@ -41,7 +40,7 @@ public class HttpConfiguration extends AggregateLifeCycle private int _requestBufferSize=16*1024; private int _responseHeaderSize=6*1024; private int _responseBufferSize=16*1024; - + public HttpConfiguration(SslContextFactory sslContextFactory,boolean ssl) { _sslContextFactory=sslContextFactory!=null?sslContextFactory:ssl?new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH):null; @@ -49,7 +48,7 @@ public class HttpConfiguration extends AggregateLifeCycle if (_sslContextFactory!=null) addBean(_sslContextFactory,sslContextFactory==null); } - + public SslContextFactory getSslContextFactory() { return _sslContextFactory; @@ -121,7 +120,7 @@ public class HttpConfiguration extends AggregateLifeCycle * */ public void customize(Request request) throws IOException - { + { if (isSecure()) { request.setScheme(HttpScheme.HTTPS.asString()); @@ -130,7 +129,7 @@ public class HttpConfiguration extends AggregateLifeCycle SSLEngine sslEngine=sslConnection.getSSLEngine(); SslCertificates.customize(sslEngine,request); } - + request.setTimeStamp(System.currentTimeMillis()); if (isForwarded()) checkForwardedHeaders(request); @@ -242,13 +241,13 @@ public class HttpConfiguration extends AggregateLifeCycle /* ------------------------------------------------------------ */ /** * The request is integral IFF it is secure AND the server port - * matches any configured {@link #getIntegralPort()}. + * matches any configured {@link #getIntegralPort()}. * This allows separation of listeners providing INTEGRAL versus * CONFIDENTIAL constraints, such as one SSL listener configured to require * client certs providing CONFIDENTIAL, whereas another SSL listener not * requiring client certs providing mere INTEGRAL constraints. *

- * The request is secure if it is SSL or it {@link #isForwarded()} is true + * The request is secure if it is SSL or it {@link #isForwarded()} is true * and the scheme matches {@link #getIntegralScheme()()} */ public boolean isIntegral(Request request) @@ -280,13 +279,13 @@ public class HttpConfiguration extends AggregateLifeCycle /* ------------------------------------------------------------ */ /** * The request is confidential IFF it is secure AND the server port - * matches any configured {@link #getConfidentialPort()}. + * matches any configured {@link #getConfidentialPort()}. * This allows separation of listeners providing INTEGRAL versus * CONFIDENTIAL constraints, such as one SSL listener configured to require * client certs providing CONFIDENTIAL, whereas another SSL listener not * requiring client certs providing mere INTEGRAL constraints. *

- * The request is secure if it is SSL or it {@link #isForwarded()} is true + * The request is secure if it is SSL or it {@link #isForwarded()} is true * and the scheme matches {@link #getConfidentialScheme()} */ public boolean isConfidential(Request request) @@ -510,7 +509,7 @@ public class HttpConfiguration extends AggregateLifeCycle { _forwardedSslSessionIdHeader = forwardedSslSessionId; } - + /* ------------------------------------------------------------ */ @Override @@ -521,8 +520,8 @@ public class HttpConfiguration extends AggregateLifeCycle _sslContextFactory.checkKeyStore(); super.doStart(); - - SSLEngine sslEngine = _sslContextFactory.newSslEngine(); + + SSLEngine sslEngine = _sslContextFactory.newSSLEngine(); sslEngine.setUseClientMode(false); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnectionFactory.java new file mode 100644 index 00000000000..cb4e5157ca2 --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnectionFactory.java @@ -0,0 +1,69 @@ +//======================================================================== +//Copyright 2011-2012 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.server; + +import java.nio.channels.SocketChannel; +import javax.net.ssl.SSLEngine; + +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.ssl.SslConnection; +import org.eclipse.jetty.util.ssl.SslContextFactory; + +public class HttpServerConnectionFactory implements ConnectionFactory +{ + private final Connector connector; + private final HttpConfiguration configuration; + + public HttpServerConnectionFactory(Connector connector) + { + this(connector, new HttpConfiguration(connector.getSslContextFactory(), connector.getSslContextFactory() != null)); + } + public HttpServerConnectionFactory(Connector connector, HttpConfiguration configuration) + { + this.connector = connector; + this.configuration = configuration; + } + + public Connector getConnector() + { + return connector; + } + + public HttpConfiguration getHttpConfiguration() + { + return configuration; + } + + @Override + public Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment) + { + SslContextFactory sslContextFactory = connector.getSslContextFactory(); + if (sslContextFactory != null) + { + SSLEngine engine = sslContextFactory.newSSLEngine(endPoint.getRemoteAddress()); + engine.setUseClientMode(false); + SslConnection sslConnection = new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine); + Connection httpConnection = new HttpConnection(getHttpConfiguration(), connector, sslConnection.getDecryptedEndPoint()); + sslConnection.getDecryptedEndPoint().setConnection(httpConnection); + httpConnection.onOpen(); + return sslConnection; + } + else + { + return new HttpConnection(getHttpConfiguration(), getConnector(), endPoint); + } + } +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java new file mode 100644 index 00000000000..1692fe1788b --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpServerConnector.java @@ -0,0 +1,27 @@ +package org.eclipse.jetty.server; + +import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.util.annotation.Name; +import org.eclipse.jetty.util.ssl.SslContextFactory; + +public class HttpServerConnector extends SelectChannelConnector +{ + public HttpServerConnector(Server server) + { + this(server, null); + } + + public HttpServerConnector(Server server, SslContextFactory sslContextFactory) + { + this(server, null, null, null, sslContextFactory, 0, 0); + } + + public HttpServerConnector(@Name("server") Server server, @Name("executor") Executor executor, @Name("scheduler") ScheduledExecutorService scheduler, @Name("bufferPool") ByteBufferPool pool, @Name("sslContextFactory") SslContextFactory sslContextFactory, @Name("acceptors") int acceptors, @Name("selectors") int selectors) + { + super(server, executor, scheduler, pool, sslContextFactory, acceptors, selectors); + setDefaultConnectionFactory(new HttpServerConnectionFactory(this)); + } +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java index f197e50aa54..f85f9c8d1fa 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java @@ -23,50 +23,34 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteArrayEndPoint; -import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; public class LocalConnector extends AbstractConnector { - private static final Logger LOG = Log.getLogger(LocalConnector.class); - private final BlockingQueue _connects = new LinkedBlockingQueue<>(); - + public LocalConnector(Server server) { - this(server,null,null,null,null, -1); - } - - public LocalConnector(Server server, boolean ssl) - { - this(server,new ConnectionFactory(null,ssl),null,null,null,0); - manage(getConnectionFactory()); - } - - public LocalConnector(Server server, HttpConfiguration httpConfig) - { - this(server,new ConnectionFactory(httpConfig,null,false),null,null,null,0); - manage(getConnectionFactory()); + this(server,null); } public LocalConnector(Server server, SslContextFactory sslContextFactory) { - this(server,new ConnectionFactory(sslContextFactory,sslContextFactory!=null),null,null,null,0); - manage(getConnectionFactory()); + this(server, null, null, null, sslContextFactory, 0); } - - public LocalConnector(Server server, ConnectionFactory connectionFactory, Executor executor, ScheduledExecutorService scheduler, ByteBufferPool pool, - int acceptors) + + public LocalConnector(Server server, Executor executor, ScheduledExecutorService scheduler, ByteBufferPool pool, + SslContextFactory sslContextFactory, int acceptors) { - super(server,connectionFactory,executor,scheduler,pool,acceptors); + super(server,executor,scheduler,pool, sslContextFactory, acceptors); setIdleTimeout(30000); + setDefaultConnectionFactory(new HttpServerConnectionFactory(this)); } - + @Override public Object getTransport() { @@ -77,7 +61,7 @@ public class LocalConnector extends AbstractConnector * Returns all the responses received once the thread activity has * returned to the level it was before the requests. *

- * This methods waits until the connection is closed or + * This methods waits until the connection is closed or * is idle for 1s before returning the responses. * @param requests the requests * @return the responses @@ -93,7 +77,7 @@ public class LocalConnector extends AbstractConnector * Returns all the responses received once the thread activity has * returned to the level it was before the requests. *

- * This methods waits until the connection is closed or + * This methods waits until the connection is closed or * an idle period before returning the responses. * @param requests the requests * @param idleFor The time the response stream must be idle for before returning @@ -111,7 +95,7 @@ public class LocalConnector extends AbstractConnector * Returns all the responses received once the thread activity has * returned to the level it was before the requests. *

- * This methods waits until the connection is closed or + * This methods waits until the connection is closed or * is idle for 1s before returning the responses. * @param requestsBuffer the requests * @return the responses @@ -126,7 +110,7 @@ public class LocalConnector extends AbstractConnector * Returns all the responses received once the thread activity has * returned to the level it was before the requests. *

- * This methods waits until the connection is closed or + * This methods waits until the connection is closed or * an idle period before returning the responses. * @param requestsBuffer the requests * @param idleFor The time the response stream must be idle for before returning @@ -136,7 +120,7 @@ public class LocalConnector extends AbstractConnector */ public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception { - LOG.debug("getResponses"); + logger.debug("getResponses"); LocalEndPoint endp = new LocalEndPoint(); endp.setInput(requestsBuffer); _connects.add(endp); @@ -161,16 +145,15 @@ public class LocalConnector extends AbstractConnector @Override protected void accept(int acceptorID) throws IOException, InterruptedException { - LOG.debug("accepting {}",acceptorID); + logger.debug("accepting {}", acceptorID); LocalEndPoint endp = _connects.take(); - Connection connection=getConnectionFactory().newConnection(LocalConnector.this,endp); + Connection connection = getDefaultConnectionFactory().newConnection(null, endp, null); endp.setConnection(connection); endp.onOpen(); connection.onOpen(); connectionOpened(connection); } - public class LocalEndPoint extends ByteArrayEndPoint { private CountDownLatch _closed = new CountDownLatch(1); @@ -232,7 +215,7 @@ public class LocalConnector extends AbstractConnector } catch(Exception e) { - LOG.warn(e); + logger.warn(e); } } } @@ -254,10 +237,10 @@ public class LocalConnector extends AbstractConnector } catch(Exception e) { - LOG.warn(e); + logger.warn(e); } } } - + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java new file mode 100644 index 00000000000..570a32f7fc9 --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java @@ -0,0 +1,56 @@ +// ======================================================================== +// Copyright (c) 2004-2012 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.server; + +import java.io.IOException; + +/** + *

A {@link Connector} that handles network communication.

+ */ +public interface NetworkConnector extends Connector, AutoCloseable +{ + /** + *

Performs the activities needed to open the network communication + * (for example, to start accepting incoming network connections).

+ * + * @throws IOException if this connector cannot be opened + * @see #close() + */ + void open() throws IOException; + + /** + *

Performs the activities needed to close the network communication + * (for example, to stop accepting network connections).

+ * @throws IOException if this connector cannot be closed + */ + void close() throws IOException; + + /** + * @return The hostname representing the interface to which + * this connector will bind, or null for all interfaces. + */ + String getHost(); + + /** + * @return The configured port for the connector or 0 if any available + * port may be used. + */ + int getPort(); + + /** + * @return The actual port the connector is listening on, or + * -1 if it has not been opened, or -2 if it has been closed. + */ + int getLocalPort(); +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SelectChannelConnector.java index f2aad4ba14b..fdf4e4e135e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SelectChannelConnector.java @@ -15,7 +15,9 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.net.InetSocketAddress; +import java.net.ServerSocket; import java.net.Socket; +import java.net.SocketException; import java.nio.channels.Channel; import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; @@ -23,10 +25,9 @@ import java.nio.channels.SocketChannel; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; -import org.eclipse.jetty.continuation.Continuation; +import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.SelectChannelEndPoint; import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SelectorManager.ManagedSelector; @@ -34,121 +35,139 @@ import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.ssl.SslContextFactory; /** - * Selecting NIO connector. - *

- * This connector uses efficient NIO buffers with a non blocking threading model. Direct NIO buffers - * are used and threads are only allocated to connections with requests. Synchronization is used to - * simulate blocking for the servlet API, and any unflushed content at the end of request handling - * is written asynchronously. - *

- *

- * This connector is best used when there are a many connections that have idle periods. - *

- *

- * When used with {@link org.eclipse.jetty.continuation.Continuation}, threadless waits are supported. - * If a filter or servlet returns after calling {@link Continuation#suspend()} or when a - * runtime exception is thrown from a call to {@link Continuation#undispatch()}, Jetty will - * will not send a response to the client. Instead the thread is released and the Continuation is - * placed on the timer queue. If the Continuation timeout expires, or it's - * resume method is called, then the request is again allocated a thread and the request is retried. - * The limitation of this approach is that request content is not available on the retried request, - * thus if possible it should be read after the continuation or saved as a request attribute or as the - * associated object of the Continuation instance. - *

+ *

Implementation of {@link NetworkConnector} based on NIO classes.

*/ -public class SelectChannelConnector extends AbstractNetConnector +public class SelectChannelConnector extends AbstractNetworkConnector { private final SelectorManager _manager; - protected ServerSocketChannel _acceptChannel; - protected boolean _inheritChannel; - private int _localPort=-1; - - /* ------------------------------------------------------------ */ + private volatile ServerSocketChannel _acceptChannel; + private volatile boolean _inheritChannel = false; + private volatile int _localPort = -1; + private volatile int _acceptQueueSize = 128; + private volatile boolean _reuseAddress = true; + private volatile int _lingerTime = -1; + public SelectChannelConnector(Server server) { - this(server,null,null,null,null,0,0); + this(server, null); } - - /* ------------------------------------------------------------ */ - public SelectChannelConnector(Server server, boolean ssl) - { - this(server,new ConnectionFactory(null,ssl)); - manage(getConnectionFactory()); - } - - /* ------------------------------------------------------------ */ + public SelectChannelConnector(Server server, SslContextFactory sslContextFactory) { - this(server,new ConnectionFactory(sslContextFactory,sslContextFactory!=null)); - manage(getConnectionFactory()); + this(server, null, null, null, sslContextFactory, 0, 0); } - - /* ------------------------------------------------------------ */ - public SelectChannelConnector(Server server, ConnectionFactory connectionFactory) - { - this(server,connectionFactory,null,null,null,0,0); - } - - /* ------------------------------------------------------------ */ /** - * @param server The server this connector will be added to. Must not be null. - * @param executor An executor for this connector or null to use the servers executor + * @param server The server this connector will be added to. Must not be null. + * @param executor An executor for this connector or null to use the servers executor * @param scheduler A scheduler for this connector or null to use the servers scheduler - * @param pool A buffer pool for this connector or null to use a default {@link ByteBufferPool} + * @param pool A buffer pool for this connector or null to use a default {@link ByteBufferPool} * @param acceptors the number of acceptor threads to use, or 0 for a default value. */ - public SelectChannelConnector( - @Name("server") Server server, - @Name("connectionFactory") ConnectionFactory connectionFactory, - @Name("executor") Executor executor, - @Name("scheduler") ScheduledExecutorService scheduler, - @Name("bufferPool") ByteBufferPool pool, - @Name("acceptors") int acceptors, - @Name("selectors") int selectors) + public SelectChannelConnector( + @Name("server") Server server, + @Name("executor") Executor executor, + @Name("scheduler") ScheduledExecutorService scheduler, + @Name("bufferPool") ByteBufferPool pool, + @Name("sslContextFactory") SslContextFactory sslContextFactory, + @Name("acceptors") int acceptors, + @Name("selectors") int selectors) { - super(server,connectionFactory,executor,scheduler,pool,acceptors); - _manager=new ConnectorSelectorManager(selectors!=0?selectors:Math.max(1,(Runtime.getRuntime().availableProcessors())/4)); - addBean(_manager,true); - - // TODO yuck - if (getConnectionFactory().getSslContextFactory()!=null) + super(server, executor, scheduler, pool, sslContextFactory, acceptors); + _manager = new ConnectorSelectorManager(selectors > 0 ? selectors : Math.max(1, (Runtime.getRuntime().availableProcessors()) / 4)); + addBean(_manager, true); + + // TODO: why we need to set the linger time when in SSL mode ? + if (sslContextFactory != null) setSoLingerTime(30000); + + // TODO: we hardcode HTTP, but this is a generic connector that should not hardcode anything + setDefaultConnectionFactory(new HttpServerConnectionFactory(this)); } - + /** + * @return whether this connector uses a channel inherited from the JVM. + * @see System#inheritedChannel() + */ public boolean isInheritChannel() { return _inheritChannel; } /** - * If true, the connector first tries to inherit from a channel provided by the system. - * If there is no inherited channel available, or if the inherited channel provided not usable, - * then it will fall back upon normal ServerSocketChannel creation. - *

- * Use it with xinetd/inetd, to launch an instance of Jetty on demand. The port + *

Sets whether this connector uses a channel inherited from the JVM.

+ *

If true, the connector first tries to inherit from a channel provided by the system. + * If there is no inherited channel available, or if the inherited channel is not usable, + * then it will fall back using {@link ServerSocketChannel}.

+ *

Use it with xinetd/inetd, to launch an instance of Jetty on demand. The port * used to access pages on the Jetty instance is the same as the port used to - * launch Jetty. - * + * launch Jetty.

+ * + * @param inheritChannel whether this connector uses a channel inherited from the JVM. */ public void setInheritChannel(boolean inheritChannel) { _inheritChannel = inheritChannel; } + @Override + public void open() throws IOException + { + if (_acceptChannel == null) + { + ServerSocketChannel serverChannel = null; + if (isInheritChannel()) + { + Channel channel = System.inheritedChannel(); + if (channel instanceof ServerSocketChannel) + serverChannel = (ServerSocketChannel)channel; + else + logger.warn("Unable to use System.inheritedChannel() [{}]. Trying a new ServerSocketChannel at {}:{}", channel, getHost(), getPort()); + } + + if (serverChannel == null) + { + serverChannel = ServerSocketChannel.open(); + + InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort()); + serverChannel.socket().bind(bindAddress, getAcceptQueueSize()); + serverChannel.socket().setReuseAddress(getReuseAddress()); + + _localPort = serverChannel.socket().getLocalPort(); + if (_localPort <= 0) + throw new IOException("Server channel not bound"); + + addBean(serverChannel); + } + + serverChannel.configureBlocking(true); + addBean(serverChannel); + + _acceptChannel = serverChannel; + } + } + + @Override + public void close() throws IOException + { + ServerSocketChannel serverChannel = _acceptChannel; + if (serverChannel != null) + { + removeBean(serverChannel); + if (serverChannel.isOpen()) + serverChannel.close(); + } + _acceptChannel = null; + _localPort = -2; + } + @Override public void accept(int acceptorID) throws IOException { - ServerSocketChannel server; - synchronized(this) + ServerSocketChannel serverChannel = _acceptChannel; + if (serverChannel != null && serverChannel.isOpen()) { - server = _acceptChannel; - } - - if (server!=null && server.isOpen() && _manager.isStarted()) - { - SocketChannel channel = server.accept(); + SocketChannel channel = serverChannel.accept(); channel.configureBlocking(false); Socket socket = channel.socket(); configure(socket); @@ -156,19 +175,19 @@ public class SelectChannelConnector extends AbstractNetConnector } } - @Override - public void close() throws IOException + protected void configure(Socket socket) { - synchronized(this) + try { - if (_acceptChannel != null) - { - removeBean(_acceptChannel); - if (_acceptChannel.isOpen()) - _acceptChannel.close(); - } - _acceptChannel = null; - _localPort=-2; + socket.setTcpNoDelay(true); + if (_lingerTime >= 0) + socket.setSoLinger(true, _lingerTime / 1000); + else + socket.setSoLinger(false, 0); + } + catch (SocketException e) + { + logger.ignore(e); } } @@ -178,7 +197,7 @@ public class SelectChannelConnector extends AbstractNetConnector } @Override - public synchronized Object getTransport() + public Object getTransport() { return _acceptChannel; } @@ -186,64 +205,12 @@ public class SelectChannelConnector extends AbstractNetConnector @Override public int getLocalPort() { - synchronized(this) - { - return _localPort; - } - } - - @Override - public void open() throws IOException - { - synchronized(this) - { - if (_acceptChannel == null) - { - if (_inheritChannel) - { - Channel channel = System.inheritedChannel(); - if ( channel instanceof ServerSocketChannel ) - _acceptChannel = (ServerSocketChannel)channel; - else - LOG.warn("Unable to use System.inheritedChannel() [" +channel+ "]. Trying a new ServerSocketChannel at " + getHost() + ":" + getPort()); - } - - if (_acceptChannel == null) - { - // Create a new server socket - _acceptChannel = ServerSocketChannel.open(); - - // Bind the server socket to the local host and port - _acceptChannel.socket().setReuseAddress(getReuseAddress()); - InetSocketAddress addr = getHost()==null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort()); - _acceptChannel.socket().bind(addr,getAcceptQueueSize()); - - _localPort=_acceptChannel.socket().getLocalPort(); - if (_localPort<=0) - throw new IOException("Server channel not bound"); - - addBean(_acceptChannel); - } - - _acceptChannel.configureBlocking(true); - addBean(_acceptChannel); - } - } - } - - - /* - * @see org.eclipse.jetty.server.server.AbstractConnector#doStart() - */ - @Override - protected void doStart() throws Exception - { - super.doStart(); + return _localPort; } protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException { - return new SelectChannelEndPoint(channel,selectSet,key, getScheduler(), getIdleTimeout()); + return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout()); } protected void endPointClosed(EndPoint endpoint) @@ -251,12 +218,68 @@ public class SelectChannelConnector extends AbstractNetConnector connectionClosed(endpoint.getConnection()); } - /* ------------------------------------------------------------ */ + protected Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment) + { + return getDefaultConnectionFactory().newConnection(channel, endPoint, attachment); + } + + /** + * @return the linger time + * @see Socket#getSoLinger() + */ + public int getLingerTime() + { + return _lingerTime; + } + + /** + * @param lingerTime the linger time. Use -1 to disable. + * @see Socket#setSoLinger(boolean, int) + */ + public void setSoLingerTime(int lingerTime) + { + _lingerTime = lingerTime; + } + + /** + * @return the accept queue size + */ + public int getAcceptQueueSize() + { + return _acceptQueueSize; + } + + /** + * @param acceptQueueSize the accept queue size (also known as accept backlog) + */ + public void setAcceptQueueSize(int acceptQueueSize) + { + _acceptQueueSize = acceptQueueSize; + } + + /** + * @return whether the server socket reuses addresses + * @see ServerSocket#getReuseAddress() + */ + public boolean getReuseAddress() + { + return _reuseAddress; + } + + /** + * @param reuseAddress whether the server socket reuses addresses + * @see ServerSocket#setReuseAddress(boolean) + */ + public void setReuseAddress(boolean reuseAddress) + { + _reuseAddress = reuseAddress; + } + private final class ConnectorSelectorManager extends SelectorManager { - private ConnectorSelectorManager(int selectSets) + private ConnectorSelectorManager(int selectors) { - super(selectSets); + super(selectors); } @Override @@ -266,18 +289,17 @@ public class SelectChannelConnector extends AbstractNetConnector } @Override - protected void endPointClosed(EndPoint endpoint) + public void connectionOpened(Connection connection) { - SelectChannelConnector.this.connectionClosed(endpoint.getConnection()); - super.endPointClosed(endpoint); + super.connectionOpened(connection); + SelectChannelConnector.this.connectionOpened(connection); } @Override - protected void endPointOpened(EndPoint endpoint) + public void connectionClosed(Connection connection) { - // TODO handle max connections and low resources - super.endPointOpened(endpoint); - SelectChannelConnector.this.connectionOpened(endpoint.getConnection()); + super.connectionClosed(connection); + SelectChannelConnector.this.connectionClosed(connection); } @Override @@ -290,13 +312,13 @@ public class SelectChannelConnector extends AbstractNetConnector @Override protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey selectionKey) throws IOException { - return SelectChannelConnector.this.newEndPoint(channel,selectSet, selectionKey); + return SelectChannelConnector.this.newEndPoint(channel, selectSet, selectionKey); } @Override public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment) throws IOException { - return getConnectionFactory().newConnection(SelectChannelConnector.this,endpoint); + return SelectChannelConnector.this.newConnection(channel, endpoint, attachment); } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 3e521cb38cb..01567c90d3a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -4,7 +4,7 @@ // 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 @@ -16,14 +16,12 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Enumeration; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.server.Connector.NetConnector; import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.AttributesMap; @@ -117,7 +115,7 @@ public class Server extends HandlerWrapper implements Attributes addBean(_threadPool,pool==null); setServer(this); } - + /* ------------------------------------------------------------ */ public static String getVersion() @@ -148,15 +146,15 @@ public class Server extends HandlerWrapper implements Attributes { //and we weren't stopping before if (!_stopAtShutdown) - { + { //only register to stop if we're already started (otherwise we'll do it in doStart()) - if (isStarted()) + if (isStarted()) ShutdownThread.register(this); } } else ShutdownThread.deregister(this); - + _stopAtShutdown=stop; } @@ -302,8 +300,8 @@ public class Server extends HandlerWrapper implements Attributes for (int i=_connectors.length;i-->0;) { LOG.info("Graceful shutdown {}",_connectors[i]); - if (_connectors[i] instanceof NetConnector) - ((NetConnector)_connectors[i]).close(); + if (_connectors[i] instanceof NetworkConnector) + ((NetworkConnector)_connectors[i]).close(); } } @@ -457,7 +455,7 @@ public class Server extends HandlerWrapper implements Attributes } /* ------------------------------------------------------------ */ - /** + /** */ @Deprecated public int getMaxCookieVersion() @@ -466,7 +464,7 @@ public class Server extends HandlerWrapper implements Attributes } /* ------------------------------------------------------------ */ - /** + /** */ @Deprecated public void setMaxCookieVersion(int maxCookieVersion) 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 28480c3d00c..3af72199c3a 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 @@ -24,10 +24,10 @@ import org.eclipse.jetty.util.ssl.SslContextFactory; * @deprecated use SelectChannelConnector with {@link SslContextFactory} * @org.apache.xbean.XBean element="sslConnector" description="Creates an NIO ssl connector" */ -public class SslSelectChannelConnector extends SelectChannelConnector +public class SslSelectChannelConnector extends SelectChannelConnector { public SslSelectChannelConnector(Server server) { - super(server,true); + super(server,new SslContextFactory()); } } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java index 04bcc873713..ac6d802e78a 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/CheckReverseProxyHeadersTest.java @@ -13,12 +13,7 @@ package org.eclipse.jetty.server; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.io.IOException; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -26,6 +21,10 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.handler.AbstractHandler; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + /** * */ @@ -94,9 +93,10 @@ public class CheckReverseProxyHeadersTest { Server server = new Server(); LocalConnector connector = new LocalConnector(server); - // Activate reverse proxy headers checking - connector.getConnectionFactory().getHttpConfig().setForwarded(true); + HttpConfiguration httpConfiguration = new HttpConfiguration(null, false); + httpConfiguration.setForwarded(true); + connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector, httpConfiguration)); server.setConnectors(new Connector[] {connector}); ValidationHandler validationHandler = new ValidationHandler(requestValidator); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java index 61952dc3b47..a44fa4c0d35 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java @@ -19,16 +19,9 @@ */ package org.eclipse.jetty.server; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.IOException; import java.io.PrintWriter; import java.util.concurrent.TimeUnit; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -45,6 +38,12 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * */ @@ -61,8 +60,10 @@ public class HttpConnectionTest server = new Server(); connector = new LocalConnector(server); server.addConnector(connector); - connector.getConnectionFactory().getHttpConfig().setRequestHeaderSize(1024); - connector.getConnectionFactory().getHttpConfig().setResponseHeaderSize(1024); + HttpConfiguration httpConfiguration = new HttpConfiguration(null, false); + httpConfiguration.setRequestHeaderSize(1024); + httpConfiguration.setResponseHeaderSize(1024); + connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector, httpConfiguration)); server.setHandler(new DumpHandler()); server.start(); } @@ -135,7 +136,7 @@ public class HttpConnectionTest offset = checkContains(response,offset,"HTTP/1.1 200"); checkContains(response,offset,"/R1"); } - + @Test public void testHead() throws Exception { @@ -143,15 +144,15 @@ public class HttpConnectionTest "Host: localhost\015\012"+ "Connection: close\015\012"+ "\015\012"); - + String responseHEAD=connector.getResponses("HEAD /R1 HTTP/1.1\015\012"+ "Host: localhost\015\012"+ "Connection: close\015\012"+ "\015\012"); - + assertThat(responsePOST,startsWith(responseHEAD.substring(0,responseHEAD.length()-2))); assertThat(responsePOST.length(),greaterThan(responseHEAD.length())); - + responsePOST=connector.getResponses("POST /R1 HTTP/1.1\015\012"+ "Host: localhost\015\012"+ "Connection: close\015\012"+ @@ -413,7 +414,7 @@ public class HttpConnectionTest { String response = null; int offset = 0; - + StringBuilder request = new StringBuilder(); request.append("GET / HTTP/1.1\n"); request.append("Host: localhost\n"); @@ -422,7 +423,7 @@ public class HttpConnectionTest request.append(String.format("X-Header-%04d: %08x\n", i, i)); } request.append("\015\012"); - + response = connector.getResponses(request.toString()); checkContains(response, offset, "HTTP/1.1 413"); } @@ -434,8 +435,8 @@ public class HttpConnectionTest for (int i=0;i<500;i++) str+="xxxxxxxxxxxx"; final String longstr = str; - - String response = null; + + String response = null; server.stop(); server.setHandler(new DumpHandler() { @@ -488,8 +489,8 @@ public class HttpConnectionTest for (int i=0;i<500;i++) str+="xxxxxxxxxxxx"; final String longstr = str; - - String response = null; + + String response = null; server.stop(); server.setHandler(new DumpHandler() { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java index 5e6822a0670..f63f63d4f53 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java @@ -19,7 +19,6 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; import java.net.Socket; - import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; import javax.servlet.ServletException; @@ -39,9 +38,9 @@ public class HttpServerTestFixture protected static final long PAUSE=10L; protected static final int LOOPS=Stress.isEnabled()?250:50; protected static final String HOST="localhost"; - + protected static Server _server; - protected static Connector.NetConnector _connector; + protected static NetworkConnector _connector; protected String _scheme="http"; protected Socket newSocket(String host,int port) throws Exception @@ -52,14 +51,14 @@ public class HttpServerTestFixture socket.setSoLinger(false,0); return socket; } - + @BeforeClass public static void before() { _server = new Server(); } - - protected static void startServer(Connector.NetConnector connector) throws Exception + + protected static void startServer(NetworkConnector connector) throws Exception { _connector = connector; _server.addConnector(_connector); @@ -81,20 +80,20 @@ public class HttpServerTestFixture current.setHandler(handler); current.start(); } - + protected static class EchoHandler extends AbstractHandler { boolean musthavecontent=true; - + public EchoHandler() {} - + public EchoHandler(boolean content) { musthavecontent=false; } - + @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -111,7 +110,7 @@ public class HttpServerTestFixture int count=0; BufferedReader reader=request.getReader(); - + if (request.getContentLength()!=0) { String line=reader.readLine(); @@ -123,7 +122,7 @@ public class HttpServerTestFixture line=reader.readLine(); } } - + if (count==0) { if (musthavecontent) @@ -131,7 +130,7 @@ public class HttpServerTestFixture writer.println("No content"); } - + // just to be difficult reader.close(); writer.close(); @@ -171,7 +170,7 @@ public class HttpServerTestFixture String data = "\u0a870123456789A\u0a87CDEFGHIJKLMNOPQRSTUVWXYZ\u0250bcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; while (data.length() results = new ArrayList(); _handler._checker = new RequestTester() { @@ -326,8 +328,8 @@ public class RequestTest "x-forwarded-for: remote\n"+ "x-forwarded-proto: https\n"+ "\n",10,TimeUnit.SECONDS); - - + + int i=0; assertEquals("0.0.0.0",results.get(i++)); assertEquals("myhost",results.get(i++)); @@ -920,7 +922,7 @@ public class RequestTest { ((Request)request).setHandled(true); - if (request.getContentLength()>0 + if (request.getContentLength()>0 && !MimeTypes.Type.FORM_ENCODED.asString().equals(request.getContentType()) && !request.getContentType().startsWith("multipart/form-data")) _content=IO.toString(request.getInputStream()); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index 4c620850869..875bdfa4da9 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -13,11 +13,6 @@ package org.eclipse.jetty.server; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; @@ -29,7 +24,6 @@ import java.util.Locale; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; - import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @@ -52,6 +46,11 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * */ @@ -89,7 +88,7 @@ public class ResponseTest super.onOpen(); fillInterested(); } - + @Override public void onFillable() { @@ -160,7 +159,7 @@ public class ResponseTest protected void commitResponse(ResponseInfo info, ByteBuffer content) throws IOException { } - + @Override public Connector getConnector() { @@ -600,7 +599,7 @@ public class ResponseTest }); server.start(); - Socket socket = new Socket("localhost",((Connector.NetConnector)server.getConnectors()[0]).getLocalPort()); + Socket socket = new Socket("localhost",((NetworkConnector)server.getConnectors()[0]).getLocalPort()); socket.getOutputStream().write("HEAD / HTTP/1.1\r\nHost: localhost\r\n\r\n".getBytes()); socket.getOutputStream().write("GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n".getBytes()); socket.getOutputStream().flush(); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelStatisticsTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelStatisticsTest.java index 5763e00db7c..43861169648 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelStatisticsTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SelectChannelStatisticsTest.java @@ -13,9 +13,6 @@ package org.eclipse.jetty.server; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -23,7 +20,6 @@ import java.io.PrintWriter; import java.net.Socket; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -40,12 +36,15 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class SelectChannelStatisticsTest { private static final Logger LOG = Log.getLogger(SelectChannelStatisticsTest.class); private static Server _server; - private static AbstractNetConnector _connector; + private static AbstractNetworkConnector _connector; private static CyclicBarrier _connect; private static CountDownLatch _closed; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/SlowClientWithPipelinedRequestTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/SlowClientWithPipelinedRequestTest.java index 3548f515f39..3cd3be1cfd7 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/SlowClientWithPipelinedRequestTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/SlowClientWithPipelinedRequestTest.java @@ -12,16 +12,14 @@ package org.eclipse.jetty.server; //You may elect to redistribute this code under either of these licenses. //======================================================================== -import static org.hamcrest.Matchers.lessThan; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; import java.util.Arrays; import java.util.concurrent.atomic.AtomicInteger; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -34,6 +32,8 @@ import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; +import static org.hamcrest.Matchers.lessThan; + public class SlowClientWithPipelinedRequestTest { private final AtomicInteger handles = new AtomicInteger(); @@ -43,23 +43,24 @@ public class SlowClientWithPipelinedRequestTest public void startServer(Handler handler) throws Exception { server = new Server(); - connector = new SelectChannelConnector(server,new ConnectionFactory() + connector = new SelectChannelConnector(server); + connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector) { @Override - protected Connection newConnection(Connector connector,EndPoint endpoint) + public Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment) { - return new HttpConnection(getHttpConfig(),connector,endpoint) + return new HttpConnection(getHttpConfiguration(), getConnector(), endPoint) { @Override - public synchronized void onFillable() + public void onFillable() { handles.incrementAndGet(); super.onFillable(); } }; } - },null,null,null,0,0); - + }); + server.addConnector(connector); connector.setPort(0); server.setHandler(handler); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/IPAccessHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/IPAccessHandlerTest.java index 9e7ee7cbf3b..e441e867f94 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/IPAccessHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/IPAccessHandlerTest.java @@ -4,18 +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.server.handler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import java.io.BufferedReader; import java.io.EOFException; import java.io.IOException; @@ -28,13 +25,13 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.Server; @@ -45,19 +42,22 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + @RunWith(Parameterized.class) public class IPAccessHandlerTest { private static Server _server; - private static Connector.NetConnector _connector; + private static NetworkConnector _connector; private static IPAccessHandler _handler; - + private String _white; private String _black; private String _host; private String _uri; private String _code; - + @BeforeClass public static void setUp() throws Exception @@ -78,7 +78,7 @@ public class IPAccessHandlerTest _server.setHandler(_handler); _server.start(); } - + /* ------------------------------------------------------------ */ @AfterClass public static void tearDown() @@ -86,7 +86,7 @@ public class IPAccessHandlerTest { _server.stop(); } - + /* ------------------------------------------------------------ */ public IPAccessHandlerTest(String white, String black, String host, String uri, String code) { @@ -96,7 +96,7 @@ public class IPAccessHandlerTest _uri = uri; _code = code; } - + /* ------------------------------------------------------------ */ @Test public void testHandler() @@ -104,7 +104,7 @@ public class IPAccessHandlerTest { _handler.setWhite(_white.split(";",-1)); _handler.setBlack(_black.split(";",-1)); - + String request = "GET " + _uri + " HTTP/1.1\n" + "Host: "+ _host + "\n\n"; Socket socket = new Socket("127.0.0.1", _connector.getLocalPort()); socket.setSoTimeout(5000); @@ -231,7 +231,7 @@ public class IPAccessHandlerTest return builder.toString(); } } - + /* ------------------------------------------------------------ */ @Parameters public static Collection data() { @@ -239,20 +239,20 @@ public class IPAccessHandlerTest // Empty lists {"", "", "127.0.0.1", "/", "200"}, {"", "", "127.0.0.1", "/dump/info", "200"}, - - // White list + + // White list {"127.0.0.1", "", "127.0.0.1", "/", "200"}, {"127.0.0.1", "", "127.0.0.1", "/dispatch", "200"}, {"127.0.0.1", "", "127.0.0.1", "/dump/info", "200"}, - + {"127.0.0.1|/", "", "127.0.0.1", "/", "200"}, {"127.0.0.1|/", "", "127.0.0.1", "/dispatch", "403"}, {"127.0.0.1|/", "", "127.0.0.1", "/dump/info", "403"}, - + {"127.0.0.1|/*", "", "127.0.0.1", "/", "200"}, {"127.0.0.1|/*", "", "127.0.0.1", "/dispatch", "200"}, {"127.0.0.1|/*", "", "127.0.0.1", "/dump/info", "200"}, - + {"127.0.0.1|/dump/*", "", "127.0.0.1", "/", "403"}, {"127.0.0.1|/dump/*", "", "127.0.0.1", "/dispatch", "403"}, {"127.0.0.1|/dump/*", "", "127.0.0.1", "/dump/info", "200"}, @@ -268,7 +268,7 @@ public class IPAccessHandlerTest {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/dump/info", "200"}, {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/dump/test", "200"}, {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/dump/fail", "403"}, - + {"127.0.0.0-2|", "", "127.0.0.1", "/", "200"}, {"127.0.0.0-2|", "", "127.0.0.1", "/dump/info", "200"}, @@ -290,20 +290,20 @@ public class IPAccessHandlerTest {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dump/info", "200"}, {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dump/test", "200"}, {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dump/fail", "403"}, - + // Black list {"", "127.0.0.1", "127.0.0.1", "/", "403"}, {"", "127.0.0.1", "127.0.0.1", "/dispatch", "403"}, {"", "127.0.0.1", "127.0.0.1", "/dump/info", "403"}, - + {"", "127.0.0.1|/", "127.0.0.1", "/", "403"}, {"", "127.0.0.1|/", "127.0.0.1", "/dispatch", "200"}, {"", "127.0.0.1|/", "127.0.0.1", "/dump/info", "200"}, - + {"", "127.0.0.1|/*", "127.0.0.1", "/", "403"}, {"", "127.0.0.1|/*", "127.0.0.1", "/dispatch", "403"}, {"", "127.0.0.1|/*", "127.0.0.1", "/dump/info", "403"}, - + {"", "127.0.0.1|/dump/*", "127.0.0.1", "/", "200"}, {"", "127.0.0.1|/dump/*", "127.0.0.1", "/dispatch", "200"}, {"", "127.0.0.1|/dump/*", "127.0.0.1", "/dump/info", "403"}, @@ -319,7 +319,7 @@ public class IPAccessHandlerTest {"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/dump/info", "403"}, {"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/dump/test", "403"}, {"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/dump/fail", "200"}, - + {"", "127.0.0.0-2|", "127.0.0.1", "/", "403"}, {"", "127.0.0.0-2|", "127.0.0.1", "/dump/info", "403"}, @@ -341,7 +341,7 @@ public class IPAccessHandlerTest {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dump/info", "403"}, {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dump/test", "403"}, {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dump/fail", "200"}, - + // Both lists {"127.0.0.1|/dump", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump", "200"}, {"127.0.0.1|/dump", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump/info", "403"}, @@ -355,7 +355,7 @@ public class IPAccessHandlerTest {"127.0.0.1|/dump/*", "127.0.0.1|/dump/test;127.0.0.1|/dump/fail", "127.0.0.1", "/dump/info", "200"}, {"127.0.0.1|/dump/*", "127.0.0.1|/dump/test;127.0.0.1|/dump/fail", "127.0.0.1", "/dump/test", "403"}, {"127.0.0.1|/dump/*", "127.0.0.1|/dump/test;127.0.0.1|/dump/fail", "127.0.0.1", "/dump/fail", "403"}, - + {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1|/dump/test", "127.0.0.1", "/dump", "403"}, {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1|/dump/test", "127.0.0.1", "/dump/info", "200"}, {"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1|/dump/test", "127.0.0.1", "/dump/test", "403"}, @@ -381,7 +381,7 @@ public class IPAccessHandlerTest {"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/dump/info", "200"}, {"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/dump/test", "403"}, {"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/dump/fail", "403"}, - + {"172.0.0.0-255", "", "127.0.0.1", "/", "403"}, {"172.0.0.0-255", "", "127.0.0.1", "/dump/info", "403"}, diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java index 7fd1acd5d4d..f3d44da3cb1 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java @@ -21,7 +21,6 @@ import java.io.OutputStream; import java.net.Socket; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; - import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; @@ -30,13 +29,13 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import junit.framework.TestCase; - import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.util.ssl.SslContextFactory; /** * HttpServer Tester. @@ -72,15 +71,15 @@ public class SSLCloseTest extends TestCase */ public void testClose() throws Exception { - Server server=new Server(); - SelectChannelConnector connector=new SelectChannelConnector(server,true); - String keystore = System.getProperty("user.dir")+File.separator+"src"+File.separator+"test"+File.separator+"resources"+File.separator+"keystore"; + SslContextFactory sslContextFactory = new SslContextFactory(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setKeyManagerPassword("keypwd"); + Server server=new Server(); + SelectChannelConnector connector=new SelectChannelConnector(server, sslContextFactory); connector.setPort(0); - connector.getConnectionFactory().getSslContextFactory().setKeyStorePath(keystore); - connector.getConnectionFactory().getSslContextFactory().setKeyStorePassword("storepwd"); - connector.getConnectionFactory().getSslContextFactory().setKeyManagerPassword("keypwd"); server.setConnectors(new Connector[] { connector }); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java index 171295a6da4..43a7a1bc9cd 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java @@ -18,11 +18,6 @@ package org.eclipse.jetty.server.ssl; -import static org.hamcrest.Matchers.greaterThan; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -33,7 +28,6 @@ import java.net.HttpURLConnection; import java.net.Socket; import java.net.SocketTimeoutException; import java.net.URL; - import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; @@ -43,7 +37,8 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpServerConnectionFactory; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.Server; @@ -56,6 +51,11 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + /** * */ @@ -85,23 +85,25 @@ public class SSLEngineTest private Server server; private SelectChannelConnector connector; - + @Before public void startServer() throws Exception { - server=new Server(); - connector=new SelectChannelConnector(server,true); String keystore = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath(); + SslContextFactory sslContextFactory = new SslContextFactory(); + sslContextFactory.setKeyStorePath(keystore); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setKeyManagerPassword("keypwd"); + server=new Server(); + connector=new SelectChannelConnector(server, sslContextFactory); connector.setPort(0); - SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory(); - cf.setKeyStorePath(keystore); - cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); - connector.getConnectionFactory().getHttpConfig().setRequestBufferSize(512); - connector.getConnectionFactory().getHttpConfig().setRequestHeaderSize(512); + HttpConfiguration httpConfiguration = new HttpConfiguration(sslContextFactory, true); + httpConfiguration.setRequestBufferSize(512); + httpConfiguration.setRequestHeaderSize(512); + connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector, httpConfiguration)); - server.setConnectors(new Connector[]{connector }); + server.addConnector(connector); } @After @@ -111,14 +113,13 @@ public class SSLEngineTest server.join(); } - @Test public void testHelloWorld() throws Exception { server.setHandler(new HelloWorldHandler()); server.start(); server.dumpStdErr(); - + SSLContext ctx=SSLContext.getInstance("TLS"); ctx.init(null,SslContextFactory.TRUST_ALL_CERTS,new java.security.SecureRandom()); @@ -141,13 +142,13 @@ public class SSLEngineTest assertThat(response,Matchers.containsString("200 OK")); assertThat(response,Matchers.containsString(HELLO_WORLD)); } - + @Test public void testBigResponse() throws Exception { server.setHandler(new HelloWorldHandler()); server.start(); - + SSLContext ctx=SSLContext.getInstance("TLS"); ctx.init(null,SslContextFactory.TRUST_ALL_CERTS,new java.security.SecureRandom()); @@ -175,7 +176,7 @@ public class SSLEngineTest { server.setHandler(new HelloWorldHandler()); server.start(); - + final int loops=20; final int numConns=20; @@ -384,5 +385,5 @@ public class SSLEngineTest response.flushBuffer(); } } - + } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java index dc7d7c6562e..8a43a6d0a44 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java @@ -26,7 +26,6 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; - import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManagerFactory; @@ -35,6 +34,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.ssl.SslContextFactory; @@ -45,30 +45,30 @@ import org.junit.Test; public class SSLSelectChannelConnectorLoadTest { private static Server server; - private static SslSelectChannelConnector connector; + private static SelectChannelConnector connector; private static SSLContext sslContext; @BeforeClass public static void startServer() throws Exception { - server = new Server(); - connector = new SslSelectChannelConnector(server); - server.addConnector(connector); - String keystorePath = System.getProperty("basedir", ".") + "/src/test/resources/keystore"; - SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory(); - cf.setKeyStorePath(keystorePath); - cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); - cf.setTrustStore(keystorePath); - cf.setTrustStorePassword("storepwd"); + SslContextFactory sslContextFactory = new SslContextFactory(); + sslContextFactory.setKeyStorePath(keystorePath); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setKeyManagerPassword("keypwd"); + sslContextFactory.setTrustStore(keystorePath); + sslContextFactory.setTrustStorePassword("storepwd"); + + server = new Server(); + connector = new SelectChannelConnector(server, sslContextFactory); + server.addConnector(connector); server.setHandler(new EmptyHandler()); server.start(); KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); - keystore.load(new FileInputStream(connector.getConnectionFactory().getSslContextFactory().getKeyStorePath()), "storepwd".toCharArray()); + keystore.load(new FileInputStream(keystorePath), "storepwd".toCharArray()); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keystore); sslContext = SSLContext.getInstance("SSL"); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java index 0068144bc1d..795aff2ee9c 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java @@ -12,14 +12,11 @@ // ======================================================================== package org.eclipse.jetty.server.ssl; -import static org.junit.Assert.assertEquals; - import java.io.FileInputStream; import java.io.OutputStream; import java.net.Socket; import java.security.KeyStore; import java.util.Arrays; - import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; @@ -31,6 +28,8 @@ import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; +import static org.junit.Assert.assertEquals; + /** * HttpServer Tester. */ @@ -40,48 +39,47 @@ public class SelectChannelServerSslTest extends HttpServerTestBase { _scheme="https"; } - + @Override protected Socket newSocket(String host, int port) throws Exception { return __sslContext.getSocketFactory().createSocket(host,port); } - + @BeforeClass public static void init() throws Exception - { - SelectChannelConnector connector = new SelectChannelConnector(_server,true); - + { String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore"; - SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory(); - cf.setKeyStorePath(keystorePath); - cf.setKeyStorePassword("storepwd"); - cf.setKeyManagerPassword("keypwd"); - cf.setTrustStore(keystorePath); - cf.setTrustStorePassword("storepwd"); + SslContextFactory sslContextFactory = new SslContextFactory(); + sslContextFactory.setKeyStorePath(keystorePath); + sslContextFactory.setKeyStorePassword("storepwd"); + sslContextFactory.setKeyManagerPassword("keypwd"); + sslContextFactory.setTrustStore(keystorePath); + sslContextFactory.setTrustStorePassword("storepwd"); + SelectChannelConnector connector = new SelectChannelConnector(_server, sslContextFactory); + startServer(connector); - KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); - keystore.load(new FileInputStream(connector.getConnectionFactory().getSslContextFactory().getKeyStorePath()), "storepwd".toCharArray()); + keystore.load(new FileInputStream(connector.getSslContextFactory().getKeyStorePath()), "storepwd".toCharArray()); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keystore); __sslContext = SSLContext.getInstance("TLS"); __sslContext.init(null, trustManagerFactory.getTrustManagers(), null); - + try { HttpsURLConnection.setDefaultHostnameVerifier(__hostnameverifier); - SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, SslContextFactory.TRUST_ALL_CERTS, new java.security.SecureRandom()); + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, SslContextFactory.TRUST_ALL_CERTS, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch(Exception e) { e.printStackTrace(); throw new RuntimeException(e); - } - } + } + } @Test public void testRequest2FixedFragments() throws Exception @@ -104,7 +102,7 @@ public class SelectChannelServerSslTest extends HttpServerTestBase // Write out the fragments for (int j=0; j factories = new LinkedHashMap<>(); private final Queue sessions = new ConcurrentLinkedQueue<>(); - private final ByteBufferPool bufferPool = new StandardByteBufferPool(); - private final Executor executor = new LazyExecutor(); - private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); private final ServerSessionFrameListener listener; - private final SslContextFactory sslContextFactory; - private volatile ConnectionFactory defaultConnectionFactory; private volatile int initialWindowSize = 65536; - public SPDYServerConnector(ServerSessionFrameListener listener) + public SPDYServerConnector(Server server, ServerSessionFrameListener listener) { - this(listener, null); + this(server, null, listener); } - public SPDYServerConnector(ServerSessionFrameListener listener, SslContextFactory sslContextFactory) + public SPDYServerConnector(Server server, SslContextFactory sslContextFactory, ServerSessionFrameListener listener) { + super(server, sslContextFactory); this.listener = listener; - this.sslContextFactory = sslContextFactory; - if (sslContextFactory != null) - addBean(sslContextFactory); - putAsyncConnectionFactory("spdy/3", new ServerSPDYAsyncConnectionFactory(SPDY.V3, bufferPool, executor, scheduler, listener)); - putAsyncConnectionFactory("spdy/2", new ServerSPDYAsyncConnectionFactory(SPDY.V2, bufferPool, executor, scheduler, listener)); - setDefaultAsyncConnectionFactory(getAsyncConnectionFactory("spdy/2")); - } - - public ByteBufferPool getByteBufferPool() - { - return bufferPool; - } - - public Executor getExecutor() - { - return executor; - } - - public ScheduledExecutorService getScheduler() - { - return scheduler; + putConnectionFactory("spdy/3", new ServerSPDYAsyncConnectionFactory(SPDY.V3, getByteBufferPool(), getExecutor(), getScheduler(), listener)); + putConnectionFactory("spdy/2", new ServerSPDYAsyncConnectionFactory(SPDY.V2, getByteBufferPool(), getExecutor(), getScheduler(), listener)); + setDefaultConnectionFactory(getConnectionFactory("spdy/2")); } public ServerSessionFrameListener getServerSessionFrameListener() @@ -96,11 +63,6 @@ public class SPDYServerConnector extends SelectChannelConnector return listener; } - public SslContextFactory getSslContextFactory() - { - return sslContextFactory; - } - @Override protected void doStart() throws Exception { @@ -112,83 +74,22 @@ public class SPDYServerConnector extends SelectChannelConnector protected void doStop() throws Exception { closeSessions(); - scheduler.shutdown(); super.doStop(); } - @Override - public void join() throws InterruptedException - { - scheduler.awaitTermination(0, TimeUnit.MILLISECONDS); - super.join(); - } - - public ConnectionFactory getAsyncConnectionFactory(String protocol) - { - synchronized (factories) - { - return factories.get(protocol); - } - } - - public ConnectionFactory putAsyncConnectionFactory(String protocol, ConnectionFactory factory) - { - synchronized (factories) - { - return factories.put(protocol, factory); - } - } - - public ConnectionFactory removeAsyncConnectionFactory(String protocol) - { - synchronized (factories) - { - return factories.remove(protocol); - } - } - - public Map getAsyncConnectionFactories() - { - synchronized (factories) - { - return new LinkedHashMap<>(factories); - } - } - - public void clearAsyncConnectionFactories() - { - synchronized (factories) - { - factories.clear(); - } - } - protected List provideProtocols() { - synchronized (factories) - { - return new ArrayList<>(factories.keySet()); - } - } - - public ConnectionFactory getDefaultAsyncConnectionFactory() - { - return defaultConnectionFactory; - } - - public void setDefaultAsyncConnectionFactory(ConnectionFactory defaultConnectionFactory) - { - this.defaultConnectionFactory = defaultConnectionFactory; + return new ArrayList<>(getConnectionFactories().keySet()); } @Override - protected Connection newConnection(final SocketChannel channel, EndPoint endPoint) + protected Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment) { + SslContextFactory sslContextFactory = getSslContextFactory(); if (sslContextFactory != null) { final SSLEngine engine = newSSLEngine(sslContextFactory, channel); - Executor executor = getExecutor(); - SslConnection sslConnection = new SslConnection(bufferPool, executor, endPoint, engine) + SslConnection sslConnection = new SslConnection(getByteBufferPool(), getExecutor(), endPoint, engine) { @Override public void onClose() @@ -199,7 +100,7 @@ public class SPDYServerConnector extends SelectChannelConnector }; final EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint(); - NextProtoNegoServerAsyncConnection connection = new NextProtoNegoServerAsyncConnection(channel, sslEndPoint, this); + NextProtoNegoServerConnection connection = new NextProtoNegoServerConnection(channel, sslEndPoint, this); sslEndPoint.setConnection(connection); getSelectorManager().connectionOpened(connection); @@ -209,7 +110,7 @@ public class SPDYServerConnector extends SelectChannelConnector } else { - ConnectionFactory connectionFactory = getDefaultAsyncConnectionFactory(); + ConnectionFactory connectionFactory = getDefaultConnectionFactory(); Connection connection = connectionFactory.newConnection(channel, endPoint, this); endPoint.setConnection(connection); return connection; @@ -225,7 +126,7 @@ public class SPDYServerConnector extends SelectChannelConnector { String peerHost = channel.socket().getInetAddress().getHostAddress(); int peerPort = channel.socket().getPort(); - SSLEngine engine = sslContextFactory.newSslEngine(peerHost, peerPort); + SSLEngine engine = sslContextFactory.newSSLEngine(peerHost, peerPort); engine.setUseClientMode(false); return engine; } @@ -265,7 +166,7 @@ public class SPDYServerConnector extends SelectChannelConnector this.initialWindowSize = initialWindowSize; } - public void replaceAsyncConnection(EndPoint endPoint, Connection connection) + public void replaceConnection(EndPoint endPoint, Connection connection) { Connection oldConnection = endPoint.getConnection(); endPoint.setConnection(connection); diff --git a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ServerSPDYAsyncConnectionFactory.java b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ServerSPDYAsyncConnectionFactory.java index 4419d74e238..6f857199776 100644 --- a/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ServerSPDYAsyncConnectionFactory.java +++ b/jetty-spdy/spdy-jetty/src/main/java/org/eclipse/jetty/spdy/ServerSPDYAsyncConnectionFactory.java @@ -17,9 +17,10 @@ import java.nio.channels.SocketChannel; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; +import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener; import org.eclipse.jetty.spdy.generator.Generator; import org.eclipse.jetty.spdy.parser.Parser; diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/AbstractTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/AbstractTest.java index ea99abd3e22..412a69b50b5 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/AbstractTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/AbstractTest.java @@ -56,13 +56,13 @@ public abstract class AbstractTest protected InetSocketAddress startServer(short version, ServerSessionFrameListener listener) throws Exception { + server = new Server(); if (connector == null) connector = newSPDYServerConnector(listener); if (listener == null) listener = connector.getServerSessionFrameListener(); - connector.setDefaultAsyncConnectionFactory(new ServerSPDYAsyncConnectionFactory(version, connector.getByteBufferPool(), connector.getExecutor(), connector.getScheduler(), listener)); + connector.setDefaultConnectionFactory(new ServerSPDYAsyncConnectionFactory(version, connector.getByteBufferPool(), connector.getExecutor(), connector.getScheduler(), listener)); connector.setPort(0); - server = new Server(); server.addConnector(connector); server.start(); return new InetSocketAddress("localhost", connector.getLocalPort()); @@ -70,7 +70,7 @@ public abstract class AbstractTest protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener) { - return new SPDYServerConnector(listener); + return new SPDYServerConnector(server, listener); } protected Session startClient(InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java index d6c4b600f72..16a1bda8df2 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLEngineLeakTest.java @@ -31,7 +31,7 @@ public class SSLEngineLeakTest extends AbstractTest protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener) { SslContextFactory sslContextFactory = newSslContextFactory(); - return new SPDYServerConnector(listener, sslContextFactory); + return new SPDYServerConnector(server, sslContextFactory, listener); } @Override diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLSynReplyTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLSynReplyTest.java index aa398e0073c..4ae19cfd466 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLSynReplyTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/SSLSynReplyTest.java @@ -27,7 +27,7 @@ public class SSLSynReplyTest extends SynReplyTest protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener) { SslContextFactory sslContextFactory = newSslContextFactory(); - return new SPDYServerConnector(listener, sslContextFactory); + return new SPDYServerConnector(server, sslContextFactory, listener); } @Override 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 0d609ddcb83..ba54030e6ef 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 @@ -39,7 +39,6 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; - import javax.net.ssl.CertPathTrustManagerParameters; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; @@ -295,7 +294,7 @@ public class SslContextFactory extends AbstractLifeCycle _context = (_sslProvider == null)?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider); _context.init(keyManagers,trustManagers,secureRandom); - SSLEngine engine=newSslEngine(); + SSLEngine engine= newSSLEngine(); LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols())); if (LOG.isDebugEnabled()) @@ -1390,20 +1389,19 @@ public class SslContextFactory extends AbstractLifeCycle } /* ------------------------------------------------------------ */ - public SSLEngine newSslEngine(String host,int port) + public SSLEngine newSSLEngine(String host, int port) { if (!isRunning()) throw new IllegalStateException("!STARTED"); SSLEngine sslEngine=isSessionCachingEnabled() ?_context.createSSLEngine(host, port) :_context.createSSLEngine(); - customize(sslEngine); return sslEngine; } /* ------------------------------------------------------------ */ - public SSLEngine newSslEngine() + public SSLEngine newSSLEngine() { if (!isRunning()) throw new IllegalStateException("!STARTED"); @@ -1428,17 +1426,11 @@ public class SslContextFactory extends AbstractLifeCycle } /* ------------------------------------------------------------ */ - public SSLEngine createSSLEngine(InetSocketAddress address) throws IOException + public SSLEngine newSSLEngine(InetSocketAddress address) { - SSLEngine engine = (address != null) - ?newSslEngine(address.getAddress().getHostAddress(), address.getPort()) - :newSslEngine(); - engine.setUseClientMode(false); - - customize(engine); - return engine; + return address != null ? newSSLEngine(address.getAddress().getHostAddress(), address.getPort()) : newSSLEngine(); } - + /* ------------------------------------------------------------ */ @Override public String toString() diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index e6da4d3e8d2..b224932a218 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -5,11 +5,11 @@ package org.eclipse.jetty.webapp; //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. //======================================================================== import java.io.File; @@ -23,6 +23,7 @@ import java.util.List; import java.util.regex.Pattern; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.PatternMatcher; @@ -40,15 +41,15 @@ public class WebInfConfiguration extends AbstractConfiguration public static final String TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured"; public static final String CONTAINER_JAR_PATTERN = "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern"; public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern"; - + /** * If set, to a list of URLs, these resources are added to the context - * resource base as a resource collection. + * resource base as a resource collection. */ public static final String RESOURCE_URLS = "org.eclipse.jetty.resources"; - + protected Resource _preUnpackBaseResource; - + @Override public void preConfigure(final WebAppContext context) throws Exception { @@ -56,16 +57,16 @@ public class WebInfConfiguration extends AbstractConfiguration File work = findWorkDirectory(context); if (work != null) makeTempDirectory(work, context, false); - + //Make a temp directory for the webapp if one is not already set resolveTempDirectory(context); - + //Extract webapp if necessary unpack (context); - + //Apply an initial ordering to the jars which governs which will be scanned for META-INF - //info and annotations. The ordering is based on inclusion patterns. + //info and annotations. The ordering is based on inclusion patterns. String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN); Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp)); tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN); @@ -78,7 +79,7 @@ public class WebInfConfiguration extends AbstractConfiguration public void matched(URI uri) throws Exception { context.getMetaData().addContainerJar(Resource.newResource(uri)); - } + } }; ClassLoader loader = context.getClassLoader(); while (loader != null && (loader instanceof URLClassLoader)) @@ -90,21 +91,21 @@ public class WebInfConfiguration extends AbstractConfiguration int i=0; for (URL u : urls) { - try + try { containerUris[i] = u.toURI(); } catch (URISyntaxException e) { containerUris[i] = new URI(u.toString().replaceAll(" ", "%20")); - } + } i++; } containerJarNameMatcher.match(containerPattern, containerUris, false); } loader = loader.getParent(); } - + //Apply ordering to WEB-INF/lib jars PatternMatcher webInfJarNameMatcher = new PatternMatcher () { @@ -112,10 +113,10 @@ public class WebInfConfiguration extends AbstractConfiguration public void matched(URI uri) throws Exception { context.getMetaData().addWebInfJar(Resource.newResource(uri)); - } + } }; List jars = findJars(context); - + //Convert to uris for matching URI[] uris = null; if (jars != null) @@ -127,9 +128,9 @@ public class WebInfConfiguration extends AbstractConfiguration uris[i++] = r.getURI(); } } - webInfJarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match + webInfJarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match } - + @Override public void configure(WebAppContext context) throws Exception @@ -157,7 +158,7 @@ public class WebInfConfiguration extends AbstractConfiguration if (lib.exists() || lib.isDirectory()) ((WebAppClassLoader)context.getClassLoader()).addJars(lib); } - + // Look for extra resource @SuppressWarnings("unchecked") List resources = (List)context.getAttribute(RESOURCE_URLS); @@ -177,23 +178,23 @@ public class WebInfConfiguration extends AbstractConfiguration { // delete temp directory if we had to create it or if it isn't called work Boolean tmpdirConfigured = (Boolean)context.getAttribute(TEMPDIR_CONFIGURED); - + if (context.getTempDirectory()!=null && (tmpdirConfigured == null || !tmpdirConfigured.booleanValue()) && !isTempWorkDirectory(context.getTempDirectory())) { IO.delete(context.getTempDirectory()); context.setTempDirectory(null); - + //clear out the context attributes for the tmp dir only if we had to //create the tmp dir context.setAttribute(TEMPDIR_CONFIGURED, null); context.setAttribute(WebAppContext.TEMPDIR, null); } - + //reset the base resource back to what it was before we did any unpacking of resources context.setBaseResource(_preUnpackBaseResource); } - + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.webapp.AbstractConfiguration#cloneConfigure(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.WebAppContext) @@ -217,7 +218,7 @@ public class WebInfConfiguration extends AbstractConfiguration * Get a temporary directory in which to unpack the war etc etc. * The algorithm for determining this is to check these alternatives * in the order shown: - * + * *

A. Try to use an explicit directory specifically for this webapp:

*
    *
  1. @@ -229,8 +230,8 @@ public class WebInfConfiguration extends AbstractConfiguration * this webapp && exists && writeable, then use it. Do NOT set delete on exit. *
  2. *
- * - *

B. Create a directory based on global settings. The new directory + * + *

B. Create a directory based on global settings. The new directory * will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost * Work out where to create this directory: *

    @@ -257,7 +258,7 @@ public class WebInfConfiguration extends AbstractConfiguration context.setAttribute(TEMPDIR_CONFIGURED, Boolean.TRUE); return; // Already have a suitable tmp dir configured } - + // No temp directory configured, try to establish one. // First we check the context specific, javax.servlet specified, temp directory attribute @@ -322,7 +323,7 @@ public class WebInfConfiguration extends AbstractConfiguration } } } - + /** * Given an Object, return File reference for object. * Typically used to convert anonymous Object from getAttribute() calls to a File object. @@ -353,7 +354,7 @@ public class WebInfConfiguration extends AbstractConfiguration { if (parent != null && parent.exists() && parent.canWrite() && parent.isDirectory()) { - String temp = getCanonicalNameForWebAppTmpDir(context); + String temp = getCanonicalNameForWebAppTmpDir(context); File tmpDir = new File(parent,temp); if (deleteExisting && tmpDir.exists()) @@ -362,7 +363,7 @@ public class WebInfConfiguration extends AbstractConfiguration { if(LOG.isDebugEnabled())LOG.debug("Failed to delete temp dir "+tmpDir); } - + //If we can't delete the existing tmp dir, create a new one if (tmpDir.exists()) { @@ -371,9 +372,9 @@ public class WebInfConfiguration extends AbstractConfiguration if (tmpDir.exists()) IO.delete(tmpDir); LOG.warn("Can't reuse "+old+", using "+tmpDir); - } + } } - + if (!tmpDir.exists()) tmpDir.mkdir(); @@ -388,13 +389,13 @@ public class WebInfConfiguration extends AbstractConfiguration context.setTempDirectory(tmpDir); } } - - + + public void unpack (WebAppContext context) throws IOException { Resource web_app = context.getBaseResource(); _preUnpackBaseResource = context.getBaseResource(); - + if (web_app == null) { String war = context.getWar(); @@ -425,7 +426,7 @@ public class WebInfConfiguration extends AbstractConfiguration if (web_app.exists() && ( (context.isCopyWebDir() && web_app.getFile() != null && web_app.getFile().isDirectory()) || (context.isExtractWAR() && web_app.getFile() != null && !web_app.getFile().isDirectory()) || - (context.isExtractWAR() && web_app.getFile() == null) || + (context.isExtractWAR() && web_app.getFile() == null) || !web_app.isDirectory()) ) { @@ -443,7 +444,7 @@ public class WebInfConfiguration extends AbstractConfiguration extractedWebAppDir=sibling; } } - + if (extractedWebAppDir==null) // Then extract it if necessary to the temporary location extractedWebAppDir= new File(context.getTempDirectory(), "webapp"); @@ -459,13 +460,13 @@ public class WebInfConfiguration extends AbstractConfiguration //Use a sentinel file that will exist only whilst the extraction is taking place. //This will help us detect interrupted extractions. File extractionLock = new File (context.getTempDirectory(), ".extract_lock"); - + if (!extractedWebAppDir.exists()) { //it hasn't been extracted before so extract it - extractionLock.createNewFile(); + extractionLock.createNewFile(); extractedWebAppDir.mkdir(); - LOG.info("Extract " + web_app + " to " + extractedWebAppDir); + LOG.info("Extract " + web_app + " to " + extractedWebAppDir); Resource jar_web_app = JarResource.newJarResource(web_app); jar_web_app.copyTo(extractedWebAppDir); extractionLock.delete(); @@ -484,7 +485,7 @@ public class WebInfConfiguration extends AbstractConfiguration extractionLock.delete(); } } - } + } web_app = Resource.newResource(extractedWebAppDir.getCanonicalPath()); } @@ -494,13 +495,13 @@ public class WebInfConfiguration extends AbstractConfiguration LOG.warn("Web application not found " + war); throw new java.io.FileNotFoundException(war); } - + context.setBaseResource(web_app); - + if (LOG.isDebugEnabled()) LOG.debug("webapp=" + web_app); } - + // Do we need to extract WEB-INF/lib? if (context.isCopyWebInf() && !context.isCopyWebDir()) @@ -544,11 +545,11 @@ public class WebInfConfiguration extends AbstractConfiguration if (LOG.isDebugEnabled()) LOG.debug("context.resourcebase = "+rc); - context.setBaseResource(rc); + context.setBaseResource(rc); } } - - + + public File findWorkDirectory (WebAppContext context) throws IOException { if (context.getBaseResource() != null) @@ -561,8 +562,8 @@ public class WebInfConfiguration extends AbstractConfiguration } return null; } - - + + /** * Check if the tmpDir itself is called "work", or if the tmpDir * is in a directory called "work". @@ -579,13 +580,13 @@ public class WebInfConfiguration extends AbstractConfiguration return false; return (t.getName().equalsIgnoreCase("work")); } - - + + /** * Create a canonical name for a webapp temp directory. * The form of the name is: * "Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36_hashcode_of_whole_string - * + * * host and port uniquely identify the server * context and virtual host uniquely identify the webapp * @return the canonical name for the webapp temp directory @@ -594,8 +595,8 @@ public class WebInfConfiguration extends AbstractConfiguration { StringBuffer canonicalName = new StringBuffer(); canonicalName.append("jetty-"); - - //get the host and the port from the first connector + + //get the host and the port from the first connector Server server=context.getServer(); if (server!=null) { @@ -606,9 +607,9 @@ public class WebInfConfiguration extends AbstractConfiguration //Get the host String host=null; int port=0; - if (connectors!=null && (connectors[0] instanceof Connector.NetConnector)) + if (connectors!=null && (connectors[0] instanceof NetworkConnector)) { - Connector.NetConnector connector = (Connector.NetConnector)connectors[0]; + NetworkConnector connector = (NetworkConnector)connectors[0]; host=connector.getHost(); port=connector.getLocalPort(); if (port < 0) @@ -617,18 +618,18 @@ public class WebInfConfiguration extends AbstractConfiguration if (host == null) host = "0.0.0.0"; canonicalName.append(host); - + //Get the port canonicalName.append("-"); - //if not available (eg no connectors or connector not started), + //if not available (eg no connectors or connector not started), //try getting one that was configured. canonicalName.append(port); canonicalName.append("-"); } } - + //Resource base try { @@ -637,11 +638,11 @@ public class WebInfConfiguration extends AbstractConfiguration { if (context.getWar()==null || context.getWar().length()==0) resource=context.newResource(context.getResourceBase()); - + // Set dir or WAR resource = context.newResource(context.getWar()); } - + String tmp = URIUtil.decodePath(resource.getURL().getPath()); if (tmp.endsWith("/")) tmp = tmp.substring(0, tmp.length()-1); @@ -656,13 +657,13 @@ public class WebInfConfiguration extends AbstractConfiguration { LOG.warn("Can't generate resourceBase as part of webapp tmp dir name", e); } - + //Context name String contextPath = context.getContextPath(); contextPath=contextPath.replace('/','_'); contextPath=contextPath.replace('\\','_'); canonicalName.append(contextPath); - + //Virtual host (if there is one) canonicalName.append("-"); String[] vhosts = context.getVirtualHosts(); @@ -670,43 +671,43 @@ public class WebInfConfiguration extends AbstractConfiguration canonicalName.append("any"); else canonicalName.append(vhosts[0]); - + // sanitize for (int i=0;i findJars (WebAppContext context) + protected List findJars (WebAppContext context) throws Exception { List jarResources = new ArrayList(); - + Resource web_inf = context.getWebInf(); if (web_inf==null || !web_inf.exists()) return null; - + Resource web_inf_lib = web_inf.addPath("/lib"); - - + + if (web_inf_lib.exists() && web_inf_lib.isDirectory()) { String[] files=web_inf_lib.list(); for (int f=0;files!=null && f