Merge branch 'jetty-9' of ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project into jetty-9

This commit is contained in:
Joakim Erdfelt 2012-08-03 09:37:58 -07:00
commit 744bd20a44
49 changed files with 1052 additions and 1196 deletions

View File

@ -22,6 +22,8 @@ import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler; 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.NCSARequestLog;
import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
@ -44,7 +46,7 @@ public class LikeJettyXml
// Setup Threadpool // Setup Threadpool
QueuedThreadPool threadPool = new QueuedThreadPool(); QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setMaxThreads(500); threadPool.setMaxThreads(500);
Server server = new Server(threadPool); Server server = new Server(threadPool);
server.manage(threadPool); server.manage(threadPool);
server.setDumpAfterStart(true); server.setDumpAfterStart(true);
@ -61,33 +63,35 @@ public class LikeJettyXml
SelectChannelConnector connector = new SelectChannelConnector(server); SelectChannelConnector connector = new SelectChannelConnector(server);
connector.setPort(8080); connector.setPort(8080);
connector.setIdleTimeout(30000); 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); // TODO connector.setStatsOn(false);
server.setConnectors(new Connector[] server.setConnectors(new Connector[]
{ connector }); { connector });
SelectChannelConnector ssl_connector = new SelectChannelConnector(server,true); SslContextFactory sslContextFactory = new SslContextFactory();
ssl_connector.setPort(8443); sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore");
SslContextFactory cf = ssl_connector.getConnectionFactory().getSslContextFactory(); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
cf.setKeyStorePath(jetty_home + "/etc/keystore"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setTrustStore(jetty_home + "/etc/keystore");
cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
cf.setTrustStore(jetty_home + "/etc/keystore"); sslContextFactory.setExcludeCipherSuites(
cf.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); new String[]{
cf.setExcludeCipherSuites( "SSL_RSA_WITH_DES_CBC_SHA",
new String[] { "SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_RSA_WITH_DES_CBC_SHA", "SSL_DHE_DSS_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA", "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_DHE_DSS_WITH_DES_CBC_SHA", "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_RSA_EXPORT_WITH_RC4_40_MD5", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_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); SelectChannelConnector sslConnector = new SelectChannelConnector(server,sslContextFactory);
server.addConnector(ssl_connector); sslConnector.setPort(8443);
ssl_connector.open(); // TODO sslConnector.setStatsOn(false);
server.addConnector(sslConnector);
sslConnector.open();
HandlerCollection handlers = new HandlerCollection(); HandlerCollection handlers = new HandlerCollection();
ContextHandlerCollection contexts = new ContextHandlerCollection(); ContextHandlerCollection contexts = new ContextHandlerCollection();

View File

@ -38,17 +38,17 @@ public class ManyConnectors
connector1.setPort(8888); connector1.setPort(8888);
connector1.setName("admin"); connector1.setName("admin");
SelectChannelConnector ssl_connector = new SelectChannelConnector(server,true);
String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution"); String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution");
System.setProperty("jetty.home",jetty_home); System.setProperty("jetty.home", jetty_home);
ssl_connector.setPort(8443); SslContextFactory sslContextFactory = new SslContextFactory();
SslContextFactory cf = ssl_connector.getConnectionFactory().getSslContextFactory(); sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore");
cf.setKeyStorePath(jetty_home + "/etc/keystore"); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); SelectChannelConnector sslConnector = new SelectChannelConnector(server,sslContextFactory);
sslConnector.setPort(8443);
server.setConnectors(new Connector[] server.setConnectors(new Connector[]
{ connector0, connector1, ssl_connector }); { connector0, connector1, sslConnector });
server.setHandler(new HelloHandler()); server.setHandler(new HelloHandler());

View File

@ -36,6 +36,7 @@ import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
@ -65,7 +66,7 @@ public class XmlConfiguredJetty
Properties properties = new Properties(); Properties properties = new Properties();
String jettyHomeBase = testdir.getDir().getAbsolutePath(); 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; int idx = 0;
_jettyHome = new File(jettyHomeBase + "#" + idx); _jettyHome = new File(jettyHomeBase + "#" + idx);
while (_jettyHome.exists()) while (_jettyHome.exists())
@ -412,9 +413,9 @@ public class XmlConfiguredJetty
Connector connectors[] = _server.getConnectors(); Connector connectors[] = _server.getConnectors();
for (int i = 0; _serverPort<0 && i < connectors.length; i++) 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) if (port>0)
_serverPort=port; _serverPort=port;
} }

View File

@ -33,6 +33,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -86,7 +87,7 @@ public class SelectChannelEndPointInterestsTest
super.onOpen(); super.onOpen();
fillInterested(); fillInterested();
} }
@Override @Override
public void onFillable() public void onFillable()
{ {
@ -98,6 +99,19 @@ public class SelectChannelEndPointInterestsTest
selectorManager.start(); 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 @Test
public void testReadBlockedThenWriteBlockedThenReadableThenWritable() throws Exception public void testReadBlockedThenWriteBlockedThenReadableThenWritable() throws Exception
{ {

View File

@ -1,11 +1,5 @@
package org.eclipse.jetty.io; 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.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
@ -13,7 +7,6 @@ import java.net.Socket;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLEngineResult.HandshakeStatus;
@ -28,6 +21,12 @@ import org.junit.BeforeClass;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; 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 public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
{ {
@ -55,7 +54,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
@Override @Override
protected Connection newConnection(SocketChannel channel, EndPoint endpoint) protected Connection newConnection(SocketChannel channel, EndPoint endpoint)
{ {
SSLEngine engine = __sslCtxFactory.newSslEngine(); SSLEngine engine = __sslCtxFactory.newSSLEngine();
engine.setUseClientMode(false); engine.setUseClientMode(false);
SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine); SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine);
@ -94,7 +93,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
server.configureBlocking(false); server.configureBlocking(false);
_manager.accept(server); _manager.accept(server);
SSLEngine engine = __sslCtxFactory.newSslEngine(); SSLEngine engine = __sslCtxFactory.newSSLEngine();
engine.setUseClientMode(true); engine.setUseClientMode(true);
engine.beginHandshake(); engine.beginHandshake();
@ -263,8 +262,8 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
@Test @Test
public void checkSslEngineBehaviour() throws Exception public void checkSslEngineBehaviour() throws Exception
{ {
SSLEngine server = __sslCtxFactory.newSslEngine(); SSLEngine server = __sslCtxFactory.newSSLEngine();
SSLEngine client = __sslCtxFactory.newSslEngine(); SSLEngine client = __sslCtxFactory.newSSLEngine();
ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize());

View File

@ -13,12 +13,10 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import junit.framework.Assert; import junit.framework.Assert;
import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
@ -52,7 +50,7 @@ public class SslConnectionTest
@Override @Override
public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment) public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment)
{ {
SSLEngine engine = __sslCtxFactory.newSslEngine(); SSLEngine engine = __sslCtxFactory.newSSLEngine();
engine.setUseClientMode(false); engine.setUseClientMode(false);
SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine); SslConnection sslConnection = new SslConnection(__byteBufferPool, _threadPool, endpoint, engine);
@ -120,7 +118,7 @@ public class SslConnectionTest
super.onOpen(); super.onOpen();
fillInterested(); fillInterested();
} }
@Override @Override
public void onClose() public void onClose()
{ {

View File

@ -13,12 +13,8 @@
package org.eclipse.jetty.security; package org.eclipse.jetty.security;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.containsString;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 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.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpServerConnectionFactory;
import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
@ -40,6 +37,9 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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) $ * @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(); _server = new Server();
_connector = new LocalConnector(_server); _connector = new LocalConnector(_server);
_connector.setIdleTimeout(300000); _connector.setIdleTimeout(300000);
_connector.getConnectionFactory().getHttpConfig().setIntegralPort(9998); HttpConfiguration httpConfiguration = new HttpConfiguration(null, false);
_connector.getConnectionFactory().getHttpConfig().setIntegralScheme("FTP"); httpConfiguration.setIntegralPort(9998);
_connector.getConnectionFactory().getHttpConfig().setConfidentialPort(9999); httpConfiguration.setIntegralScheme("FTP");
_connector.getConnectionFactory().getHttpConfig().setConfidentialScheme("SPDY"); httpConfiguration.setConfidentialPort(9999);
_connectorS = new LocalConnector(_server, httpConfiguration.setConfidentialScheme("SPDY");
new HttpConfiguration(null,false) _connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(_connector, httpConfiguration));
_connectorS = new LocalConnector(_server);
_connectorS.setDefaultConnectionFactory(new HttpServerConnectionFactory(_connectorS, new HttpConfiguration(null,false)
{ {
@Override @Override
public void customize(Request request) throws IOException public void customize(Request request) throws IOException
@ -83,7 +86,7 @@ public class DataConstraintsTest
{ {
return true; return true;
} }
}); }));
_server.setConnectors(new Connector[]{_connector,_connectorS}); _server.setConnectors(new Connector[]{_connector,_connectorS});
ContextHandler _context = new ContextHandler(); ContextHandler _context = new ContextHandler();

View File

@ -15,19 +15,16 @@ package org.eclipse.jetty.server;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory; 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.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.StandardByteBufferPool; 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.AggregateLifeCycle;
import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log; 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; import org.eclipse.jetty.util.ssl.SslContextFactory;
/** /**
* Abstract Connector implementation. This abstract implementation of the Connector interface provides: * <p>Partial implementation of {@link Connector}</p>
* <ul>
* <li>AbstractLifeCycle implementation</li>
* <li>Implementations for connector getters and setters</li>
* <li>Buffer management</li>
* <li>Socket configuration</li>
* <li>Base acceptor thread</li>
* <li>Optional reverse proxy headers checking</li>
* </ul>
*/ */
public abstract class AbstractConnector extends AggregateLifeCycle implements Connector, Dumpable 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<String, ConnectionFactory> factories = new LinkedHashMap<>();
private final Statistics _stats = new ConnectionStatistics(); private final Statistics _stats = new ConnectionStatistics();
private final ConnectionFactory _connectionFactory; private final Server _server;
private final Thread[] _acceptors; private final SslContextFactory _sslContextFactory;
private final Executor _executor; private final Executor _executor;
private final ScheduledExecutorService _scheduler; private final ScheduledExecutorService _scheduler;
private final Server _server;
private final ByteBufferPool _byteBufferPool; private final ByteBufferPool _byteBufferPool;
private final Thread[] _acceptors;
private volatile String _name; private volatile String _name;
private volatile int _acceptQueueSize = 128;
private volatile boolean _reuseAddress = true;
private volatile long _idleTimeout = 200000; 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 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 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 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. * @param acceptors the number of acceptor threads to use, or 0 for a default value.
*/ */
public AbstractConnector( public AbstractConnector(
Server server, Server server,
ConnectionFactory connectionFactory, Executor executor,
Executor executor, ScheduledExecutorService scheduler,
ScheduledExecutorService scheduler, ByteBufferPool pool,
ByteBufferPool pool, int acceptors) SslContextFactory sslContextFactory,
int acceptors)
{ {
_server=server; _server=server;
_executor=executor!=null?executor:_server.getThreadPool(); _executor=executor!=null?executor:_server.getThreadPool();
@ -86,23 +73,22 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
@Override @Override
public Thread newThread(Runnable r) public Thread newThread(Runnable r)
{ {
return new Thread(r, "Timer-" + getName()); return new Thread(r, "Scheduler-" + getName());
} }
}); });
_byteBufferPool = pool!=null?pool:new StandardByteBufferPool(); _byteBufferPool = pool!=null?pool:new StandardByteBufferPool();
_sslContextFactory = sslContextFactory;
_connectionFactory=connectionFactory!=null?connectionFactory:new ConnectionFactory();
addBean(_server,false); addBean(_server,false);
addBean(_executor,false); addBean(_executor,false);
addBean(_scheduler,scheduler==null); addBean(_scheduler,scheduler==null);
addBean(_byteBufferPool,pool==null); addBean(_byteBufferPool,pool==null);
addBean(_connectionFactory,connectionFactory!=null); addBean(_sslContextFactory,true);
if (acceptors<=0) if (acceptors<=0)
acceptors=Math.max(1,(Runtime.getRuntime().availableProcessors()) / 4); acceptors=Math.max(1,(Runtime.getRuntime().availableProcessors()) / 4);
if (acceptors > 2 * Runtime.getRuntime().availableProcessors()) 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]; _acceptors = new Thread[acceptors];
} }
@ -117,13 +103,7 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
{ {
return _server; return _server;
} }
@Override
public ConnectionFactory getConnectionFactory()
{
return _connectionFactory;
}
@Override @Override
public Executor getExecutor() public Executor getExecutor()
{ {
@ -136,9 +116,11 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
return _byteBufferPool; return _byteBufferPool;
} }
/** public SslContextFactory getSslContextFactory()
* @return Returns the maxIdleTime. {
*/ return _sslContextFactory;
}
@Override @Override
public long getIdleTimeout() 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 * <p>Sets the maximum Idle time for a connection, which roughly translates to the {@link Socket#setSoTimeout(int)}
* other mechanisms may be used to implement the timeout. The max idle time is applied: * call, although with NIO implementations other mechanisms may be used to implement the timeout.</p>
* <p>The max idle time is applied:</p>
* <ul> * <ul>
* <li>When waiting for a new request to be received on a connection</li> * <li>When waiting for a new message to be received on a connection</li>
* <li>When reading the headers and content of a request</li> * <li>When waiting for a new message to be sent on a connection</li>
* <li>When writing the headers and content of a response</li>
* </ul> * </ul>
* Jetty interprets this value as the maximum time between some progress being made on the connection. So if a single byte is read or written, then the * <p>This value is interpreted as the maximum time between some progress being made on the connection.
* 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 * So if a single byte is read or written, then the timeout is reset.</p>
* 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.
* <p/>
* Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so
* these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand).
* *
* @param idleTimeout The idleTimeout to set. * @param idleTimeout the idle timeout
*/ */
public void setIdleTimeout(long idleTimeout) public void setIdleTimeout(long idleTimeout)
{ {
_idleTimeout = 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. * @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 @Override
protected void doStart() throws Exception protected void doStart() throws Exception
{ {
super.doStart(); super.doStart();
// Start selector thread for (int i = 0; i < _acceptors.length; i++)
synchronized (this) 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 @Override
protected void doStop() throws Exception protected void doStop() throws Exception
{ {
super.doStop();
for (Thread thread : _acceptors) for (Thread thread : _acceptors)
{ {
if (thread != null) if (thread != null)
thread.interrupt(); thread.interrupt();
} }
super.doStop();
logger.info("Stopped {}", this);
} }
public void join() throws InterruptedException public void join() throws InterruptedException
{ {
for (Thread thread : _acceptors) join(0);
if (thread != null)
thread.join();
} }
protected void configure(Socket socket) public void join(long timeout) throws InterruptedException
{ {
try for (Thread thread : _acceptors)
{ if (thread != null)
socket.setTcpNoDelay(true); thread.join(timeout);
if (_soLingerTime >= 0)
socket.setSoLinger(true, _soLingerTime / 1000);
else
socket.setSoLinger(false, 0);
}
catch (Exception e)
{
LOG.ignore(e);
}
} }
protected abstract void accept(int acceptorID) throws IOException, InterruptedException; 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<String, ConnectionFactory> 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 private class Acceptor implements Runnable
{ {
int _acceptor = 0; private final int _acceptor;
Acceptor(int id) private Acceptor(int id)
{ {
_acceptor = id; _acceptor = id;
} }
@ -275,22 +256,17 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
public void run() public void run()
{ {
Thread current = Thread.currentThread(); Thread current = Thread.currentThread();
String name; String name = current.getName();
current.setName(name + " Acceptor" + _acceptor + " " + AbstractConnector.this);
synchronized (AbstractConnector.this) synchronized (AbstractConnector.this)
{ {
if (!isRunning())
return;
_acceptors[_acceptor] = current; _acceptors[_acceptor] = current;
name = _acceptors[_acceptor].getName();
current.setName(name + " Acceptor" + _acceptor + " " + AbstractConnector.this);
} }
int old_priority = current.getPriority();
try try
{ {
current.setPriority(old_priority); while (isRunning())
while (isRunning() && getTransport() != null)
{ {
try try
{ {
@ -298,17 +274,16 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
} }
catch (IOException | InterruptedException e) catch (IOException | InterruptedException e)
{ {
LOG.ignore(e); logger.ignore(e);
} }
catch (Throwable e) catch (Throwable e)
{ {
LOG.warn(e); logger.warn(e);
} }
} }
} }
finally finally
{ {
current.setPriority(old_priority);
current.setName(name); current.setName(name);
synchronized (AbstractConnector.this) synchronized (AbstractConnector.this)
@ -350,22 +325,6 @@ public abstract class AbstractConnector extends AggregateLifeCycle implements Co
_stats.connectionClosed(duration, requests, requests); _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() public ScheduledExecutorService getScheduler()
{ {
return _scheduler; return _scheduler;

View File

@ -20,14 +20,17 @@ import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
public abstract class AbstractNetConnector extends AbstractConnector implements Connector.NetConnector /**
* <p>Partial implementation of {@link NetworkConnector}.</p>
*/
public abstract class AbstractNetworkConnector extends AbstractConnector implements NetworkConnector
{ {
private volatile String _host; private volatile String _host;
private volatile int _port = 0; 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) public void setHost(String host)
@ -74,14 +77,8 @@ public abstract class AbstractNetConnector extends AbstractConnector implements
@Override @Override
protected void doStop() throws Exception protected void doStop() throws Exception
{ {
try close();
{
close();
}
catch (IOException e)
{
LOG.warn(e);
}
super.doStop(); super.doStop();
int i = getName().lastIndexOf("/"); int i = getName().lastIndexOf("/");

View File

@ -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 // All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0 // are made available under the terms of the Eclipse Public License v1.0
@ -13,80 +13,22 @@
package org.eclipse.jetty.server; package org.eclipse.jetty.server;
import java.io.IOException; import java.nio.channels.SocketChannel;
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint; 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 * <p>Factory for {@link Connection}s.</p>
*/
public interface ConnectionFactory
{ {
private final boolean _ssl; /**
private final SslContextFactory _sslContextFactory; * <p>Creates a new {@link Connection} with the given parameters</p>
* @param channel the {@link SocketChannel} associated with the connection
* @param endPoint the {@link EndPoint} associated with the connection
// TODO Make this part of pluggable factory * @param attachment the attachment associated with the connection
private final HttpConfiguration _httpConfig; * @return a new {@link Connection}
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.
*/ */
ConnectionFactory(SslContextFactory sslContextFactory, boolean ssl) public Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment);
{
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;
}
} }

View File

@ -28,14 +28,14 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics
private final SampleStatistic _messagesOut = new SampleStatistic(); private final SampleStatistic _messagesOut = new SampleStatistic();
private final SampleStatistic _connectionDurationStats = new SampleStatistic(); private final SampleStatistic _connectionDurationStats = new SampleStatistic();
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public int getBytesIn() public int getBytesIn()
{ {
return -1; return -1;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
@ -185,7 +185,7 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics
return (start != -1)?(System.currentTimeMillis() - start):0; return (start != -1)?(System.currentTimeMillis() - start):0;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void doStart() public void doStart()
@ -193,12 +193,12 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics
statsReset(); statsReset();
_statsStartedAt.set(System.currentTimeMillis()); _statsStartedAt.set(System.currentTimeMillis());
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void doStop() public void doStop()
{ {
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -212,7 +212,7 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics
_connectionStats.reset(); _connectionStats.reset();
_connectionDurationStats.reset(); _connectionDurationStats.reset();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void connectionOpened() public void connectionOpened()
@ -223,19 +223,19 @@ class ConnectionStatistics extends AbstractLifeCycle implements Statistics
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void connectionUpgraded(long duration, int msgIn, int msgOut) public void connectionUpgraded(long duration, int messagesIn, int messagesOut)
{ {
_messagesIn.set(msgIn); _messagesIn.set(messagesIn);
_messagesOut.set(msgOut); _messagesOut.set(messagesOut);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void connectionClosed(long duration, int msgIn, int msgOut) public void connectionClosed(long duration, int messagesIn, int messagesOut)
{ {
_messagesIn.set(msgIn); _messagesIn.set(messagesIn);
_messagesOut.set(msgOut); _messagesOut.set(messagesOut);
_connectionStats.decrement(); _connectionStats.decrement();
_connectionDurationStats.set(duration); _connectionDurationStats.set(duration);
} }
} }

View File

@ -13,7 +13,6 @@
package org.eclipse.jetty.server; package org.eclipse.jetty.server;
import java.io.IOException;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService; 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.component.LifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
/** HTTP Connector. /**
* Implementations of this interface provide connectors for the HTTP protocol. * <p>A {@link Connector} accept connections and data from remote peers,
* A connector receives requests (normally from a socket) and calls the * and allows applications to send data to remote peers, by setting up
* handle method of the Handler object. These operations are performed using * the machinery needed to handle such tasks.</p>
* 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.
*
*/ */
public interface Connector extends LifeCycle 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. * @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 /**
* <p>{@link Connector} statistics.</p>
*/
public interface Statistics extends LifeCycle
{ {
/* ------------------------------------------------------------ */
/** /**
* Opens the connector * @return true if gathering of statistics is enabled
* @throws IOException
*/ */
void open() throws IOException; public boolean getStatsOn();
/* ------------------------------------------------------------ */
void close() throws IOException;
/* ------------------------------------------------------------ */
/** /**
* @return The hostname representing the interface to which * <p>Resets the statistics.</p>
* this connector will bind, or null for all interfaces.
*/ */
String getHost(); public void statsReset();
/* ------------------------------------------------------------ */
/** /**
* @return The configured port for the connector or 0 if any available * @return the number of messages received by this connector
* port may be used. * since last call to {@link #statsReset()}.
*/
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.
*/ */
public int getMessagesIn(); public int getMessagesIn();
/* ------------------------------------------------------------ */
/** /**
* @return Get the number of messages sent by this connector * @return the number of messages sent by this connector
* since last call of statsReset(). If setStatsOn(false) then this * since last call to {@link #statsReset()}.
* is undefined.
*/ */
public int getMessagesOut(); public int getMessagesOut();
/* ------------------------------------------------------------ */
/** /**
* @return Get the number of bytes received by this connector * @return the number of bytes received by this connector
* since last call of statsReset(). If setStatsOn(false) then this * since last call to {@link #statsReset()}.
* is undefined.
*/ */
public int getBytesIn(); public int getBytesIn();
/* ------------------------------------------------------------ */
/** /**
* @return Get the number of bytes sent by this connector * @return the number of bytes sent by this connector
* since last call of statsReset(). If setStatsOn(false) then this * since last call to {@link #statsReset()}.
* is undefined.
*/ */
public int getBytesOut(); 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(); public long getConnectionsDurationTotal();
/* ------------------------------------------------------------ */
/** /**
* @return Number of connections accepted by the server since * @return the number of connections accepted by the server
* statsReset() called. Undefined if setStatsOn(false). * since last call to {@link #statsReset()}.
*/ */
public int getConnections() ; public int getConnections() ;
/* ------------------------------------------------------------ */
/** /**
* @return Number of connections currently open that were opened * @return the number of connections currently open that were opened
* since statsReset() called. Undefined if setStatsOn(false). * since last call to {@link #statsReset()}.
*/ */
public int getConnectionsOpen() ; public int getConnectionsOpen() ;
/* ------------------------------------------------------------ */
/** /**
* @return Maximum number of connections opened simultaneously * @return the max number of connections opened simultaneously
* since statsReset() called. Undefined if setStatsOn(false). * since last call to {@link #statsReset()}.
*/ */
public int getConnectionsOpenMax() ; public int getConnectionsOpenMax() ;
/* ------------------------------------------------------------ */
/** /**
* @return Maximum duration in milliseconds of an open connection * @return the max time a connection has been open, in milliseconds,
* since statsReset() called. Undefined if setStatsOn(false). * since last call to {@link #statsReset()}.
*/ */
public long getConnectionsDurationMax(); public long getConnectionsDurationMax();
/* ------------------------------------------------------------ */
/** /**
* @return Mean duration in milliseconds of open connections * @return the mean time connections have been open, in milliseconds,
* since statsReset() called. Undefined if setStatsOn(false). * since last call to {@link #statsReset()}.
*/ */
public double getConnectionsDurationMean() ; public double getConnectionsDurationMean() ;
/* ------------------------------------------------------------ */
/** /**
* @return Standard deviation of duration in milliseconds of * @return the standard deviation of the time connections have been open, in milliseconds,
* open connections since statsReset() called. Undefined if * since last call to {@link #statsReset()}.
* setStatsOn(false).
*/ */
public double getConnectionsDurationStdDev() ; public double getConnectionsDurationStdDev() ;
/* ------------------------------------------------------------ */
/** /**
* @return Mean number of messages received per connection * @return the mean number of messages received per connection
* since statsReset() called. Undefined if setStatsOn(false). * since last call to {@link #statsReset()}.
*/ */
public double getConnectionsMessagesInMean() ; public double getConnectionsMessagesInMean() ;
/* ------------------------------------------------------------ */
/** /**
* @return Standard Deviation of number of messages received per connection * @return the standard deviation of the number of messages received per connection
* since statsReset() called. Undefined if setStatsOn(false). * since last call to {@link #statsReset()}.
*/ */
public double getConnectionsMessagesInStdDev() ; public double getConnectionsMessagesInStdDev() ;
/* ------------------------------------------------------------ */
/** /**
* @return Maximum number of messages received per connection * @return the max number of messages received by a connection
* since statsReset() called. Undefined if setStatsOn(false). * since last call to {@link #statsReset()}.
*/ */
public int getConnectionsMessagesInMax(); public int getConnectionsMessagesInMax();
/* ------------------------------------------------------------ */
/** /**
* @return Timestamp stats were started at. * @return the number of milliseconds the statistics have been started or reset
*/ */
public long getStatsOnMs(); public long getStatsOnMs();
void connectionOpened(); /**
* <p>Callback method invoked when a new connection is opened.</p>
*/
public void connectionOpened();
void connectionUpgraded(long duration, int requests, int requests2); /**
* <p>Callback method invoked when a connection is upgraded.</p>
void connectionClosed(long duration, int requests, int requests2); *
* @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);
/**
* <p>Callback method invoked when a connection is closed.</p>
*
* @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);
} }
} }

View File

@ -2,7 +2,6 @@ package org.eclipse.jetty.server;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
@ -21,10 +20,10 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
public class HttpConfiguration extends AggregateLifeCycle public class HttpConfiguration extends AggregateLifeCycle
{ {
static final Logger LOG = Log.getLogger(HttpConfiguration.class); static final Logger LOG = Log.getLogger(HttpConfiguration.class);
private final SslContextFactory _sslContextFactory; private final SslContextFactory _sslContextFactory;
private final boolean _ssl; private final boolean _ssl;
private String _integralScheme = HttpScheme.HTTPS.asString(); private String _integralScheme = HttpScheme.HTTPS.asString();
private int _integralPort = 0; private int _integralPort = 0;
private String _confidentialScheme = HttpScheme.HTTPS.asString(); private String _confidentialScheme = HttpScheme.HTTPS.asString();
@ -41,7 +40,7 @@ public class HttpConfiguration extends AggregateLifeCycle
private int _requestBufferSize=16*1024; private int _requestBufferSize=16*1024;
private int _responseHeaderSize=6*1024; private int _responseHeaderSize=6*1024;
private int _responseBufferSize=16*1024; private int _responseBufferSize=16*1024;
public HttpConfiguration(SslContextFactory sslContextFactory,boolean ssl) public HttpConfiguration(SslContextFactory sslContextFactory,boolean ssl)
{ {
_sslContextFactory=sslContextFactory!=null?sslContextFactory:ssl?new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH):null; _sslContextFactory=sslContextFactory!=null?sslContextFactory:ssl?new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH):null;
@ -49,7 +48,7 @@ public class HttpConfiguration extends AggregateLifeCycle
if (_sslContextFactory!=null) if (_sslContextFactory!=null)
addBean(_sslContextFactory,sslContextFactory==null); addBean(_sslContextFactory,sslContextFactory==null);
} }
public SslContextFactory getSslContextFactory() public SslContextFactory getSslContextFactory()
{ {
return _sslContextFactory; return _sslContextFactory;
@ -121,7 +120,7 @@ public class HttpConfiguration extends AggregateLifeCycle
* </ul> * </ul>
*/ */
public void customize(Request request) throws IOException public void customize(Request request) throws IOException
{ {
if (isSecure()) if (isSecure())
{ {
request.setScheme(HttpScheme.HTTPS.asString()); request.setScheme(HttpScheme.HTTPS.asString());
@ -130,7 +129,7 @@ public class HttpConfiguration extends AggregateLifeCycle
SSLEngine sslEngine=sslConnection.getSSLEngine(); SSLEngine sslEngine=sslConnection.getSSLEngine();
SslCertificates.customize(sslEngine,request); SslCertificates.customize(sslEngine,request);
} }
request.setTimeStamp(System.currentTimeMillis()); request.setTimeStamp(System.currentTimeMillis());
if (isForwarded()) if (isForwarded())
checkForwardedHeaders(request); checkForwardedHeaders(request);
@ -242,13 +241,13 @@ public class HttpConfiguration extends AggregateLifeCycle
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* The request is integral IFF it is secure AND the server port * 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 * This allows separation of listeners providing INTEGRAL versus
* CONFIDENTIAL constraints, such as one SSL listener configured to require * CONFIDENTIAL constraints, such as one SSL listener configured to require
* client certs providing CONFIDENTIAL, whereas another SSL listener not * client certs providing CONFIDENTIAL, whereas another SSL listener not
* requiring client certs providing mere INTEGRAL constraints. * requiring client certs providing mere INTEGRAL constraints.
* <p> * <p>
* 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()()} * and the scheme matches {@link #getIntegralScheme()()}
*/ */
public boolean isIntegral(Request request) 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 * 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 * This allows separation of listeners providing INTEGRAL versus
* CONFIDENTIAL constraints, such as one SSL listener configured to require * CONFIDENTIAL constraints, such as one SSL listener configured to require
* client certs providing CONFIDENTIAL, whereas another SSL listener not * client certs providing CONFIDENTIAL, whereas another SSL listener not
* requiring client certs providing mere INTEGRAL constraints. * requiring client certs providing mere INTEGRAL constraints.
* <p> * <p>
* 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()} * and the scheme matches {@link #getConfidentialScheme()}
*/ */
public boolean isConfidential(Request request) public boolean isConfidential(Request request)
@ -510,7 +509,7 @@ public class HttpConfiguration extends AggregateLifeCycle
{ {
_forwardedSslSessionIdHeader = forwardedSslSessionId; _forwardedSslSessionIdHeader = forwardedSslSessionId;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
@ -521,8 +520,8 @@ public class HttpConfiguration extends AggregateLifeCycle
_sslContextFactory.checkKeyStore(); _sslContextFactory.checkKeyStore();
super.doStart(); super.doStart();
SSLEngine sslEngine = _sslContextFactory.newSslEngine(); SSLEngine sslEngine = _sslContextFactory.newSSLEngine();
sslEngine.setUseClientMode(false); sslEngine.setUseClientMode(false);

View File

@ -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);
}
}
}

View File

@ -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));
}
}

View File

@ -23,50 +23,34 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.io.ByteArrayEndPoint; import org.eclipse.jetty.io.ByteArrayEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil; 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; import org.eclipse.jetty.util.ssl.SslContextFactory;
public class LocalConnector extends AbstractConnector public class LocalConnector extends AbstractConnector
{ {
private static final Logger LOG = Log.getLogger(LocalConnector.class);
private final BlockingQueue<LocalEndPoint> _connects = new LinkedBlockingQueue<>(); private final BlockingQueue<LocalEndPoint> _connects = new LinkedBlockingQueue<>();
public LocalConnector(Server server) public LocalConnector(Server server)
{ {
this(server,null,null,null,null, -1); this(server,null);
}
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());
} }
public LocalConnector(Server server, SslContextFactory sslContextFactory) public LocalConnector(Server server, SslContextFactory sslContextFactory)
{ {
this(server,new ConnectionFactory(sslContextFactory,sslContextFactory!=null),null,null,null,0); this(server, null, null, null, sslContextFactory, 0);
manage(getConnectionFactory());
} }
public LocalConnector(Server server, ConnectionFactory connectionFactory, Executor executor, ScheduledExecutorService scheduler, ByteBufferPool pool, public LocalConnector(Server server, Executor executor, ScheduledExecutorService scheduler, ByteBufferPool pool,
int acceptors) SslContextFactory sslContextFactory, int acceptors)
{ {
super(server,connectionFactory,executor,scheduler,pool,acceptors); super(server,executor,scheduler,pool, sslContextFactory, acceptors);
setIdleTimeout(30000); setIdleTimeout(30000);
setDefaultConnectionFactory(new HttpServerConnectionFactory(this));
} }
@Override @Override
public Object getTransport() public Object getTransport()
{ {
@ -77,7 +61,7 @@ public class LocalConnector extends AbstractConnector
* Returns all the responses received once the thread activity has * Returns all the responses received once the thread activity has
* returned to the level it was before the requests. * returned to the level it was before the requests.
* <p> * <p>
* 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. * is idle for 1s before returning the responses.
* @param requests the requests * @param requests the requests
* @return the responses * @return the responses
@ -93,7 +77,7 @@ public class LocalConnector extends AbstractConnector
* Returns all the responses received once the thread activity has * Returns all the responses received once the thread activity has
* returned to the level it was before the requests. * returned to the level it was before the requests.
* <p> * <p>
* 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. * an idle period before returning the responses.
* @param requests the requests * @param requests the requests
* @param idleFor The time the response stream must be idle for before returning * @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 * Returns all the responses received once the thread activity has
* returned to the level it was before the requests. * returned to the level it was before the requests.
* <p> * <p>
* 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. * is idle for 1s before returning the responses.
* @param requestsBuffer the requests * @param requestsBuffer the requests
* @return the responses * @return the responses
@ -126,7 +110,7 @@ public class LocalConnector extends AbstractConnector
* Returns all the responses received once the thread activity has * Returns all the responses received once the thread activity has
* returned to the level it was before the requests. * returned to the level it was before the requests.
* <p> * <p>
* 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. * an idle period before returning the responses.
* @param requestsBuffer the requests * @param requestsBuffer the requests
* @param idleFor The time the response stream must be idle for before returning * @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 public ByteBuffer getResponses(ByteBuffer requestsBuffer,long idleFor,TimeUnit units) throws Exception
{ {
LOG.debug("getResponses"); logger.debug("getResponses");
LocalEndPoint endp = new LocalEndPoint(); LocalEndPoint endp = new LocalEndPoint();
endp.setInput(requestsBuffer); endp.setInput(requestsBuffer);
_connects.add(endp); _connects.add(endp);
@ -161,16 +145,15 @@ public class LocalConnector extends AbstractConnector
@Override @Override
protected void accept(int acceptorID) throws IOException, InterruptedException protected void accept(int acceptorID) throws IOException, InterruptedException
{ {
LOG.debug("accepting {}",acceptorID); logger.debug("accepting {}", acceptorID);
LocalEndPoint endp = _connects.take(); LocalEndPoint endp = _connects.take();
Connection connection=getConnectionFactory().newConnection(LocalConnector.this,endp); Connection connection = getDefaultConnectionFactory().newConnection(null, endp, null);
endp.setConnection(connection); endp.setConnection(connection);
endp.onOpen(); endp.onOpen();
connection.onOpen(); connection.onOpen();
connectionOpened(connection); connectionOpened(connection);
} }
public class LocalEndPoint extends ByteArrayEndPoint public class LocalEndPoint extends ByteArrayEndPoint
{ {
private CountDownLatch _closed = new CountDownLatch(1); private CountDownLatch _closed = new CountDownLatch(1);
@ -232,7 +215,7 @@ public class LocalConnector extends AbstractConnector
} }
catch(Exception e) catch(Exception e)
{ {
LOG.warn(e); logger.warn(e);
} }
} }
} }
@ -254,10 +237,10 @@ public class LocalConnector extends AbstractConnector
} }
catch(Exception e) catch(Exception e)
{ {
LOG.warn(e); logger.warn(e);
} }
} }
} }
} }
} }

View File

@ -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;
/**
* <p>A {@link Connector} that handles network communication.</p>
*/
public interface NetworkConnector extends Connector, AutoCloseable
{
/**
* <p>Performs the activities needed to open the network communication
* (for example, to start accepting incoming network connections).</p>
*
* @throws IOException if this connector cannot be opened
* @see #close()
*/
void open() throws IOException;
/**
* <p>Performs the activities needed to close the network communication
* (for example, to stop accepting network connections).</p>
* @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();
}

View File

@ -15,7 +15,9 @@ package org.eclipse.jetty.server;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException;
import java.nio.channels.Channel; import java.nio.channels.Channel;
import java.nio.channels.SelectionKey; import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel; import java.nio.channels.ServerSocketChannel;
@ -23,10 +25,9 @@ import java.nio.channels.SocketChannel;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService; 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.Connection;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.SelectChannelEndPoint; import org.eclipse.jetty.io.SelectChannelEndPoint;
import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SelectorManager;
import org.eclipse.jetty.io.SelectorManager.ManagedSelector; 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; import org.eclipse.jetty.util.ssl.SslContextFactory;
/** /**
* Selecting NIO connector. * <p>Implementation of {@link NetworkConnector} based on NIO classes.</p>
* <p>
* 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.
* </p>
* <p>
* This connector is best used when there are a many connections that have idle periods.
* </p>
* <p>
* 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.
* </p>
*/ */
public class SelectChannelConnector extends AbstractNetConnector public class SelectChannelConnector extends AbstractNetworkConnector
{ {
private final SelectorManager _manager; private final SelectorManager _manager;
protected ServerSocketChannel _acceptChannel; private volatile ServerSocketChannel _acceptChannel;
protected boolean _inheritChannel; private volatile boolean _inheritChannel = false;
private int _localPort=-1; private volatile int _localPort = -1;
private volatile int _acceptQueueSize = 128;
/* ------------------------------------------------------------ */ private volatile boolean _reuseAddress = true;
private volatile int _lingerTime = -1;
public SelectChannelConnector(Server server) 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) public SelectChannelConnector(Server server, SslContextFactory sslContextFactory)
{ {
this(server,new ConnectionFactory(sslContextFactory,sslContextFactory!=null)); this(server, null, null, null, sslContextFactory, 0, 0);
manage(getConnectionFactory());
} }
/* ------------------------------------------------------------ */
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 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 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 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. * @param acceptors the number of acceptor threads to use, or 0 for a default value.
*/ */
public SelectChannelConnector( public SelectChannelConnector(
@Name("server") Server server, @Name("server") Server server,
@Name("connectionFactory") ConnectionFactory connectionFactory, @Name("executor") Executor executor,
@Name("executor") Executor executor, @Name("scheduler") ScheduledExecutorService scheduler,
@Name("scheduler") ScheduledExecutorService scheduler, @Name("bufferPool") ByteBufferPool pool,
@Name("bufferPool") ByteBufferPool pool, @Name("sslContextFactory") SslContextFactory sslContextFactory,
@Name("acceptors") int acceptors, @Name("acceptors") int acceptors,
@Name("selectors") int selectors) @Name("selectors") int selectors)
{ {
super(server,connectionFactory,executor,scheduler,pool,acceptors); super(server, executor, scheduler, pool, sslContextFactory, acceptors);
_manager=new ConnectorSelectorManager(selectors!=0?selectors:Math.max(1,(Runtime.getRuntime().availableProcessors())/4)); _manager = new ConnectorSelectorManager(selectors > 0 ? selectors : Math.max(1, (Runtime.getRuntime().availableProcessors()) / 4));
addBean(_manager,true); addBean(_manager, true);
// TODO yuck // TODO: why we need to set the linger time when in SSL mode ?
if (getConnectionFactory().getSslContextFactory()!=null) if (sslContextFactory != null)
setSoLingerTime(30000); 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() public boolean isInheritChannel()
{ {
return _inheritChannel; return _inheritChannel;
} }
/** /**
* If true, the connector first tries to inherit from a channel provided by the system. * <p>Sets whether this connector uses a channel inherited from the JVM.</p>
* If there is no inherited channel available, or if the inherited channel provided not usable, * <p>If true, the connector first tries to inherit from a channel provided by the system.
* then it will fall back upon normal ServerSocketChannel creation. * If there is no inherited channel available, or if the inherited channel is not usable,
* <p> * then it will fall back using {@link ServerSocketChannel}.</p>
* Use it with xinetd/inetd, to launch an instance of Jetty on demand. The port * <p>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 * used to access pages on the Jetty instance is the same as the port used to
* launch Jetty. * launch Jetty.</p>
* *
* @param inheritChannel whether this connector uses a channel inherited from the JVM.
*/ */
public void setInheritChannel(boolean inheritChannel) public void setInheritChannel(boolean inheritChannel)
{ {
_inheritChannel = 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 @Override
public void accept(int acceptorID) throws IOException public void accept(int acceptorID) throws IOException
{ {
ServerSocketChannel server; ServerSocketChannel serverChannel = _acceptChannel;
synchronized(this) if (serverChannel != null && serverChannel.isOpen())
{ {
server = _acceptChannel; SocketChannel channel = serverChannel.accept();
}
if (server!=null && server.isOpen() && _manager.isStarted())
{
SocketChannel channel = server.accept();
channel.configureBlocking(false); channel.configureBlocking(false);
Socket socket = channel.socket(); Socket socket = channel.socket();
configure(socket); configure(socket);
@ -156,19 +175,19 @@ public class SelectChannelConnector extends AbstractNetConnector
} }
} }
@Override protected void configure(Socket socket)
public void close() throws IOException
{ {
synchronized(this) try
{ {
if (_acceptChannel != null) socket.setTcpNoDelay(true);
{ if (_lingerTime >= 0)
removeBean(_acceptChannel); socket.setSoLinger(true, _lingerTime / 1000);
if (_acceptChannel.isOpen()) else
_acceptChannel.close(); socket.setSoLinger(false, 0);
} }
_acceptChannel = null; catch (SocketException e)
_localPort=-2; {
logger.ignore(e);
} }
} }
@ -178,7 +197,7 @@ public class SelectChannelConnector extends AbstractNetConnector
} }
@Override @Override
public synchronized Object getTransport() public Object getTransport()
{ {
return _acceptChannel; return _acceptChannel;
} }
@ -186,64 +205,12 @@ public class SelectChannelConnector extends AbstractNetConnector
@Override @Override
public int getLocalPort() public int getLocalPort()
{ {
synchronized(this) return _localPort;
{
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();
} }
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException 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) protected void endPointClosed(EndPoint endpoint)
@ -251,12 +218,68 @@ public class SelectChannelConnector extends AbstractNetConnector
connectionClosed(endpoint.getConnection()); 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 final class ConnectorSelectorManager extends SelectorManager
{ {
private ConnectorSelectorManager(int selectSets) private ConnectorSelectorManager(int selectors)
{ {
super(selectSets); super(selectors);
} }
@Override @Override
@ -266,18 +289,17 @@ public class SelectChannelConnector extends AbstractNetConnector
} }
@Override @Override
protected void endPointClosed(EndPoint endpoint) public void connectionOpened(Connection connection)
{ {
SelectChannelConnector.this.connectionClosed(endpoint.getConnection()); super.connectionOpened(connection);
super.endPointClosed(endpoint); SelectChannelConnector.this.connectionOpened(connection);
} }
@Override @Override
protected void endPointOpened(EndPoint endpoint) public void connectionClosed(Connection connection)
{ {
// TODO handle max connections and low resources super.connectionClosed(connection);
super.endPointOpened(endpoint); SelectChannelConnector.this.connectionClosed(connection);
SelectChannelConnector.this.connectionOpened(endpoint.getConnection());
} }
@Override @Override
@ -290,13 +312,13 @@ public class SelectChannelConnector extends AbstractNetConnector
@Override @Override
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey selectionKey) throws IOException 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 @Override
public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment) throws IOException public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment) throws IOException
{ {
return getConnectionFactory().newConnection(SelectChannelConnector.this,endpoint); return SelectChannelConnector.this.newConnection(channel, endpoint, attachment);
} }
} }
} }

View File

@ -4,7 +4,7 @@
// All rights reserved. This program and the accompanying materials // All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0 // are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution. // and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at // The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html // http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at // The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php // http://www.opensource.org/licenses/apache2.0.php
@ -16,14 +16,12 @@ package org.eclipse.jetty.server;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Enumeration; import java.util.Enumeration;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.Connector.NetConnector;
import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.AttributesMap; import org.eclipse.jetty.util.AttributesMap;
@ -117,7 +115,7 @@ public class Server extends HandlerWrapper implements Attributes
addBean(_threadPool,pool==null); addBean(_threadPool,pool==null);
setServer(this); setServer(this);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public static String getVersion() public static String getVersion()
@ -148,15 +146,15 @@ public class Server extends HandlerWrapper implements Attributes
{ {
//and we weren't stopping before //and we weren't stopping before
if (!_stopAtShutdown) if (!_stopAtShutdown)
{ {
//only register to stop if we're already started (otherwise we'll do it in doStart()) //only register to stop if we're already started (otherwise we'll do it in doStart())
if (isStarted()) if (isStarted())
ShutdownThread.register(this); ShutdownThread.register(this);
} }
} }
else else
ShutdownThread.deregister(this); ShutdownThread.deregister(this);
_stopAtShutdown=stop; _stopAtShutdown=stop;
} }
@ -302,8 +300,8 @@ public class Server extends HandlerWrapper implements Attributes
for (int i=_connectors.length;i-->0;) for (int i=_connectors.length;i-->0;)
{ {
LOG.info("Graceful shutdown {}",_connectors[i]); LOG.info("Graceful shutdown {}",_connectors[i]);
if (_connectors[i] instanceof NetConnector) if (_connectors[i] instanceof NetworkConnector)
((NetConnector)_connectors[i]).close(); ((NetworkConnector)_connectors[i]).close();
} }
} }
@ -457,7 +455,7 @@ public class Server extends HandlerWrapper implements Attributes
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
*/ */
@Deprecated @Deprecated
public int getMaxCookieVersion() public int getMaxCookieVersion()
@ -466,7 +464,7 @@ public class Server extends HandlerWrapper implements Attributes
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
*/ */
@Deprecated @Deprecated
public void setMaxCookieVersion(int maxCookieVersion) public void setMaxCookieVersion(int maxCookieVersion)

View File

@ -24,10 +24,10 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
* @deprecated use SelectChannelConnector with {@link SslContextFactory} * @deprecated use SelectChannelConnector with {@link SslContextFactory}
* @org.apache.xbean.XBean element="sslConnector" description="Creates an NIO ssl connector" * @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) public SslSelectChannelConnector(Server server)
{ {
super(server,true); super(server,new SslContextFactory());
} }
} }

View File

@ -13,12 +13,7 @@
package org.eclipse.jetty.server; 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 java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -26,6 +21,10 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.junit.Test; 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(); Server server = new Server();
LocalConnector connector = new LocalConnector(server); LocalConnector connector = new LocalConnector(server);
// Activate reverse proxy headers checking // 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}); server.setConnectors(new Connector[] {connector});
ValidationHandler validationHandler = new ValidationHandler(requestValidator); ValidationHandler validationHandler = new ValidationHandler(requestValidator);

View File

@ -19,16 +19,9 @@
*/ */
package org.eclipse.jetty.server; 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.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -45,6 +38,12 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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(); server = new Server();
connector = new LocalConnector(server); connector = new LocalConnector(server);
server.addConnector(connector); server.addConnector(connector);
connector.getConnectionFactory().getHttpConfig().setRequestHeaderSize(1024); HttpConfiguration httpConfiguration = new HttpConfiguration(null, false);
connector.getConnectionFactory().getHttpConfig().setResponseHeaderSize(1024); httpConfiguration.setRequestHeaderSize(1024);
httpConfiguration.setResponseHeaderSize(1024);
connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector, httpConfiguration));
server.setHandler(new DumpHandler()); server.setHandler(new DumpHandler());
server.start(); server.start();
} }
@ -135,7 +136,7 @@ public class HttpConnectionTest
offset = checkContains(response,offset,"HTTP/1.1 200"); offset = checkContains(response,offset,"HTTP/1.1 200");
checkContains(response,offset,"/R1"); checkContains(response,offset,"/R1");
} }
@Test @Test
public void testHead() throws Exception public void testHead() throws Exception
{ {
@ -143,15 +144,15 @@ public class HttpConnectionTest
"Host: localhost\015\012"+ "Host: localhost\015\012"+
"Connection: close\015\012"+ "Connection: close\015\012"+
"\015\012"); "\015\012");
String responseHEAD=connector.getResponses("HEAD /R1 HTTP/1.1\015\012"+ String responseHEAD=connector.getResponses("HEAD /R1 HTTP/1.1\015\012"+
"Host: localhost\015\012"+ "Host: localhost\015\012"+
"Connection: close\015\012"+ "Connection: close\015\012"+
"\015\012"); "\015\012");
assertThat(responsePOST,startsWith(responseHEAD.substring(0,responseHEAD.length()-2))); assertThat(responsePOST,startsWith(responseHEAD.substring(0,responseHEAD.length()-2)));
assertThat(responsePOST.length(),greaterThan(responseHEAD.length())); assertThat(responsePOST.length(),greaterThan(responseHEAD.length()));
responsePOST=connector.getResponses("POST /R1 HTTP/1.1\015\012"+ responsePOST=connector.getResponses("POST /R1 HTTP/1.1\015\012"+
"Host: localhost\015\012"+ "Host: localhost\015\012"+
"Connection: close\015\012"+ "Connection: close\015\012"+
@ -413,7 +414,7 @@ public class HttpConnectionTest
{ {
String response = null; String response = null;
int offset = 0; int offset = 0;
StringBuilder request = new StringBuilder(); StringBuilder request = new StringBuilder();
request.append("GET / HTTP/1.1\n"); request.append("GET / HTTP/1.1\n");
request.append("Host: localhost\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(String.format("X-Header-%04d: %08x\n", i, i));
} }
request.append("\015\012"); request.append("\015\012");
response = connector.getResponses(request.toString()); response = connector.getResponses(request.toString());
checkContains(response, offset, "HTTP/1.1 413"); checkContains(response, offset, "HTTP/1.1 413");
} }
@ -434,8 +435,8 @@ public class HttpConnectionTest
for (int i=0;i<500;i++) for (int i=0;i<500;i++)
str+="xxxxxxxxxxxx"; str+="xxxxxxxxxxxx";
final String longstr = str; final String longstr = str;
String response = null; String response = null;
server.stop(); server.stop();
server.setHandler(new DumpHandler() server.setHandler(new DumpHandler()
{ {
@ -488,8 +489,8 @@ public class HttpConnectionTest
for (int i=0;i<500;i++) for (int i=0;i<500;i++)
str+="xxxxxxxxxxxx"; str+="xxxxxxxxxxxx";
final String longstr = str; final String longstr = str;
String response = null; String response = null;
server.stop(); server.stop();
server.setHandler(new DumpHandler() server.setHandler(new DumpHandler()
{ {

View File

@ -19,7 +19,6 @@ import java.io.OutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.Writer; import java.io.Writer;
import java.net.Socket; import java.net.Socket;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -39,9 +38,9 @@ public class HttpServerTestFixture
protected static final long PAUSE=10L; protected static final long PAUSE=10L;
protected static final int LOOPS=Stress.isEnabled()?250:50; protected static final int LOOPS=Stress.isEnabled()?250:50;
protected static final String HOST="localhost"; protected static final String HOST="localhost";
protected static Server _server; protected static Server _server;
protected static Connector.NetConnector _connector; protected static NetworkConnector _connector;
protected String _scheme="http"; protected String _scheme="http";
protected Socket newSocket(String host,int port) throws Exception protected Socket newSocket(String host,int port) throws Exception
@ -52,14 +51,14 @@ public class HttpServerTestFixture
socket.setSoLinger(false,0); socket.setSoLinger(false,0);
return socket; return socket;
} }
@BeforeClass @BeforeClass
public static void before() public static void before()
{ {
_server = new Server(); _server = new Server();
} }
protected static void startServer(Connector.NetConnector connector) throws Exception protected static void startServer(NetworkConnector connector) throws Exception
{ {
_connector = connector; _connector = connector;
_server.addConnector(_connector); _server.addConnector(_connector);
@ -81,20 +80,20 @@ public class HttpServerTestFixture
current.setHandler(handler); current.setHandler(handler);
current.start(); current.start();
} }
protected static class EchoHandler extends AbstractHandler protected static class EchoHandler extends AbstractHandler
{ {
boolean musthavecontent=true; boolean musthavecontent=true;
public EchoHandler() public EchoHandler()
{} {}
public EchoHandler(boolean content) public EchoHandler(boolean content)
{ {
musthavecontent=false; musthavecontent=false;
} }
@Override @Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{ {
@ -111,7 +110,7 @@ public class HttpServerTestFixture
int count=0; int count=0;
BufferedReader reader=request.getReader(); BufferedReader reader=request.getReader();
if (request.getContentLength()!=0) if (request.getContentLength()!=0)
{ {
String line=reader.readLine(); String line=reader.readLine();
@ -123,7 +122,7 @@ public class HttpServerTestFixture
line=reader.readLine(); line=reader.readLine();
} }
} }
if (count==0) if (count==0)
{ {
if (musthavecontent) if (musthavecontent)
@ -131,7 +130,7 @@ public class HttpServerTestFixture
writer.println("No content"); writer.println("No content");
} }
// just to be difficult // just to be difficult
reader.close(); reader.close();
writer.close(); writer.close();
@ -171,7 +170,7 @@ public class HttpServerTestFixture
String data = "\u0a870123456789A\u0a87CDEFGHIJKLMNOPQRSTUVWXYZ\u0250bcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; String data = "\u0a870123456789A\u0a87CDEFGHIJKLMNOPQRSTUVWXYZ\u0250bcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
while (data.length()<block) while (data.length()<block)
data+=data; data+=data;
String chunk = (input+data).substring(0,block); String chunk = (input+data).substring(0,block);
response.setContentType("text/plain"); response.setContentType("text/plain");
if (encoding==null) if (encoding==null)
@ -206,7 +205,7 @@ public class HttpServerTestFixture
} }
} }
public final static HostnameVerifier __hostnameverifier = new HostnameVerifier() public final static HostnameVerifier __hostnameverifier = new HostnameVerifier()
{ {
public boolean verify(String hostname, SSLSession session) public boolean verify(String hostname, SSLSession session)

View File

@ -13,14 +13,6 @@
package org.eclipse.jetty.server; package org.eclipse.jetty.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileReader;
@ -32,7 +24,6 @@ import java.util.Arrays;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -52,6 +43,14 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class RequestTest public class RequestTest
{ {
private static final Logger LOG = Log.getLogger(RequestTest.class); private static final Logger LOG = Log.getLogger(RequestTest.class);
@ -64,11 +63,14 @@ public class RequestTest
{ {
_server = new Server(); _server = new Server();
_connector = new LocalConnector(_server); _connector = new LocalConnector(_server);
_connector.getConnectionFactory().getHttpConfig().setRequestHeaderSize(512); HttpConfiguration httpConfiguration = new HttpConfiguration(null, false);
_connector.getConnectionFactory().getHttpConfig().setRequestBufferSize(1024); httpConfiguration.setRequestHeaderSize(512);
_connector.getConnectionFactory().getHttpConfig().setResponseHeaderSize(512); httpConfiguration.setRequestBufferSize(1024);
_connector.getConnectionFactory().getHttpConfig().setResponseBufferSize(2048); httpConfiguration.setResponseHeaderSize(512);
_connector.getConnectionFactory().getHttpConfig().setForwarded(true); httpConfiguration.setResponseBufferSize(2048);
httpConfiguration.setForwarded(true);
HttpServerConnectionFactory defaultConnectionFactory = new HttpServerConnectionFactory(_connector, httpConfiguration);
_connector.setDefaultConnectionFactory(defaultConnectionFactory);
_server.addConnector(_connector); _server.addConnector(_connector);
_handler = new RequestHandler(); _handler = new RequestHandler();
_server.setHandler(_handler); _server.setHandler(_handler);
@ -125,7 +127,7 @@ public class RequestTest
assertTrue(responses.startsWith("HTTP/1.1 200")); assertTrue(responses.startsWith("HTTP/1.1 200"));
} }
@Test @Test
public void testMultiPart() throws Exception public void testMultiPart() throws Exception
{ {
@ -149,7 +151,7 @@ public class RequestTest
} }
} }
}; };
String multipart = "--AaB03x\r\n"+ String multipart = "--AaB03x\r\n"+
"content-disposition: form-data; name=\"field1\"\r\n"+ "content-disposition: form-data; name=\"field1\"\r\n"+
"\r\n"+ "\r\n"+
@ -160,7 +162,7 @@ public class RequestTest
"\r\n"+ "\r\n"+
"000000000000000000000000000000000000000000000000000\r\n"+ "000000000000000000000000000000000000000000000000000\r\n"+
"--AaB03x--\r\n"; "--AaB03x--\r\n";
String request="GET / HTTP/1.1\r\n"+ String request="GET / HTTP/1.1\r\n"+
"Host: whatever\r\n"+ "Host: whatever\r\n"+
"Content-Type: multipart/form-data; boundary=\"AaB03x\"\r\n"+ "Content-Type: multipart/form-data; boundary=\"AaB03x\"\r\n"+
@ -275,7 +277,7 @@ public class RequestTest
@Test @Test
public void testHostPort() throws Exception public void testHostPort() throws Exception
{ {
final ArrayList<String> results = new ArrayList<String>(); final ArrayList<String> results = new ArrayList<String>();
_handler._checker = new RequestTester() _handler._checker = new RequestTester()
{ {
@ -326,8 +328,8 @@ public class RequestTest
"x-forwarded-for: remote\n"+ "x-forwarded-for: remote\n"+
"x-forwarded-proto: https\n"+ "x-forwarded-proto: https\n"+
"\n",10,TimeUnit.SECONDS); "\n",10,TimeUnit.SECONDS);
int i=0; int i=0;
assertEquals("0.0.0.0",results.get(i++)); assertEquals("0.0.0.0",results.get(i++));
assertEquals("myhost",results.get(i++)); assertEquals("myhost",results.get(i++));
@ -920,7 +922,7 @@ public class RequestTest
{ {
((Request)request).setHandled(true); ((Request)request).setHandled(true);
if (request.getContentLength()>0 if (request.getContentLength()>0
&& !MimeTypes.Type.FORM_ENCODED.asString().equals(request.getContentType()) && !MimeTypes.Type.FORM_ENCODED.asString().equals(request.getContentType())
&& !request.getContentType().startsWith("multipart/form-data")) && !request.getContentType().startsWith("multipart/form-data"))
_content=IO.toString(request.getInputStream()); _content=IO.toString(request.getInputStream());

View File

@ -13,11 +13,6 @@
package org.eclipse.jetty.server; 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.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.LineNumberReader; import java.io.LineNumberReader;
@ -29,7 +24,6 @@ import java.util.Locale;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -52,6 +46,11 @@ import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; 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(); super.onOpen();
fillInterested(); fillInterested();
} }
@Override @Override
public void onFillable() public void onFillable()
{ {
@ -160,7 +159,7 @@ public class ResponseTest
protected void commitResponse(ResponseInfo info, ByteBuffer content) throws IOException protected void commitResponse(ResponseInfo info, ByteBuffer content) throws IOException
{ {
} }
@Override @Override
public Connector getConnector() public Connector getConnector()
{ {
@ -600,7 +599,7 @@ public class ResponseTest
}); });
server.start(); 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("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().write("GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n".getBytes());
socket.getOutputStream().flush(); socket.getOutputStream().flush();

View File

@ -13,9 +13,6 @@
package org.eclipse.jetty.server; package org.eclipse.jetty.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -23,7 +20,6 @@ import java.io.PrintWriter;
import java.net.Socket; import java.net.Socket;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.CyclicBarrier;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -40,12 +36,15 @@ import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SelectChannelStatisticsTest public class SelectChannelStatisticsTest
{ {
private static final Logger LOG = Log.getLogger(SelectChannelStatisticsTest.class); private static final Logger LOG = Log.getLogger(SelectChannelStatisticsTest.class);
private static Server _server; private static Server _server;
private static AbstractNetConnector _connector; private static AbstractNetworkConnector _connector;
private static CyclicBarrier _connect; private static CyclicBarrier _connect;
private static CountDownLatch _closed; private static CountDownLatch _closed;

View File

@ -12,16 +12,14 @@ package org.eclipse.jetty.server;
//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 static org.hamcrest.Matchers.lessThan;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -34,6 +32,8 @@ import org.junit.Assert;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import static org.hamcrest.Matchers.lessThan;
public class SlowClientWithPipelinedRequestTest public class SlowClientWithPipelinedRequestTest
{ {
private final AtomicInteger handles = new AtomicInteger(); private final AtomicInteger handles = new AtomicInteger();
@ -43,23 +43,24 @@ public class SlowClientWithPipelinedRequestTest
public void startServer(Handler handler) throws Exception public void startServer(Handler handler) throws Exception
{ {
server = new Server(); server = new Server();
connector = new SelectChannelConnector(server,new ConnectionFactory() connector = new SelectChannelConnector(server);
connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector)
{ {
@Override @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 @Override
public synchronized void onFillable() public void onFillable()
{ {
handles.incrementAndGet(); handles.incrementAndGet();
super.onFillable(); super.onFillable();
} }
}; };
} }
},null,null,null,0,0); });
server.addConnector(connector); server.addConnector(connector);
connector.setPort(0); connector.setPort(0);
server.setHandler(handler); server.setHandler(handler);

View File

@ -4,18 +4,15 @@
// All rights reserved. This program and the accompanying materials // All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0 // are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution. // and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at // The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html // http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at // The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php // http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.server.handler; 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.BufferedReader;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
@ -28,13 +25,13 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server; 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;
import org.junit.runners.Parameterized.Parameters; import org.junit.runners.Parameterized.Parameters;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class IPAccessHandlerTest public class IPAccessHandlerTest
{ {
private static Server _server; private static Server _server;
private static Connector.NetConnector _connector; private static NetworkConnector _connector;
private static IPAccessHandler _handler; private static IPAccessHandler _handler;
private String _white; private String _white;
private String _black; private String _black;
private String _host; private String _host;
private String _uri; private String _uri;
private String _code; private String _code;
@BeforeClass @BeforeClass
public static void setUp() public static void setUp()
throws Exception throws Exception
@ -78,7 +78,7 @@ public class IPAccessHandlerTest
_server.setHandler(_handler); _server.setHandler(_handler);
_server.start(); _server.start();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@AfterClass @AfterClass
public static void tearDown() public static void tearDown()
@ -86,7 +86,7 @@ public class IPAccessHandlerTest
{ {
_server.stop(); _server.stop();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public IPAccessHandlerTest(String white, String black, String host, String uri, String code) public IPAccessHandlerTest(String white, String black, String host, String uri, String code)
{ {
@ -96,7 +96,7 @@ public class IPAccessHandlerTest
_uri = uri; _uri = uri;
_code = code; _code = code;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Test @Test
public void testHandler() public void testHandler()
@ -104,7 +104,7 @@ public class IPAccessHandlerTest
{ {
_handler.setWhite(_white.split(";",-1)); _handler.setWhite(_white.split(";",-1));
_handler.setBlack(_black.split(";",-1)); _handler.setBlack(_black.split(";",-1));
String request = "GET " + _uri + " HTTP/1.1\n" + "Host: "+ _host + "\n\n"; String request = "GET " + _uri + " HTTP/1.1\n" + "Host: "+ _host + "\n\n";
Socket socket = new Socket("127.0.0.1", _connector.getLocalPort()); Socket socket = new Socket("127.0.0.1", _connector.getLocalPort());
socket.setSoTimeout(5000); socket.setSoTimeout(5000);
@ -231,7 +231,7 @@ public class IPAccessHandlerTest
return builder.toString(); return builder.toString();
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Parameters @Parameters
public static Collection<Object[]> data() { public static Collection<Object[]> data() {
@ -239,20 +239,20 @@ public class IPAccessHandlerTest
// Empty lists // Empty lists
{"", "", "127.0.0.1", "/", "200"}, {"", "", "127.0.0.1", "/", "200"},
{"", "", "127.0.0.1", "/dump/info", "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", "/", "200"},
{"127.0.0.1", "", "127.0.0.1", "/dispatch", "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", "/dump/info", "200"},
{"127.0.0.1|/", "", "127.0.0.1", "/", "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", "/dispatch", "403"},
{"127.0.0.1|/", "", "127.0.0.1", "/dump/info", "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", "/", "200"},
{"127.0.0.1|/*", "", "127.0.0.1", "/dispatch", "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", "/dump/info", "200"},
{"127.0.0.1|/dump/*", "", "127.0.0.1", "/", "403"}, {"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", "/dispatch", "403"},
{"127.0.0.1|/dump/*", "", "127.0.0.1", "/dump/info", "200"}, {"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/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/test", "200"},
{"127.0.0.1|/dump/info;127.0.0.1|/dump/test", "", "127.0.0.1", "/dump/fail", "403"}, {"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", "/", "200"},
{"127.0.0.0-2|", "", "127.0.0.1", "/dump/info", "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/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/test", "200"},
{"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dump/fail", "403"}, {"127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "", "127.0.0.1", "/dump/fail", "403"},
// Black list // Black list
{"", "127.0.0.1", "127.0.0.1", "/", "403"}, {"", "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", "/dispatch", "403"},
{"", "127.0.0.1", "127.0.0.1", "/dump/info", "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", "/", "403"},
{"", "127.0.0.1|/", "127.0.0.1", "/dispatch", "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", "/dump/info", "200"},
{"", "127.0.0.1|/*", "127.0.0.1", "/", "403"}, {"", "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", "/dispatch", "403"},
{"", "127.0.0.1|/*", "127.0.0.1", "/dump/info", "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", "/", "200"},
{"", "127.0.0.1|/dump/*", "127.0.0.1", "/dispatch", "200"}, {"", "127.0.0.1|/dump/*", "127.0.0.1", "/dispatch", "200"},
{"", "127.0.0.1|/dump/*", "127.0.0.1", "/dump/info", "403"}, {"", "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/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/test", "403"},
{"", "127.0.0.1|/dump/info;127.0.0.1|/dump/test", "127.0.0.1", "/dump/fail", "200"}, {"", "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", "/", "403"},
{"", "127.0.0.0-2|", "127.0.0.1", "/dump/info", "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/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/test", "403"},
{"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dump/fail", "200"}, {"", "127.0.0.0-2|/dump/info;127.0.0.0-2|/dump/test", "127.0.0.1", "/dump/fail", "200"},
// Both lists // 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", "200"},
{"127.0.0.1|/dump", "127.0.0.1|/dump/fail", "127.0.0.1", "/dump/info", "403"}, {"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/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/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/*", "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", "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/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"}, {"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/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/test", "403"},
{"127.0.0.1|/dump/info;127.0.0.2|/dump/test", "", "127.0.0.1", "/dump/fail", "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", "/", "403"},
{"172.0.0.0-255", "", "127.0.0.1", "/dump/info", "403"}, {"172.0.0.0-255", "", "127.0.0.1", "/dump/info", "403"},

View File

@ -21,7 +21,6 @@ import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
@ -30,13 +29,13 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
/** /**
* HttpServer Tester. * HttpServer Tester.
@ -72,15 +71,15 @@ public class SSLCloseTest extends TestCase
*/ */
public void testClose() throws Exception 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"; 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.setPort(0);
connector.getConnectionFactory().getSslContextFactory().setKeyStorePath(keystore);
connector.getConnectionFactory().getSslContextFactory().setKeyStorePassword("storepwd");
connector.getConnectionFactory().getSslContextFactory().setKeyManagerPassword("keypwd");
server.setConnectors(new Connector[] server.setConnectors(new Connector[]
{ connector }); { connector });

View File

@ -18,11 +18,6 @@
package org.eclipse.jetty.server.ssl; 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.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -33,7 +28,6 @@ import java.net.HttpURLConnection;
import java.net.Socket; import java.net.Socket;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.URL; import java.net.URL;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@ -43,7 +37,8 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 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.Request;
import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
@ -56,6 +51,11 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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 Server server;
private SelectChannelConnector connector; private SelectChannelConnector connector;
@Before @Before
public void startServer() throws Exception public void startServer() throws Exception
{ {
server=new Server();
connector=new SelectChannelConnector(server,true);
String keystore = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath(); 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); connector.setPort(0);
SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory(); HttpConfiguration httpConfiguration = new HttpConfiguration(sslContextFactory, true);
cf.setKeyStorePath(keystore); httpConfiguration.setRequestBufferSize(512);
cf.setKeyStorePassword("storepwd"); httpConfiguration.setRequestHeaderSize(512);
cf.setKeyManagerPassword("keypwd"); connector.setDefaultConnectionFactory(new HttpServerConnectionFactory(connector, httpConfiguration));
connector.getConnectionFactory().getHttpConfig().setRequestBufferSize(512);
connector.getConnectionFactory().getHttpConfig().setRequestHeaderSize(512);
server.setConnectors(new Connector[]{connector }); server.addConnector(connector);
} }
@After @After
@ -111,14 +113,13 @@ public class SSLEngineTest
server.join(); server.join();
} }
@Test @Test
public void testHelloWorld() throws Exception public void testHelloWorld() throws Exception
{ {
server.setHandler(new HelloWorldHandler()); server.setHandler(new HelloWorldHandler());
server.start(); server.start();
server.dumpStdErr(); server.dumpStdErr();
SSLContext ctx=SSLContext.getInstance("TLS"); SSLContext ctx=SSLContext.getInstance("TLS");
ctx.init(null,SslContextFactory.TRUST_ALL_CERTS,new java.security.SecureRandom()); 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("200 OK"));
assertThat(response,Matchers.containsString(HELLO_WORLD)); assertThat(response,Matchers.containsString(HELLO_WORLD));
} }
@Test @Test
public void testBigResponse() throws Exception public void testBigResponse() throws Exception
{ {
server.setHandler(new HelloWorldHandler()); server.setHandler(new HelloWorldHandler());
server.start(); server.start();
SSLContext ctx=SSLContext.getInstance("TLS"); SSLContext ctx=SSLContext.getInstance("TLS");
ctx.init(null,SslContextFactory.TRUST_ALL_CERTS,new java.security.SecureRandom()); ctx.init(null,SslContextFactory.TRUST_ALL_CERTS,new java.security.SecureRandom());
@ -175,7 +176,7 @@ public class SSLEngineTest
{ {
server.setHandler(new HelloWorldHandler()); server.setHandler(new HelloWorldHandler());
server.start(); server.start();
final int loops=20; final int loops=20;
final int numConns=20; final int numConns=20;
@ -384,5 +385,5 @@ public class SSLEngineTest
response.flushBuffer(); response.flushBuffer();
} }
} }
} }

View File

@ -26,7 +26,6 @@ import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
@ -35,6 +34,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
@ -45,30 +45,30 @@ import org.junit.Test;
public class SSLSelectChannelConnectorLoadTest public class SSLSelectChannelConnectorLoadTest
{ {
private static Server server; private static Server server;
private static SslSelectChannelConnector connector; private static SelectChannelConnector connector;
private static SSLContext sslContext; private static SSLContext sslContext;
@BeforeClass @BeforeClass
public static void startServer() throws Exception 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"; String keystorePath = System.getProperty("basedir", ".") + "/src/test/resources/keystore";
SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory(); SslContextFactory sslContextFactory = new SslContextFactory();
cf.setKeyStorePath(keystorePath); sslContextFactory.setKeyStorePath(keystorePath);
cf.setKeyStorePassword("storepwd"); sslContextFactory.setKeyStorePassword("storepwd");
cf.setKeyManagerPassword("keypwd"); sslContextFactory.setKeyManagerPassword("keypwd");
cf.setTrustStore(keystorePath); sslContextFactory.setTrustStore(keystorePath);
cf.setTrustStorePassword("storepwd"); sslContextFactory.setTrustStorePassword("storepwd");
server = new Server();
connector = new SelectChannelConnector(server, sslContextFactory);
server.addConnector(connector);
server.setHandler(new EmptyHandler()); server.setHandler(new EmptyHandler());
server.start(); server.start();
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 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 trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keystore); trustManagerFactory.init(keystore);
sslContext = SSLContext.getInstance("SSL"); sslContext = SSLContext.getInstance("SSL");

View File

@ -12,14 +12,11 @@
// ======================================================================== // ========================================================================
package org.eclipse.jetty.server.ssl; package org.eclipse.jetty.server.ssl;
import static org.junit.Assert.assertEquals;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.security.KeyStore; import java.security.KeyStore;
import java.util.Arrays; import java.util.Arrays;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
@ -31,6 +28,8 @@ import org.junit.BeforeClass;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals;
/** /**
* HttpServer Tester. * HttpServer Tester.
*/ */
@ -40,48 +39,47 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
{ {
_scheme="https"; _scheme="https";
} }
@Override @Override
protected Socket newSocket(String host, int port) throws Exception protected Socket newSocket(String host, int port) throws Exception
{ {
return __sslContext.getSocketFactory().createSocket(host,port); return __sslContext.getSocketFactory().createSocket(host,port);
} }
@BeforeClass @BeforeClass
public static void init() throws Exception public static void init() throws Exception
{ {
SelectChannelConnector connector = new SelectChannelConnector(_server,true);
String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore"; String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory(); SslContextFactory sslContextFactory = new SslContextFactory();
cf.setKeyStorePath(keystorePath); sslContextFactory.setKeyStorePath(keystorePath);
cf.setKeyStorePassword("storepwd"); sslContextFactory.setKeyStorePassword("storepwd");
cf.setKeyManagerPassword("keypwd"); sslContextFactory.setKeyManagerPassword("keypwd");
cf.setTrustStore(keystorePath); sslContextFactory.setTrustStore(keystorePath);
cf.setTrustStorePassword("storepwd"); sslContextFactory.setTrustStorePassword("storepwd");
SelectChannelConnector connector = new SelectChannelConnector(_server, sslContextFactory);
startServer(connector); startServer(connector);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 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 trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keystore); trustManagerFactory.init(keystore);
__sslContext = SSLContext.getInstance("TLS"); __sslContext = SSLContext.getInstance("TLS");
__sslContext.init(null, trustManagerFactory.getTrustManagers(), null); __sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
try try
{ {
HttpsURLConnection.setDefaultHostnameVerifier(__hostnameverifier); HttpsURLConnection.setDefaultHostnameVerifier(__hostnameverifier);
SSLContext sc = SSLContext.getInstance("TLS"); SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, SslContextFactory.TRUST_ALL_CERTS, new java.security.SecureRandom()); sc.init(null, SslContextFactory.TRUST_ALL_CERTS, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} }
catch(Exception e) catch(Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@Test @Test
public void testRequest2FixedFragments() throws Exception public void testRequest2FixedFragments() throws Exception
@ -104,7 +102,7 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
// Write out the fragments // Write out the fragments
for (int j=0; j<points.length; ++j) for (int j=0; j<points.length; ++j)
{ {
int point=points[j]; int point=points[j];
os.write(bytes,last,point-last); os.write(bytes,last,point-last);
last=point; last=point;
os.flush(); os.flush();
@ -116,7 +114,7 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
os.write(bytes,last,bytes.length-last); os.write(bytes,last,bytes.length-last);
os.flush(); os.flush();
Thread.sleep(PAUSE); Thread.sleep(PAUSE);
// Read the response // Read the response
String response=readResponse(client); String response=readResponse(client);
@ -135,5 +133,5 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
public void testAvailable() throws Exception public void testAvailable() throws Exception
{ {
} }
} }

View File

@ -33,7 +33,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -80,7 +79,12 @@ public class SslBytesServerTest extends SslBytesTest
threadPool = Executors.newCachedThreadPool(); threadPool = Executors.newCachedThreadPool();
server = new Server(); server = new Server();
SelectChannelConnector connector = new SelectChannelConnector(server,true) File keyStore = MavenTestingUtils.getTestResourceFile("keystore");
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
sslContextFactory.setKeyStorePassword("storepwd");
sslContextFactory.setKeyManagerPassword("keypwd");
SelectChannelConnector connector = new SelectChannelConnector(server, sslContextFactory)
{ {
@Override @Override
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
@ -89,20 +93,12 @@ public class SslBytesServerTest extends SslBytesTest
serverEndPoint.set(endp); serverEndPoint.set(endp);
return endp; return endp;
} }
};
connector.setIdleTimeout(idleTimeout);
// connector.setPort(5870); };
connector.setIdleTimeout(idleTimeout);
// connector.setPort(5870);
connector.setPort(0); connector.setPort(0);
File keyStore = MavenTestingUtils.getTestResourceFile("keystore");
SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory();
cf.setKeyStorePath(keyStore.getAbsolutePath());
cf.setKeyStorePassword("storepwd");
cf.setKeyManagerPassword("keypwd");
server.addConnector(connector); server.addConnector(connector);
server.setHandler(new AbstractHandler() server.setHandler(new AbstractHandler()
{ {
@ -139,7 +135,7 @@ public class SslBytesServerTest extends SslBytesTest
server.start(); server.start();
serverPort = connector.getLocalPort(); serverPort = connector.getLocalPort();
sslContext = cf.getSslContext(); sslContext = sslContextFactory.getSslContext();
proxy = new SimpleProxy(threadPool, "localhost", serverPort); proxy = new SimpleProxy(threadPool, "localhost", serverPort);
proxy.start(); proxy.start();

View File

@ -16,7 +16,6 @@ package org.eclipse.jetty.server.ssl;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.net.Socket; import java.net.Socket;
import java.security.KeyStore; import java.security.KeyStore;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
@ -38,19 +37,19 @@ public class SslSelectChannelTimeoutTest extends ConnectorTimeoutTest
@BeforeClass @BeforeClass
public static void init() throws Exception public static void init() throws Exception
{ {
SelectChannelConnector connector = new SelectChannelConnector(_server,true);
connector.setIdleTimeout(MAX_IDLE_TIME); //250 msec max idle
String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore"; String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory(); SslContextFactory sslContextFactory = new SslContextFactory();
cf.setKeyStorePath(keystorePath); sslContextFactory.setKeyStorePath(keystorePath);
cf.setKeyStorePassword("storepwd"); sslContextFactory.setKeyStorePassword("storepwd");
cf.setKeyManagerPassword("keypwd"); sslContextFactory.setKeyManagerPassword("keypwd");
cf.setTrustStore(keystorePath); sslContextFactory.setTrustStore(keystorePath);
cf.setTrustStorePassword("storepwd"); sslContextFactory.setTrustStorePassword("storepwd");
SelectChannelConnector connector = new SelectChannelConnector(_server, sslContextFactory);
connector.setIdleTimeout(MAX_IDLE_TIME); //250 msec max idle
startServer(connector); startServer(connector);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 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 trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keystore); trustManagerFactory.init(keystore);
__sslContext = SSLContext.getInstance("SSL"); __sslContext = SSLContext.getInstance("SSL");

View File

@ -14,16 +14,12 @@
package org.eclipse.jetty.server.ssl; package org.eclipse.jetty.server.ssl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.KeyStore; import java.security.KeyStore;
import java.util.Arrays; import java.util.Arrays;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
@ -42,6 +38,9 @@ import org.junit.BeforeClass;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/** /**
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
@ -54,17 +53,17 @@ public class SslUploadTest
@BeforeClass @BeforeClass
public static void startServer() throws Exception public static void startServer() throws Exception
{ {
server = new Server();
connector = new SelectChannelConnector(server,true);
server.addConnector(connector);
String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore"; String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory(); SslContextFactory sslContextFactory = new SslContextFactory();
cf.setKeyStorePath(keystorePath); sslContextFactory.setKeyStorePath(keystorePath);
cf.setKeyStorePassword("storepwd"); sslContextFactory.setKeyStorePassword("storepwd");
cf.setKeyManagerPassword("keypwd"); sslContextFactory.setKeyManagerPassword("keypwd");
cf.setTrustStore(keystorePath); sslContextFactory.setTrustStore(keystorePath);
cf.setTrustStorePassword("storepwd"); sslContextFactory.setTrustStorePassword("storepwd");
server = new Server();
connector = new SelectChannelConnector(server, sslContextFactory);
server.addConnector(connector);
server.setHandler(new EmptyHandler()); server.setHandler(new EmptyHandler());
@ -83,7 +82,7 @@ public class SslUploadTest
public void test() throws Exception public void test() throws Exception
{ {
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 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 trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keystore); trustManagerFactory.init(keystore);
SSLContext sslContext = SSLContext.getInstance("SSL"); SSLContext sslContext = SSLContext.getInstance("SSL");

View File

@ -12,14 +12,6 @@ package org.eclipse.jetty.servlets;
//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 static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -36,10 +28,9 @@ import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater; import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream; import java.util.zip.InflaterInputStream;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.FilterHolder;
@ -58,6 +49,14 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters; import org.junit.runners.Parameterized.Parameters;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/** /**
* Test the effects of Gzip filtering when in the context of HTTP/1.1 Pipelining. * Test the effects of Gzip filtering when in the context of HTTP/1.1 Pipelining.
*/ */
@ -73,20 +72,20 @@ public class GzipWithPipeliningTest
{ GzipFilter.GZIP }, { GzipFilter.GZIP },
{ GzipFilter.DEFLATE + ", " + GzipFilter.GZIP }, { GzipFilter.DEFLATE + ", " + GzipFilter.GZIP },
{ GzipFilter.GZIP + ", " + GzipFilter.DEFLATE }, { GzipFilter.GZIP + ", " + GzipFilter.DEFLATE },
{ GzipFilter.DEFLATE } { GzipFilter.DEFLATE }
}; };
return Arrays.asList(data); return Arrays.asList(data);
} }
@Rule @Rule
public TestingDir testingdir = new TestingDir(); public TestingDir testingdir = new TestingDir();
private Server server; private Server server;
private URI serverUri; private URI serverUri;
private String encodingHeader; private String encodingHeader;
public GzipWithPipeliningTest(String encodingHeader) public GzipWithPipeliningTest(String encodingHeader)
{ {
this.encodingHeader = encodingHeader; this.encodingHeader = encodingHeader;
@ -114,7 +113,7 @@ public class GzipWithPipeliningTest
// Start Server // Start Server
server.start(); server.start();
Connector.NetConnector conn = (Connector.NetConnector)server.getConnectors()[0]; NetworkConnector conn = (NetworkConnector)server.getConnectors()[0];
String host = conn.getHost(); String host = conn.getHost();
if (host == null) if (host == null)
{ {
@ -130,13 +129,13 @@ public class GzipWithPipeliningTest
{ {
server.stop(); server.stop();
} }
@Test @Test
public void testGzipThenImagePipelining() throws Exception public void testGzipThenImagePipelining() throws Exception
{ {
testingdir.ensureEmpty(); testingdir.ensureEmpty();
File outputDir = testingdir.getDir(); File outputDir = testingdir.getDir();
PipelineHelper client = new PipelineHelper(serverUri, encodingHeader); PipelineHelper client = new PipelineHelper(serverUri, encodingHeader);
try try
@ -193,7 +192,7 @@ public class GzipWithPipeliningTest
// Inter-pipeline delim // Inter-pipeline delim
line = client.readLine(); line = client.readLine();
assertThat("Inter-pipeline delim should be an empty line with CR+LF",line,is("")); assertThat("Inter-pipeline delim should be an empty line with CR+LF",line,is(""));
// Sha1tracking for 1st Request // Sha1tracking for 1st Request
MessageDigest digestTxt = MessageDigest.getInstance("SHA1"); MessageDigest digestTxt = MessageDigest.getInstance("SHA1");
DigestOutputStream digesterTxt = new DigestOutputStream(new NoOpOutputStream(),digestTxt); DigestOutputStream digesterTxt = new DigestOutputStream(new NoOpOutputStream(),digestTxt);
@ -212,7 +211,7 @@ public class GzipWithPipeliningTest
} }
IO.copy(uncompressedStream, digesterTxt); IO.copy(uncompressedStream, digesterTxt);
// Read 2nd request http response header // Read 2nd request http response header
respHeader = client.readResponseHeader(); respHeader = client.readResponseHeader();
System.out.println("Response Header #2 --\n" + respHeader); System.out.println("Response Header #2 --\n" + respHeader);

View File

@ -1,44 +0,0 @@
//========================================================================
//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.spdy.http;
import java.nio.channels.SocketChannel;
import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.nio.AsyncConnection;
import org.eclipse.jetty.server.AsyncHttpConnection;
import org.eclipse.jetty.spdy.AsyncConnectionFactory;
import org.eclipse.jetty.spdy.SPDYServerConnector;
public class ServerHTTPAsyncConnectionFactory implements AsyncConnectionFactory
{
private final SPDYServerConnector connector;
public ServerHTTPAsyncConnectionFactory(SPDYServerConnector connector)
{
this.connector = connector;
}
public SPDYServerConnector getConnector()
{
return connector;
}
@Override
public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment)
{
return new AsyncHttpConnection(connector, endPoint, connector.getServer());
}
}

View File

@ -1,24 +0,0 @@
// ========================================================================
// 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.spdy;
import java.nio.channels.SocketChannel;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
public interface ConnectionFactory
{
public Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment);
}

View File

@ -21,18 +21,19 @@ import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.npn.NextProtoNego; import org.eclipse.jetty.npn.NextProtoNego;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
public class NextProtoNegoServerAsyncConnection extends AbstractConnection implements NextProtoNego.ServerProvider public class NextProtoNegoServerConnection extends AbstractConnection implements NextProtoNego.ServerProvider
{ {
private final Logger logger = Log.getLogger(getClass()); private final Logger logger = Log.getLogger(getClass());
private final SocketChannel channel; private final SocketChannel channel;
private final SPDYServerConnector connector; private final SPDYServerConnector connector;
private volatile boolean completed; private volatile boolean completed;
public NextProtoNegoServerAsyncConnection(SocketChannel channel, EndPoint endPoint, SPDYServerConnector connector) public NextProtoNegoServerConnection(SocketChannel channel, EndPoint endPoint, SPDYServerConnector connector)
{ {
super(endPoint, connector.getExecutor()); super(endPoint, connector.getExecutor());
this.channel = channel; this.channel = channel;
@ -45,7 +46,7 @@ public class NextProtoNegoServerAsyncConnection extends AbstractConnection imple
super.onOpen(); super.onOpen();
fillInterested(); fillInterested();
} }
@Override @Override
public void onFillable() public void onFillable()
{ {
@ -76,10 +77,10 @@ public class NextProtoNegoServerAsyncConnection extends AbstractConnection imple
@Override @Override
public void unsupported() public void unsupported()
{ {
ConnectionFactory asyncConnectionFactory = connector.getDefaultAsyncConnectionFactory(); ConnectionFactory ConnectionFactory = connector.getDefaultConnectionFactory();
EndPoint endPoint = getEndPoint(); EndPoint endPoint = getEndPoint();
Connection connection = asyncConnectionFactory.newConnection(channel, endPoint, connector); Connection connection = ConnectionFactory.newConnection(channel, endPoint, connector);
connector.replaceAsyncConnection(endPoint, connection); connector.replaceConnection(endPoint, connection);
completed = true; completed = true;
} }
@ -92,10 +93,10 @@ public class NextProtoNegoServerAsyncConnection extends AbstractConnection imple
@Override @Override
public void protocolSelected(String protocol) public void protocolSelected(String protocol)
{ {
ConnectionFactory asyncConnectionFactory = connector.getAsyncConnectionFactory(protocol); ConnectionFactory ConnectionFactory = connector.getConnectionFactory(protocol);
EndPoint endPoint = getEndPoint(); EndPoint endPoint = getEndPoint();
Connection connection = asyncConnectionFactory.newConnection(channel, endPoint, connector); Connection connection = ConnectionFactory.newConnection(channel, endPoint, connector);
connector.replaceAsyncConnection(endPoint, connection); connector.replaceConnection(endPoint, connection);
completed = true; completed = true;
} }
} }

View File

@ -31,14 +31,15 @@ import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.SelectChannelEndPoint; import org.eclipse.jetty.io.SelectChannelEndPoint;
import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SelectorManager;
import org.eclipse.jetty.io.StandardByteBufferPool; import org.eclipse.jetty.io.StandardByteBufferPool;
import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.npn.NextProtoNego; import org.eclipse.jetty.npn.NextProtoNego;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.spdy.api.Session; import org.eclipse.jetty.spdy.api.Session;
import org.eclipse.jetty.spdy.api.SessionFrameListener; import org.eclipse.jetty.spdy.api.SessionFrameListener;
import org.eclipse.jetty.spdy.generator.Generator; import org.eclipse.jetty.spdy.generator.Generator;
@ -174,7 +175,7 @@ public class SPDYClient
{ {
String peerHost = channel.socket().getInetAddress().getHostAddress(); String peerHost = channel.socket().getInetAddress().getHostAddress();
int peerPort = channel.socket().getPort(); int peerPort = channel.socket().getPort();
SSLEngine engine = sslContextFactory.newSslEngine(peerHost, peerPort); SSLEngine engine = sslContextFactory.newSSLEngine(peerHost, peerPort);
engine.setUseClientMode(true); engine.setUseClientMode(true);
return engine; return engine;
} }

View File

@ -18,77 +18,44 @@ import java.nio.channels.SocketChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.StandardByteBufferPool;
import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.npn.NextProtoNego; import org.eclipse.jetty.npn.NextProtoNego;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.spdy.api.SPDY; import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.api.Session; import org.eclipse.jetty.spdy.api.Session;
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener; import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
public class SPDYServerConnector extends SelectChannelConnector public class SPDYServerConnector extends SelectChannelConnector
{ {
private static final Logger logger = Log.getLogger(SPDYServerConnector.class);
// Order is important on server side, so we use a LinkedHashMap
private final Map<String, ConnectionFactory> factories = new LinkedHashMap<>();
private final Queue<Session> sessions = new ConcurrentLinkedQueue<>(); private final Queue<Session> 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 ServerSessionFrameListener listener;
private final SslContextFactory sslContextFactory;
private volatile ConnectionFactory defaultConnectionFactory;
private volatile int initialWindowSize = 65536; 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.listener = listener;
this.sslContextFactory = sslContextFactory; putConnectionFactory("spdy/3", new ServerSPDYAsyncConnectionFactory(SPDY.V3, getByteBufferPool(), getExecutor(), getScheduler(), listener));
if (sslContextFactory != null) putConnectionFactory("spdy/2", new ServerSPDYAsyncConnectionFactory(SPDY.V2, getByteBufferPool(), getExecutor(), getScheduler(), listener));
addBean(sslContextFactory); setDefaultConnectionFactory(getConnectionFactory("spdy/2"));
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;
} }
public ServerSessionFrameListener getServerSessionFrameListener() public ServerSessionFrameListener getServerSessionFrameListener()
@ -96,11 +63,6 @@ public class SPDYServerConnector extends SelectChannelConnector
return listener; return listener;
} }
public SslContextFactory getSslContextFactory()
{
return sslContextFactory;
}
@Override @Override
protected void doStart() throws Exception protected void doStart() throws Exception
{ {
@ -112,83 +74,22 @@ public class SPDYServerConnector extends SelectChannelConnector
protected void doStop() throws Exception protected void doStop() throws Exception
{ {
closeSessions(); closeSessions();
scheduler.shutdown();
super.doStop(); 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<String, ConnectionFactory> getAsyncConnectionFactories()
{
synchronized (factories)
{
return new LinkedHashMap<>(factories);
}
}
public void clearAsyncConnectionFactories()
{
synchronized (factories)
{
factories.clear();
}
}
protected List<String> provideProtocols() protected List<String> provideProtocols()
{ {
synchronized (factories) return new ArrayList<>(getConnectionFactories().keySet());
{
return new ArrayList<>(factories.keySet());
}
}
public ConnectionFactory getDefaultAsyncConnectionFactory()
{
return defaultConnectionFactory;
}
public void setDefaultAsyncConnectionFactory(ConnectionFactory defaultConnectionFactory)
{
this.defaultConnectionFactory = defaultConnectionFactory;
} }
@Override @Override
protected Connection newConnection(final SocketChannel channel, EndPoint endPoint) protected Connection newConnection(SocketChannel channel, EndPoint endPoint, Object attachment)
{ {
SslContextFactory sslContextFactory = getSslContextFactory();
if (sslContextFactory != null) if (sslContextFactory != null)
{ {
final SSLEngine engine = newSSLEngine(sslContextFactory, channel); final SSLEngine engine = newSSLEngine(sslContextFactory, channel);
Executor executor = getExecutor(); SslConnection sslConnection = new SslConnection(getByteBufferPool(), getExecutor(), endPoint, engine)
SslConnection sslConnection = new SslConnection(bufferPool, executor, endPoint, engine)
{ {
@Override @Override
public void onClose() public void onClose()
@ -199,7 +100,7 @@ public class SPDYServerConnector extends SelectChannelConnector
}; };
final EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint(); final EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();
NextProtoNegoServerAsyncConnection connection = new NextProtoNegoServerAsyncConnection(channel, sslEndPoint, this); NextProtoNegoServerConnection connection = new NextProtoNegoServerConnection(channel, sslEndPoint, this);
sslEndPoint.setConnection(connection); sslEndPoint.setConnection(connection);
getSelectorManager().connectionOpened(connection); getSelectorManager().connectionOpened(connection);
@ -209,7 +110,7 @@ public class SPDYServerConnector extends SelectChannelConnector
} }
else else
{ {
ConnectionFactory connectionFactory = getDefaultAsyncConnectionFactory(); ConnectionFactory connectionFactory = getDefaultConnectionFactory();
Connection connection = connectionFactory.newConnection(channel, endPoint, this); Connection connection = connectionFactory.newConnection(channel, endPoint, this);
endPoint.setConnection(connection); endPoint.setConnection(connection);
return connection; return connection;
@ -225,7 +126,7 @@ public class SPDYServerConnector extends SelectChannelConnector
{ {
String peerHost = channel.socket().getInetAddress().getHostAddress(); String peerHost = channel.socket().getInetAddress().getHostAddress();
int peerPort = channel.socket().getPort(); int peerPort = channel.socket().getPort();
SSLEngine engine = sslContextFactory.newSslEngine(peerHost, peerPort); SSLEngine engine = sslContextFactory.newSSLEngine(peerHost, peerPort);
engine.setUseClientMode(false); engine.setUseClientMode(false);
return engine; return engine;
} }
@ -265,7 +166,7 @@ public class SPDYServerConnector extends SelectChannelConnector
this.initialWindowSize = initialWindowSize; this.initialWindowSize = initialWindowSize;
} }
public void replaceAsyncConnection(EndPoint endPoint, Connection connection) public void replaceConnection(EndPoint endPoint, Connection connection)
{ {
Connection oldConnection = endPoint.getConnection(); Connection oldConnection = endPoint.getConnection();
endPoint.setConnection(connection); endPoint.setConnection(connection);

View File

@ -17,9 +17,10 @@ import java.nio.channels.SocketChannel;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint; 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.api.server.ServerSessionFrameListener;
import org.eclipse.jetty.spdy.generator.Generator; import org.eclipse.jetty.spdy.generator.Generator;
import org.eclipse.jetty.spdy.parser.Parser; import org.eclipse.jetty.spdy.parser.Parser;

View File

@ -56,13 +56,13 @@ public abstract class AbstractTest
protected InetSocketAddress startServer(short version, ServerSessionFrameListener listener) throws Exception protected InetSocketAddress startServer(short version, ServerSessionFrameListener listener) throws Exception
{ {
server = new Server();
if (connector == null) if (connector == null)
connector = newSPDYServerConnector(listener); connector = newSPDYServerConnector(listener);
if (listener == null) if (listener == null)
listener = connector.getServerSessionFrameListener(); 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); connector.setPort(0);
server = new Server();
server.addConnector(connector); server.addConnector(connector);
server.start(); server.start();
return new InetSocketAddress("localhost", connector.getLocalPort()); return new InetSocketAddress("localhost", connector.getLocalPort());
@ -70,7 +70,7 @@ public abstract class AbstractTest
protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener) protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener)
{ {
return new SPDYServerConnector(listener); return new SPDYServerConnector(server, listener);
} }
protected Session startClient(InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception protected Session startClient(InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception

View File

@ -31,7 +31,7 @@ public class SSLEngineLeakTest extends AbstractTest
protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener) protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener)
{ {
SslContextFactory sslContextFactory = newSslContextFactory(); SslContextFactory sslContextFactory = newSslContextFactory();
return new SPDYServerConnector(listener, sslContextFactory); return new SPDYServerConnector(server, sslContextFactory, listener);
} }
@Override @Override

View File

@ -27,7 +27,7 @@ public class SSLSynReplyTest extends SynReplyTest
protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener) protected SPDYServerConnector newSPDYServerConnector(ServerSessionFrameListener listener)
{ {
SslContextFactory sslContextFactory = newSslContextFactory(); SslContextFactory sslContextFactory = newSslContextFactory();
return new SPDYServerConnector(listener, sslContextFactory); return new SPDYServerConnector(server, sslContextFactory, listener);
} }
@Override @Override

View File

@ -39,7 +39,6 @@ import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.net.ssl.CertPathTrustManagerParameters; import javax.net.ssl.CertPathTrustManagerParameters;
import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory; 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 = (_sslProvider == null)?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider);
_context.init(keyManagers,trustManagers,secureRandom); _context.init(keyManagers,trustManagers,secureRandom);
SSLEngine engine=newSslEngine(); SSLEngine engine= newSSLEngine();
LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols())); LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols()));
if (LOG.isDebugEnabled()) 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()) if (!isRunning())
throw new IllegalStateException("!STARTED"); throw new IllegalStateException("!STARTED");
SSLEngine sslEngine=isSessionCachingEnabled() SSLEngine sslEngine=isSessionCachingEnabled()
?_context.createSSLEngine(host, port) ?_context.createSSLEngine(host, port)
:_context.createSSLEngine(); :_context.createSSLEngine();
customize(sslEngine); customize(sslEngine);
return sslEngine; return sslEngine;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public SSLEngine newSslEngine() public SSLEngine newSSLEngine()
{ {
if (!isRunning()) if (!isRunning())
throw new IllegalStateException("!STARTED"); 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) return address != null ? newSSLEngine(address.getAddress().getHostAddress(), address.getPort()) : newSSLEngine();
?newSslEngine(address.getAddress().getHostAddress(), address.getPort())
:newSslEngine();
engine.setUseClientMode(false);
customize(engine);
return engine;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public String toString() public String toString()

View File

@ -5,11 +5,11 @@ package org.eclipse.jetty.webapp;
//All rights reserved. This program and the accompanying materials //All rights reserved. This program and the accompanying materials
//are made available under the terms of the Eclipse Public License v1.0 //are made available under the terms of the Eclipse Public License v1.0
//and Apache License v2.0 which accompanies this distribution. //and Apache License v2.0 which accompanies this distribution.
//The Eclipse Public License is available at //The Eclipse Public License is available at
//http://www.eclipse.org/legal/epl-v10.html //http://www.eclipse.org/legal/epl-v10.html
//The Apache License v2.0 is available at //The Apache License v2.0 is available at
//http://www.opensource.org/licenses/apache2.0.php //http://www.opensource.org/licenses/apache2.0.php
//You may elect to redistribute this code under either of these licenses. //You may elect to redistribute this code under either of these licenses.
//======================================================================== //========================================================================
import java.io.File; import java.io.File;
@ -23,6 +23,7 @@ import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.PatternMatcher; 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 TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured";
public static final String CONTAINER_JAR_PATTERN = "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern"; 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"; 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 * 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"; public static final String RESOURCE_URLS = "org.eclipse.jetty.resources";
protected Resource _preUnpackBaseResource; protected Resource _preUnpackBaseResource;
@Override @Override
public void preConfigure(final WebAppContext context) throws Exception public void preConfigure(final WebAppContext context) throws Exception
{ {
@ -56,16 +57,16 @@ public class WebInfConfiguration extends AbstractConfiguration
File work = findWorkDirectory(context); File work = findWorkDirectory(context);
if (work != null) if (work != null)
makeTempDirectory(work, context, false); makeTempDirectory(work, context, false);
//Make a temp directory for the webapp if one is not already set //Make a temp directory for the webapp if one is not already set
resolveTempDirectory(context); resolveTempDirectory(context);
//Extract webapp if necessary //Extract webapp if necessary
unpack (context); unpack (context);
//Apply an initial ordering to the jars which governs which will be scanned for META-INF //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); String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN);
Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp)); Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp));
tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN); tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN);
@ -78,7 +79,7 @@ public class WebInfConfiguration extends AbstractConfiguration
public void matched(URI uri) throws Exception public void matched(URI uri) throws Exception
{ {
context.getMetaData().addContainerJar(Resource.newResource(uri)); context.getMetaData().addContainerJar(Resource.newResource(uri));
} }
}; };
ClassLoader loader = context.getClassLoader(); ClassLoader loader = context.getClassLoader();
while (loader != null && (loader instanceof URLClassLoader)) while (loader != null && (loader instanceof URLClassLoader))
@ -90,21 +91,21 @@ public class WebInfConfiguration extends AbstractConfiguration
int i=0; int i=0;
for (URL u : urls) for (URL u : urls)
{ {
try try
{ {
containerUris[i] = u.toURI(); containerUris[i] = u.toURI();
} }
catch (URISyntaxException e) catch (URISyntaxException e)
{ {
containerUris[i] = new URI(u.toString().replaceAll(" ", "%20")); containerUris[i] = new URI(u.toString().replaceAll(" ", "%20"));
} }
i++; i++;
} }
containerJarNameMatcher.match(containerPattern, containerUris, false); containerJarNameMatcher.match(containerPattern, containerUris, false);
} }
loader = loader.getParent(); loader = loader.getParent();
} }
//Apply ordering to WEB-INF/lib jars //Apply ordering to WEB-INF/lib jars
PatternMatcher webInfJarNameMatcher = new PatternMatcher () PatternMatcher webInfJarNameMatcher = new PatternMatcher ()
{ {
@ -112,10 +113,10 @@ public class WebInfConfiguration extends AbstractConfiguration
public void matched(URI uri) throws Exception public void matched(URI uri) throws Exception
{ {
context.getMetaData().addWebInfJar(Resource.newResource(uri)); context.getMetaData().addWebInfJar(Resource.newResource(uri));
} }
}; };
List<Resource> jars = findJars(context); List<Resource> jars = findJars(context);
//Convert to uris for matching //Convert to uris for matching
URI[] uris = null; URI[] uris = null;
if (jars != null) if (jars != null)
@ -127,9 +128,9 @@ public class WebInfConfiguration extends AbstractConfiguration
uris[i++] = r.getURI(); 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 @Override
public void configure(WebAppContext context) throws Exception public void configure(WebAppContext context) throws Exception
@ -157,7 +158,7 @@ public class WebInfConfiguration extends AbstractConfiguration
if (lib.exists() || lib.isDirectory()) if (lib.exists() || lib.isDirectory())
((WebAppClassLoader)context.getClassLoader()).addJars(lib); ((WebAppClassLoader)context.getClassLoader()).addJars(lib);
} }
// Look for extra resource // Look for extra resource
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Resource> resources = (List<Resource>)context.getAttribute(RESOURCE_URLS); List<Resource> resources = (List<Resource>)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 // delete temp directory if we had to create it or if it isn't called work
Boolean tmpdirConfigured = (Boolean)context.getAttribute(TEMPDIR_CONFIGURED); Boolean tmpdirConfigured = (Boolean)context.getAttribute(TEMPDIR_CONFIGURED);
if (context.getTempDirectory()!=null && (tmpdirConfigured == null || !tmpdirConfigured.booleanValue()) && !isTempWorkDirectory(context.getTempDirectory())) if (context.getTempDirectory()!=null && (tmpdirConfigured == null || !tmpdirConfigured.booleanValue()) && !isTempWorkDirectory(context.getTempDirectory()))
{ {
IO.delete(context.getTempDirectory()); IO.delete(context.getTempDirectory());
context.setTempDirectory(null); context.setTempDirectory(null);
//clear out the context attributes for the tmp dir only if we had to //clear out the context attributes for the tmp dir only if we had to
//create the tmp dir //create the tmp dir
context.setAttribute(TEMPDIR_CONFIGURED, null); context.setAttribute(TEMPDIR_CONFIGURED, null);
context.setAttribute(WebAppContext.TEMPDIR, null); context.setAttribute(WebAppContext.TEMPDIR, null);
} }
//reset the base resource back to what it was before we did any unpacking of resources //reset the base resource back to what it was before we did any unpacking of resources
context.setBaseResource(_preUnpackBaseResource); context.setBaseResource(_preUnpackBaseResource);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @see org.eclipse.jetty.webapp.AbstractConfiguration#cloneConfigure(org.eclipse.jetty.webapp.WebAppContext, org.eclipse.jetty.webapp.WebAppContext) * @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. * Get a temporary directory in which to unpack the war etc etc.
* The algorithm for determining this is to check these alternatives * The algorithm for determining this is to check these alternatives
* in the order shown: * in the order shown:
* *
* <p>A. Try to use an explicit directory specifically for this webapp:</p> * <p>A. Try to use an explicit directory specifically for this webapp:</p>
* <ol> * <ol>
* <li> * <li>
@ -229,8 +230,8 @@ public class WebInfConfiguration extends AbstractConfiguration
* this webapp && exists && writeable, then use it. Do NOT set delete on exit. * this webapp && exists && writeable, then use it. Do NOT set delete on exit.
* </li> * </li>
* </ol> * </ol>
* *
* <p>B. Create a directory based on global settings. The new directory * <p>B. Create a directory based on global settings. The new directory
* will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost * will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost
* Work out where to create this directory: * Work out where to create this directory:
* <ol> * <ol>
@ -257,7 +258,7 @@ public class WebInfConfiguration extends AbstractConfiguration
context.setAttribute(TEMPDIR_CONFIGURED, Boolean.TRUE); context.setAttribute(TEMPDIR_CONFIGURED, Boolean.TRUE);
return; // Already have a suitable tmp dir configured return; // Already have a suitable tmp dir configured
} }
// No temp directory configured, try to establish one. // No temp directory configured, try to establish one.
// First we check the context specific, javax.servlet specified, temp directory attribute // 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. * Given an Object, return File reference for object.
* Typically used to convert anonymous Object from getAttribute() calls to a File 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()) if (parent != null && parent.exists() && parent.canWrite() && parent.isDirectory())
{ {
String temp = getCanonicalNameForWebAppTmpDir(context); String temp = getCanonicalNameForWebAppTmpDir(context);
File tmpDir = new File(parent,temp); File tmpDir = new File(parent,temp);
if (deleteExisting && tmpDir.exists()) 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(LOG.isDebugEnabled())LOG.debug("Failed to delete temp dir "+tmpDir);
} }
//If we can't delete the existing tmp dir, create a new one //If we can't delete the existing tmp dir, create a new one
if (tmpDir.exists()) if (tmpDir.exists())
{ {
@ -371,9 +372,9 @@ public class WebInfConfiguration extends AbstractConfiguration
if (tmpDir.exists()) if (tmpDir.exists())
IO.delete(tmpDir); IO.delete(tmpDir);
LOG.warn("Can't reuse "+old+", using "+tmpDir); LOG.warn("Can't reuse "+old+", using "+tmpDir);
} }
} }
if (!tmpDir.exists()) if (!tmpDir.exists())
tmpDir.mkdir(); tmpDir.mkdir();
@ -388,13 +389,13 @@ public class WebInfConfiguration extends AbstractConfiguration
context.setTempDirectory(tmpDir); context.setTempDirectory(tmpDir);
} }
} }
public void unpack (WebAppContext context) throws IOException public void unpack (WebAppContext context) throws IOException
{ {
Resource web_app = context.getBaseResource(); Resource web_app = context.getBaseResource();
_preUnpackBaseResource = context.getBaseResource(); _preUnpackBaseResource = context.getBaseResource();
if (web_app == null) if (web_app == null)
{ {
String war = context.getWar(); String war = context.getWar();
@ -425,7 +426,7 @@ public class WebInfConfiguration extends AbstractConfiguration
if (web_app.exists() && ( if (web_app.exists() && (
(context.isCopyWebDir() && web_app.getFile() != null && web_app.getFile().isDirectory()) || (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 && !web_app.getFile().isDirectory()) ||
(context.isExtractWAR() && web_app.getFile() == null) || (context.isExtractWAR() && web_app.getFile() == null) ||
!web_app.isDirectory()) !web_app.isDirectory())
) )
{ {
@ -443,7 +444,7 @@ public class WebInfConfiguration extends AbstractConfiguration
extractedWebAppDir=sibling; extractedWebAppDir=sibling;
} }
} }
if (extractedWebAppDir==null) if (extractedWebAppDir==null)
// Then extract it if necessary to the temporary location // Then extract it if necessary to the temporary location
extractedWebAppDir= new File(context.getTempDirectory(), "webapp"); 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. //Use a sentinel file that will exist only whilst the extraction is taking place.
//This will help us detect interrupted extractions. //This will help us detect interrupted extractions.
File extractionLock = new File (context.getTempDirectory(), ".extract_lock"); File extractionLock = new File (context.getTempDirectory(), ".extract_lock");
if (!extractedWebAppDir.exists()) if (!extractedWebAppDir.exists())
{ {
//it hasn't been extracted before so extract it //it hasn't been extracted before so extract it
extractionLock.createNewFile(); extractionLock.createNewFile();
extractedWebAppDir.mkdir(); extractedWebAppDir.mkdir();
LOG.info("Extract " + web_app + " to " + extractedWebAppDir); LOG.info("Extract " + web_app + " to " + extractedWebAppDir);
Resource jar_web_app = JarResource.newJarResource(web_app); Resource jar_web_app = JarResource.newJarResource(web_app);
jar_web_app.copyTo(extractedWebAppDir); jar_web_app.copyTo(extractedWebAppDir);
extractionLock.delete(); extractionLock.delete();
@ -484,7 +485,7 @@ public class WebInfConfiguration extends AbstractConfiguration
extractionLock.delete(); extractionLock.delete();
} }
} }
} }
web_app = Resource.newResource(extractedWebAppDir.getCanonicalPath()); web_app = Resource.newResource(extractedWebAppDir.getCanonicalPath());
} }
@ -494,13 +495,13 @@ public class WebInfConfiguration extends AbstractConfiguration
LOG.warn("Web application not found " + war); LOG.warn("Web application not found " + war);
throw new java.io.FileNotFoundException(war); throw new java.io.FileNotFoundException(war);
} }
context.setBaseResource(web_app); context.setBaseResource(web_app);
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("webapp=" + web_app); LOG.debug("webapp=" + web_app);
} }
// Do we need to extract WEB-INF/lib? // Do we need to extract WEB-INF/lib?
if (context.isCopyWebInf() && !context.isCopyWebDir()) if (context.isCopyWebInf() && !context.isCopyWebDir())
@ -544,11 +545,11 @@ public class WebInfConfiguration extends AbstractConfiguration
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("context.resourcebase = "+rc); LOG.debug("context.resourcebase = "+rc);
context.setBaseResource(rc); context.setBaseResource(rc);
} }
} }
public File findWorkDirectory (WebAppContext context) throws IOException public File findWorkDirectory (WebAppContext context) throws IOException
{ {
if (context.getBaseResource() != null) if (context.getBaseResource() != null)
@ -561,8 +562,8 @@ public class WebInfConfiguration extends AbstractConfiguration
} }
return null; return null;
} }
/** /**
* Check if the tmpDir itself is called "work", or if the tmpDir * Check if the tmpDir itself is called "work", or if the tmpDir
* is in a directory called "work". * is in a directory called "work".
@ -579,13 +580,13 @@ public class WebInfConfiguration extends AbstractConfiguration
return false; return false;
return (t.getName().equalsIgnoreCase("work")); return (t.getName().equalsIgnoreCase("work"));
} }
/** /**
* Create a canonical name for a webapp temp directory. * Create a canonical name for a webapp temp directory.
* The form of the name is: * The form of the name is:
* <code>"Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36_hashcode_of_whole_string</code> * <code>"Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36_hashcode_of_whole_string</code>
* *
* host and port uniquely identify the server * host and port uniquely identify the server
* context and virtual host uniquely identify the webapp * context and virtual host uniquely identify the webapp
* @return the canonical name for the webapp temp directory * @return the canonical name for the webapp temp directory
@ -594,8 +595,8 @@ public class WebInfConfiguration extends AbstractConfiguration
{ {
StringBuffer canonicalName = new StringBuffer(); StringBuffer canonicalName = new StringBuffer();
canonicalName.append("jetty-"); 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(); Server server=context.getServer();
if (server!=null) if (server!=null)
{ {
@ -606,9 +607,9 @@ public class WebInfConfiguration extends AbstractConfiguration
//Get the host //Get the host
String host=null; String host=null;
int port=0; 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(); host=connector.getHost();
port=connector.getLocalPort(); port=connector.getLocalPort();
if (port < 0) if (port < 0)
@ -617,18 +618,18 @@ public class WebInfConfiguration extends AbstractConfiguration
if (host == null) if (host == null)
host = "0.0.0.0"; host = "0.0.0.0";
canonicalName.append(host); canonicalName.append(host);
//Get the port //Get the port
canonicalName.append("-"); 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. //try getting one that was configured.
canonicalName.append(port); canonicalName.append(port);
canonicalName.append("-"); canonicalName.append("-");
} }
} }
//Resource base //Resource base
try try
{ {
@ -637,11 +638,11 @@ public class WebInfConfiguration extends AbstractConfiguration
{ {
if (context.getWar()==null || context.getWar().length()==0) if (context.getWar()==null || context.getWar().length()==0)
resource=context.newResource(context.getResourceBase()); resource=context.newResource(context.getResourceBase());
// Set dir or WAR // Set dir or WAR
resource = context.newResource(context.getWar()); resource = context.newResource(context.getWar());
} }
String tmp = URIUtil.decodePath(resource.getURL().getPath()); String tmp = URIUtil.decodePath(resource.getURL().getPath());
if (tmp.endsWith("/")) if (tmp.endsWith("/"))
tmp = tmp.substring(0, tmp.length()-1); 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); LOG.warn("Can't generate resourceBase as part of webapp tmp dir name", e);
} }
//Context name //Context name
String contextPath = context.getContextPath(); String contextPath = context.getContextPath();
contextPath=contextPath.replace('/','_'); contextPath=contextPath.replace('/','_');
contextPath=contextPath.replace('\\','_'); contextPath=contextPath.replace('\\','_');
canonicalName.append(contextPath); canonicalName.append(contextPath);
//Virtual host (if there is one) //Virtual host (if there is one)
canonicalName.append("-"); canonicalName.append("-");
String[] vhosts = context.getVirtualHosts(); String[] vhosts = context.getVirtualHosts();
@ -670,43 +671,43 @@ public class WebInfConfiguration extends AbstractConfiguration
canonicalName.append("any"); canonicalName.append("any");
else else
canonicalName.append(vhosts[0]); canonicalName.append(vhosts[0]);
// sanitize // sanitize
for (int i=0;i<canonicalName.length();i++) for (int i=0;i<canonicalName.length();i++)
{ {
char c=canonicalName.charAt(i); char c=canonicalName.charAt(i);
if (!Character.isJavaIdentifierPart(c) && "-.".indexOf(c)<0) if (!Character.isJavaIdentifierPart(c) && "-.".indexOf(c)<0)
canonicalName.setCharAt(i,'.'); canonicalName.setCharAt(i,'.');
} }
canonicalName.append("-"); canonicalName.append("-");
return canonicalName.toString(); return canonicalName.toString();
} }
/** /**
* Look for jars in WEB-INF/lib * Look for jars in WEB-INF/lib
* @param context * @param context
* @return the list of jar resources found within context * @return the list of jar resources found within context
* @throws Exception * @throws Exception
*/ */
protected List<Resource> findJars (WebAppContext context) protected List<Resource> findJars (WebAppContext context)
throws Exception throws Exception
{ {
List<Resource> jarResources = new ArrayList<Resource>(); List<Resource> jarResources = new ArrayList<Resource>();
Resource web_inf = context.getWebInf(); Resource web_inf = context.getWebInf();
if (web_inf==null || !web_inf.exists()) if (web_inf==null || !web_inf.exists())
return null; return null;
Resource web_inf_lib = web_inf.addPath("/lib"); Resource web_inf_lib = web_inf.addPath("/lib");
if (web_inf_lib.exists() && web_inf_lib.isDirectory()) if (web_inf_lib.exists() && web_inf_lib.isDirectory())
{ {
String[] files=web_inf_lib.list(); String[] files=web_inf_lib.list();
for (int f=0;files!=null && f<files.length;f++) for (int f=0;files!=null && f<files.length;f++)
{ {
try try
{ {
Resource file = web_inf_lib.addPath(files[f]); Resource file = web_inf_lib.addPath(files[f]);
String fnlc = file.getName().toLowerCase(); String fnlc = file.getName().toLowerCase();

View File

@ -21,18 +21,16 @@ import java.nio.channels.SocketChannel;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.SelectChannelEndPoint; import org.eclipse.jetty.io.SelectChannelEndPoint;
import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SelectorManager;
import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.client.WebSocketClient; import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.client.WebSocketClientFactory; import org.eclipse.jetty.websocket.client.WebSocketClientFactory;
@ -146,7 +144,7 @@ public class WebSocketClientSelectorManager extends SelectorManager
{ {
String peerHost = channel.socket().getInetAddress().getHostAddress(); String peerHost = channel.socket().getInetAddress().getHostAddress();
int peerPort = channel.socket().getPort(); int peerPort = channel.socket().getPort();
SSLEngine engine = sslContextFactory.newSslEngine(peerHost,peerPort); SSLEngine engine = sslContextFactory.newSSLEngine(peerHost, peerPort);
engine.setUseClientMode(true); engine.setUseClientMode(true);
return engine; return engine;
} }

View File

@ -22,7 +22,6 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.SelectChannelConnector;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback; import org.eclipse.jetty.util.FutureCallback;
@ -95,13 +94,13 @@ public class WebSocketOverSSLTest
private void startServer(final Object websocket) throws Exception private void startServer(final Object websocket) throws Exception
{ {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath());
sslContextFactory.setKeyStorePassword("storepwd");
sslContextFactory.setKeyManagerPassword("keypwd");
_server = new Server(); _server = new Server();
SelectChannelConnector connector = new SelectChannelConnector(_server,true); SelectChannelConnector connector = new SelectChannelConnector(_server, sslContextFactory);
_server.addConnector(connector); _server.addConnector(connector);
SslContextFactory cf = connector.getConnectionFactory().getSslContextFactory();
cf.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath());
cf.setKeyStorePassword("storepwd");
cf.setKeyManagerPassword("keypwd");
_server.setHandler(new WebSocketHandler.Simple(websocket.getClass())); _server.setHandler(new WebSocketHandler.Simple(websocket.getClass()));
_server.start(); _server.start();
_port = connector.getLocalPort(); _port = connector.getLocalPort();