jetty-9 added FilterConnectionFactory and made SpdyServer use it
This commit is contained in:
parent
c5d8fd748b
commit
f4d12412eb
|
@ -0,0 +1,186 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-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.embedded;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||||
|
import org.eclipse.jetty.deploy.providers.ContextProvider;
|
||||||
|
import org.eclipse.jetty.deploy.providers.WebAppProvider;
|
||||||
|
import org.eclipse.jetty.io.ArrayByteBufferPool;
|
||||||
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
|
import org.eclipse.jetty.io.FilterConnection;
|
||||||
|
import org.eclipse.jetty.jmx.MBeanContainer;
|
||||||
|
import org.eclipse.jetty.security.HashLoginService;
|
||||||
|
import org.eclipse.jetty.server.FilterConnectionFactory;
|
||||||
|
import org.eclipse.jetty.server.ForwardedRequestCustomizer;
|
||||||
|
import org.eclipse.jetty.server.Handler;
|
||||||
|
import org.eclipse.jetty.server.HttpChannelConfig;
|
||||||
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
|
import org.eclipse.jetty.server.NCSARequestLog;
|
||||||
|
import org.eclipse.jetty.server.SecureRequestCustomizer;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
|
import org.eclipse.jetty.server.SslConnectionFactory;
|
||||||
|
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||||
|
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
|
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||||
|
import org.eclipse.jetty.server.handler.RequestLogHandler;
|
||||||
|
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||||
|
import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
|
||||||
|
import org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory;
|
||||||
|
import org.eclipse.jetty.spdy.server.http.PushStrategy;
|
||||||
|
import org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy;
|
||||||
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
|
import org.eclipse.jetty.util.thread.TimerScheduler;
|
||||||
|
|
||||||
|
public class SpdyServer
|
||||||
|
{
|
||||||
|
public static void main(String[] args) throws Exception
|
||||||
|
{
|
||||||
|
String jetty_home = System.getProperty("jetty.home","../jetty-distribution/target/distribution");
|
||||||
|
System.setProperty("jetty.home",jetty_home);
|
||||||
|
|
||||||
|
// Setup Threadpool
|
||||||
|
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||||
|
threadPool.setMaxThreads(500);
|
||||||
|
|
||||||
|
Server server = new Server(threadPool);
|
||||||
|
server.manage(threadPool);
|
||||||
|
server.setDumpAfterStart(false);
|
||||||
|
server.setDumpBeforeStop(false);
|
||||||
|
|
||||||
|
// Setup JMX
|
||||||
|
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
|
||||||
|
server.addBean(mbContainer);
|
||||||
|
|
||||||
|
|
||||||
|
// Common HTTP configuration
|
||||||
|
HttpChannelConfig config = new HttpChannelConfig();
|
||||||
|
config.setSecurePort(8443);
|
||||||
|
config.addCustomizer(new ForwardedRequestCustomizer());
|
||||||
|
config.addCustomizer(new SecureRequestCustomizer());
|
||||||
|
|
||||||
|
|
||||||
|
// Http Connector
|
||||||
|
HttpConnectionFactory http = new HttpConnectionFactory(config);
|
||||||
|
FilterConnectionFactory filter = new FilterConnectionFactory(http.getProtocol());
|
||||||
|
filter.addFilter(new FilterConnection.DumpToFileFilter("http-"));
|
||||||
|
ServerConnector httpConnector = new ServerConnector(server,filter,http);
|
||||||
|
httpConnector.setPort(8080);
|
||||||
|
httpConnector.setIdleTimeout(30000);
|
||||||
|
|
||||||
|
server.addConnector(httpConnector);
|
||||||
|
|
||||||
|
|
||||||
|
// SSL configurations
|
||||||
|
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||||
|
sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore");
|
||||||
|
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||||
|
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
|
||||||
|
sslContextFactory.setTrustStorePath(jetty_home + "/etc/keystore");
|
||||||
|
sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||||
|
sslContextFactory.setExcludeCipherSuites(
|
||||||
|
"SSL_RSA_WITH_DES_CBC_SHA",
|
||||||
|
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
|
||||||
|
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
|
||||||
|
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
|
||||||
|
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
||||||
|
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
||||||
|
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Spdy Connector
|
||||||
|
|
||||||
|
PushStrategy push = new ReferrerPushStrategy();
|
||||||
|
HTTPSPDYServerConnectionFactory spdy2 = new HTTPSPDYServerConnectionFactory(2,config,push);
|
||||||
|
spdy2.setInputBufferSize(8192);
|
||||||
|
spdy2.setInitialWindowSize(32768);
|
||||||
|
|
||||||
|
HTTPSPDYServerConnectionFactory spdy3 = new HTTPSPDYServerConnectionFactory(3,config,push);
|
||||||
|
spdy2.setInputBufferSize(8192);
|
||||||
|
|
||||||
|
NPNServerConnectionFactory npn = new NPNServerConnectionFactory(spdy3.getProtocol(),spdy2.getProtocol(),http.getProtocol());
|
||||||
|
npn.setDefaultProtocol(http.getProtocol());
|
||||||
|
npn.setInputBufferSize(1024);
|
||||||
|
|
||||||
|
FilterConnectionFactory npn_filter = new FilterConnectionFactory(npn.getProtocol());
|
||||||
|
npn_filter.addFilter(new FilterConnection.DumpToFileFilter("npn-"));
|
||||||
|
|
||||||
|
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory,npn_filter.getProtocol());
|
||||||
|
FilterConnectionFactory ssl_filter = new FilterConnectionFactory(ssl.getProtocol());
|
||||||
|
ssl_filter.addFilter(new FilterConnection.DumpToFileFilter("ssl-"));
|
||||||
|
|
||||||
|
ServerConnector spdyConnector = new ServerConnector(server,ssl_filter,ssl,npn_filter,npn,spdy3,spdy2,http);
|
||||||
|
spdyConnector.setPort(8443);
|
||||||
|
|
||||||
|
server.addConnector(spdyConnector);
|
||||||
|
|
||||||
|
|
||||||
|
// Setup handlers
|
||||||
|
HandlerCollection handlers = new HandlerCollection();
|
||||||
|
ContextHandlerCollection contexts = new ContextHandlerCollection();
|
||||||
|
RequestLogHandler requestLogHandler = new RequestLogHandler();
|
||||||
|
|
||||||
|
handlers.setHandlers(new Handler[] { contexts, new DefaultHandler(), requestLogHandler });
|
||||||
|
|
||||||
|
StatisticsHandler stats = new StatisticsHandler();
|
||||||
|
stats.setHandler(handlers);
|
||||||
|
|
||||||
|
server.setHandler(stats);
|
||||||
|
|
||||||
|
// Setup deployers
|
||||||
|
DeploymentManager deployer = new DeploymentManager();
|
||||||
|
deployer.setContexts(contexts);
|
||||||
|
server.addBean(deployer);
|
||||||
|
|
||||||
|
ContextProvider context_provider = new ContextProvider();
|
||||||
|
context_provider.setMonitoredDirName(jetty_home + "/contexts");
|
||||||
|
context_provider.setScanInterval(2);
|
||||||
|
deployer.addAppProvider(context_provider);
|
||||||
|
|
||||||
|
WebAppProvider webapp_provider = new WebAppProvider();
|
||||||
|
webapp_provider.setMonitoredDirName(jetty_home + "/webapps");
|
||||||
|
webapp_provider.setParentLoaderPriority(false);
|
||||||
|
webapp_provider.setExtractWars(true);
|
||||||
|
webapp_provider.setScanInterval(2);
|
||||||
|
webapp_provider.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml");
|
||||||
|
webapp_provider.setContextXmlDir(jetty_home + "/contexts");
|
||||||
|
deployer.addAppProvider(webapp_provider);
|
||||||
|
|
||||||
|
HashLoginService login = new HashLoginService();
|
||||||
|
login.setName("Test Realm");
|
||||||
|
login.setConfig(jetty_home + "/etc/realm.properties");
|
||||||
|
server.addBean(login);
|
||||||
|
|
||||||
|
NCSARequestLog requestLog = new NCSARequestLog(jetty_home + "/logs/jetty-yyyy_mm_dd.log");
|
||||||
|
requestLog.setExtended(false);
|
||||||
|
requestLogHandler.setRequestLog(requestLog);
|
||||||
|
|
||||||
|
server.setStopAtShutdown(true);
|
||||||
|
server.setSendServerVersion(true);
|
||||||
|
|
||||||
|
server.start();
|
||||||
|
server.dumpStdErr();
|
||||||
|
server.join();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||||
#org.eclipse.jetty.LEVEL=DEBUG
|
#org.eclipse.jetty.LEVEL=DEBUG
|
||||||
org.eclipse.jetty.client.LEVEL=DEBUG
|
#org.eclipse.jetty.client.LEVEL=DEBUG
|
||||||
|
|
|
@ -202,11 +202,12 @@ public abstract class AbstractEndPoint implements EndPoint
|
||||||
{
|
{
|
||||||
LOG.debug("{} idle timeout expired", this);
|
LOG.debug("{} idle timeout expired", this);
|
||||||
|
|
||||||
|
boolean output_shutdown=isOutputShutdown();
|
||||||
TimeoutException timeout = new TimeoutException("Idle timeout expired: " + idleElapsed + "/" + idleTimeout + " ms");
|
TimeoutException timeout = new TimeoutException("Idle timeout expired: " + idleElapsed + "/" + idleTimeout + " ms");
|
||||||
_fillInterest.onFail(timeout);
|
_fillInterest.onFail(timeout);
|
||||||
_writeFlusher.onFail(timeout);
|
_writeFlusher.onFail(timeout);
|
||||||
|
|
||||||
if (isOutputShutdown())
|
if (output_shutdown)
|
||||||
close();
|
close();
|
||||||
notIdle();
|
notIdle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,11 +75,14 @@ public class ArrayByteBufferPool implements ByteBufferPool
|
||||||
@Override
|
@Override
|
||||||
public void release(ByteBuffer buffer)
|
public void release(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
Bucket bucket = bucketFor(buffer.capacity(),buffer.isDirect());
|
if (buffer!=null)
|
||||||
if (bucket!=null)
|
|
||||||
{
|
{
|
||||||
BufferUtil.clear(buffer);
|
Bucket bucket = bucketFor(buffer.capacity(),buffer.isDirect());
|
||||||
bucket._queue.offer(buffer);
|
if (bucket!=null)
|
||||||
|
{
|
||||||
|
BufferUtil.clear(buffer);
|
||||||
|
bucket._queue.offer(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ import java.util.concurrent.Executor;
|
||||||
|
|
||||||
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.annotation.Name;
|
||||||
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;
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ public class FilterConnection extends AbstractConnection
|
||||||
private static final Logger LOG = Log.getLogger(FilterConnection.class);
|
private static final Logger LOG = Log.getLogger(FilterConnection.class);
|
||||||
private static final boolean DEBUG = LOG.isDebugEnabled(); // Easy for the compiler to remove the code if DEBUG==false
|
private static final boolean DEBUG = LOG.isDebugEnabled(); // Easy for the compiler to remove the code if DEBUG==false
|
||||||
|
|
||||||
public interface Listener
|
public interface Filter
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* <p>Callback method invoked when a connection from a remote client has been accepted.</p>
|
* <p>Callback method invoked when a connection from a remote client has been accepted.</p>
|
||||||
|
@ -87,13 +88,12 @@ public class FilterConnection extends AbstractConnection
|
||||||
public void closed(EndPoint endpoint);
|
public void closed(EndPoint endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DebugListener implements Listener
|
public static class DebugFilter implements Filter
|
||||||
{
|
{
|
||||||
public DebugListener()
|
public DebugFilter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void opened(EndPoint endpoint)
|
public void opened(EndPoint endpoint)
|
||||||
{
|
{
|
||||||
|
@ -123,13 +123,43 @@ public class FilterConnection extends AbstractConnection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FileDumpListener implements Listener
|
public static class DumpToFileFilter implements Filter
|
||||||
{
|
{
|
||||||
final ConcurrentHashMap<EndPoint,OutputStream> _in = new ConcurrentHashMap<>();
|
final ConcurrentHashMap<EndPoint,OutputStream> _in = new ConcurrentHashMap<>();
|
||||||
final ConcurrentHashMap<EndPoint,OutputStream> _out = new ConcurrentHashMap<>();
|
final ConcurrentHashMap<EndPoint,OutputStream> _out = new ConcurrentHashMap<>();
|
||||||
|
final File _directory;
|
||||||
|
final String _prefix;
|
||||||
|
final boolean _deleteOnExit;
|
||||||
|
|
||||||
public FileDumpListener()
|
public DumpToFileFilter()
|
||||||
{
|
{
|
||||||
|
this(new File(System.getProperty("java.io.tmpdir")+File.separator+"FilterConnection"),true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DumpToFileFilter(File directory, boolean deleteOnExit)
|
||||||
|
{
|
||||||
|
this(directory,"dump-",deleteOnExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DumpToFileFilter(String prefix)
|
||||||
|
{
|
||||||
|
this(new File(System.getProperty("java.io.tmpdir")+File.separator+"FilterConnection"),prefix,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DumpToFileFilter(
|
||||||
|
@Name("directory") File directory,
|
||||||
|
@Name("prefix") String prefix,
|
||||||
|
@Name("deleteOnExit") boolean deleteOnExit)
|
||||||
|
{
|
||||||
|
_directory=directory;
|
||||||
|
_prefix=prefix;
|
||||||
|
_deleteOnExit=deleteOnExit;
|
||||||
|
if (!_directory.exists() && !_directory.mkdirs())
|
||||||
|
throw new IllegalArgumentException("cannot create "+directory);
|
||||||
|
if (!_directory.isDirectory())
|
||||||
|
throw new IllegalArgumentException("not directory "+directory);
|
||||||
|
if (!_directory.canWrite())
|
||||||
|
throw new IllegalArgumentException("cannot write "+directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -137,9 +167,14 @@ public class FilterConnection extends AbstractConnection
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File in = new File("/tmp/dump-"+Integer.toHexString(endpoint.hashCode())+".in");
|
File in = new File(_directory,_prefix+Integer.toHexString(endpoint.hashCode())+".in");
|
||||||
|
File out = new File(_directory,_prefix+Integer.toHexString(endpoint.hashCode())+".out");
|
||||||
|
if (_deleteOnExit)
|
||||||
|
{
|
||||||
|
in.deleteOnExit();
|
||||||
|
out.deleteOnExit();
|
||||||
|
}
|
||||||
_in.put(endpoint,new FileOutputStream(in));
|
_in.put(endpoint,new FileOutputStream(in));
|
||||||
File out = new File("/tmp/dump-"+Integer.toHexString(endpoint.hashCode())+".out");
|
|
||||||
_out.put(endpoint,new FileOutputStream(out));
|
_out.put(endpoint,new FileOutputStream(out));
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException e)
|
catch (FileNotFoundException e)
|
||||||
|
@ -206,7 +241,7 @@ public class FilterConnection extends AbstractConnection
|
||||||
private final ByteBufferPool _bufferPool;
|
private final ByteBufferPool _bufferPool;
|
||||||
private final FilteredEndPoint _filterEndPoint;
|
private final FilteredEndPoint _filterEndPoint;
|
||||||
private final int _outputBufferSize;
|
private final int _outputBufferSize;
|
||||||
private final List<Listener> _listeners = new CopyOnWriteArrayList<>();
|
private final List<Filter> _filters = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
public FilterConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, int outputBufferSize)
|
public FilterConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, int outputBufferSize)
|
||||||
{
|
{
|
||||||
|
@ -226,30 +261,30 @@ public class FilterConnection extends AbstractConnection
|
||||||
return _filterEndPoint;
|
return _filterEndPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(Listener listener)
|
public void addFilter(Filter filter)
|
||||||
{
|
{
|
||||||
_listeners.add(listener);
|
_filters.add(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeListener(Listener listener)
|
public boolean removeFilter(Filter listener)
|
||||||
{
|
{
|
||||||
return _listeners.remove(listener);
|
return _filters.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen()
|
public void onOpen()
|
||||||
{
|
{
|
||||||
super.onOpen();
|
super.onOpen();
|
||||||
for (Listener listener: _listeners)
|
for (Filter filter: _filters)
|
||||||
listener.opened(getEndPoint());
|
filter.opened(getEndPoint());
|
||||||
getFilterEndPoint().getConnection().onOpen();
|
getFilterEndPoint().getConnection().onOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
for (Listener listener: _listeners)
|
for (Filter filter: _filters)
|
||||||
listener.closed(getEndPoint());
|
filter.closed(getEndPoint());
|
||||||
_filterEndPoint.getConnection().onClose();
|
_filterEndPoint.getConnection().onClose();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
@ -372,8 +407,8 @@ public class FilterConnection extends AbstractConnection
|
||||||
|
|
||||||
if (orig>0)
|
if (orig>0)
|
||||||
buffer.position(buffer.position()+orig);
|
buffer.position(buffer.position()+orig);
|
||||||
for (Listener listener: _listeners)
|
for (Filter filter: _filters)
|
||||||
listener.incoming(getEndPoint() ,buffer);
|
filter.incoming(getEndPoint() ,buffer);
|
||||||
if (orig>0)
|
if (orig>0)
|
||||||
buffer.position(buffer.position()-orig);
|
buffer.position(buffer.position()-orig);
|
||||||
|
|
||||||
|
@ -410,8 +445,8 @@ public class FilterConnection extends AbstractConnection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Listener listener: _listeners)
|
for (Filter filter: _filters)
|
||||||
listener.outgoing(getEndPoint() ,_outBuffer);
|
filter.outgoing(getEndPoint() ,_outBuffer);
|
||||||
|
|
||||||
boolean flushed = getEndPoint().flush(_outBuffer);
|
boolean flushed = getEndPoint().flush(_outBuffer);
|
||||||
if (BufferUtil.isEmpty(_outBuffer))
|
if (BufferUtil.isEmpty(_outBuffer))
|
||||||
|
@ -462,6 +497,11 @@ public class FilterConnection extends AbstractConnection
|
||||||
return getEndPoint().isInputShutdown();
|
return getEndPoint().isInputShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EndPoint getWrappedEndPoint()
|
||||||
|
{
|
||||||
|
return getEndPoint();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
|
|
@ -328,11 +328,6 @@ public class SslConnection extends AbstractConnection
|
||||||
super(null,getEndPoint().getLocalAddress(), getEndPoint().getRemoteAddress());
|
super(null,getEndPoint().getLocalAddress(), getEndPoint().getRemoteAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
public EndPoint getEncryptedEndPoint()
|
|
||||||
{
|
|
||||||
return getEndPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FillInterest getFillInterest()
|
protected FillInterest getFillInterest()
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class FilteredSelectChannelEndPointTest extends SelectChannelEndPointTest
|
||||||
protected Connection newConnection(SocketChannel channel, EndPoint endpoint)
|
protected Connection newConnection(SocketChannel channel, EndPoint endpoint)
|
||||||
{
|
{
|
||||||
FilterConnection filter = new FilterConnection(new MappedByteBufferPool(),_threadPool,endpoint,8192);
|
FilterConnection filter = new FilterConnection(new MappedByteBufferPool(),_threadPool,endpoint,8192);
|
||||||
filter.addListener(new FilterConnection.FileDumpListener());
|
filter.addFilter(new FilterConnection.DumpToFileFilter());
|
||||||
Connection connection= super.newConnection(null,filter.getFilterEndPoint());
|
Connection connection= super.newConnection(null,filter.getFilterEndPoint());
|
||||||
filter.getFilterEndPoint().setConnection(connection);
|
filter.getFilterEndPoint().setConnection(connection);
|
||||||
return filter;
|
return filter;
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-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.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
|
import org.eclipse.jetty.io.Connection;
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
|
import org.eclipse.jetty.io.FilterConnection;
|
||||||
|
import org.eclipse.jetty.util.annotation.Name;
|
||||||
|
|
||||||
|
public class FilterConnectionFactory extends AbstractConnectionFactory
|
||||||
|
{
|
||||||
|
private final String _nextProtocol;
|
||||||
|
private final int _outputBufferSize;
|
||||||
|
private final CopyOnWriteArrayList<FilterConnection.Filter> _filters = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
public FilterConnectionFactory()
|
||||||
|
{
|
||||||
|
this(HttpVersion.HTTP_1_1.asString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterConnectionFactory(String nextProtocol)
|
||||||
|
{
|
||||||
|
this(nextProtocol,16*1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterConnectionFactory(@Name("nextProtocol") String nextProtocol,@Name("outputBufferSize") int outputBufferSize)
|
||||||
|
{
|
||||||
|
super("filter-"+nextProtocol);
|
||||||
|
_nextProtocol=nextProtocol;
|
||||||
|
_outputBufferSize=outputBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection newConnection(Connector connector, EndPoint endPoint)
|
||||||
|
{
|
||||||
|
FilterConnection filteredConnection = new FilterConnection(connector.getByteBufferPool(),connector.getExecutor(),endPoint,_outputBufferSize);
|
||||||
|
|
||||||
|
configure(filteredConnection, connector, endPoint);
|
||||||
|
addFilters(connector, filteredConnection);
|
||||||
|
|
||||||
|
ConnectionFactory next = connector.getConnectionFactory(_nextProtocol);
|
||||||
|
EndPoint filteredEndPoint = filteredConnection.getFilterEndPoint();
|
||||||
|
|
||||||
|
Connection connection = next.newConnection(connector, filteredEndPoint);
|
||||||
|
filteredEndPoint.setConnection(connection);
|
||||||
|
|
||||||
|
return filteredConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addFilters(Connector connector, FilterConnection filteredConnection)
|
||||||
|
{
|
||||||
|
for (FilterConnection.Filter filter : _filters)
|
||||||
|
filteredConnection.addFilter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFilter(FilterConnection.Filter filter)
|
||||||
|
{
|
||||||
|
addBean(filter);
|
||||||
|
_filters.add(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeFilter(FilterConnection.Filter filter)
|
||||||
|
{
|
||||||
|
removeBean(filter);
|
||||||
|
return _filters.remove(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,12 @@ import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
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.FilterConnection;
|
||||||
|
import org.eclipse.jetty.io.ssl.SslConnection;
|
||||||
import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint;
|
import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint;
|
||||||
import org.eclipse.jetty.npn.NextProtoNego;
|
import org.eclipse.jetty.npn.NextProtoNego;
|
||||||
import org.eclipse.jetty.server.AbstractConnectionFactory;
|
import org.eclipse.jetty.server.AbstractConnectionFactory;
|
||||||
|
@ -97,7 +101,19 @@ public class NPNServerConnectionFactory extends AbstractConnectionFactory
|
||||||
if (dft==null)
|
if (dft==null)
|
||||||
dft=_protocols.get(0);
|
dft=_protocols.get(0);
|
||||||
|
|
||||||
return configure(new NextProtoNegoServerConnection((DecryptedEndPoint)endPoint, connector,protocols,_defaultProtocol),connector,endPoint);
|
SSLEngine engine=null;
|
||||||
|
EndPoint ep=endPoint;
|
||||||
|
while(engine==null && ep!=null)
|
||||||
|
{
|
||||||
|
if (ep instanceof SslConnection.DecryptedEndPoint)
|
||||||
|
engine=((SslConnection.DecryptedEndPoint)ep).getSslConnection().getSSLEngine();
|
||||||
|
if (ep instanceof FilterConnection.FilteredEndPoint) // TODO make more generic
|
||||||
|
ep=((FilterConnection.FilteredEndPoint)ep).getWrappedEndPoint();
|
||||||
|
else
|
||||||
|
ep=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return configure(new NextProtoNegoServerConnection(endPoint, engine, connector,protocols,_defaultProtocol),connector,endPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -42,13 +42,13 @@ public class NextProtoNegoServerConnection extends AbstractConnection implements
|
||||||
private final String defaultProtocol;
|
private final String defaultProtocol;
|
||||||
private String nextProtocol; // No need to be volatile: it is modified and read by the same thread
|
private String nextProtocol; // No need to be volatile: it is modified and read by the same thread
|
||||||
|
|
||||||
public NextProtoNegoServerConnection(DecryptedEndPoint endPoint, Connector connector, List<String>protocols, String defaultProtocol)
|
public NextProtoNegoServerConnection(EndPoint endPoint, SSLEngine engine, Connector connector, List<String>protocols, String defaultProtocol)
|
||||||
{
|
{
|
||||||
super(endPoint, connector.getExecutor());
|
super(endPoint, connector.getExecutor());
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
this.protocols = protocols;
|
this.protocols = protocols;
|
||||||
this.defaultProtocol = defaultProtocol;
|
this.defaultProtocol = defaultProtocol;
|
||||||
engine = endPoint.getSslConnection().getSSLEngine();
|
this.engine = engine;
|
||||||
NextProtoNego.put(engine, this);
|
NextProtoNego.put(engine, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue