diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java new file mode 100644 index 00000000000..c5a7cde7fb2 --- /dev/null +++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java @@ -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(); + } +} diff --git a/jetty-client/src/test/resources/jetty-logging.properties b/jetty-client/src/test/resources/jetty-logging.properties index b53f7809211..1c19e5331e5 100644 --- a/jetty-client/src/test/resources/jetty-logging.properties +++ b/jetty-client/src/test/resources/jetty-logging.properties @@ -1,3 +1,3 @@ org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog #org.eclipse.jetty.LEVEL=DEBUG -org.eclipse.jetty.client.LEVEL=DEBUG +#org.eclipse.jetty.client.LEVEL=DEBUG diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java index 44177a76975..0eb655dd91e 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java @@ -202,11 +202,12 @@ public abstract class AbstractEndPoint implements EndPoint { LOG.debug("{} idle timeout expired", this); + boolean output_shutdown=isOutputShutdown(); TimeoutException timeout = new TimeoutException("Idle timeout expired: " + idleElapsed + "/" + idleTimeout + " ms"); _fillInterest.onFail(timeout); _writeFlusher.onFail(timeout); - if (isOutputShutdown()) + if (output_shutdown) close(); notIdle(); } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java index 1946ba3f22c..6efca46faf6 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java @@ -75,11 +75,14 @@ public class ArrayByteBufferPool implements ByteBufferPool @Override public void release(ByteBuffer buffer) { - Bucket bucket = bucketFor(buffer.capacity(),buffer.isDirect()); - if (bucket!=null) - { - BufferUtil.clear(buffer); - bucket._queue.offer(buffer); + if (buffer!=null) + { + Bucket bucket = bucketFor(buffer.capacity(),buffer.isDirect()); + if (bucket!=null) + { + BufferUtil.clear(buffer); + bucket._queue.offer(buffer); + } } } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/FilterConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/FilterConnection.java index c61263ffc9e..fa0928642d3 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/FilterConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/FilterConnection.java @@ -35,6 +35,7 @@ import java.util.concurrent.Executor; import org.eclipse.jetty.util.BufferUtil; 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.Logger; @@ -46,7 +47,7 @@ public class FilterConnection extends AbstractConnection 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 - public interface Listener + public interface Filter { /** *

Callback method invoked when a connection from a remote client has been accepted.

@@ -87,13 +88,12 @@ public class FilterConnection extends AbstractConnection public void closed(EndPoint endpoint); } - public static class DebugListener implements Listener + public static class DebugFilter implements Filter { - public DebugListener() + public DebugFilter() { } - @Override 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 _in = new ConcurrentHashMap<>(); final ConcurrentHashMap _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 @@ -137,9 +167,14 @@ public class FilterConnection extends AbstractConnection { 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)); - File out = new File("/tmp/dump-"+Integer.toHexString(endpoint.hashCode())+".out"); _out.put(endpoint,new FileOutputStream(out)); } catch (FileNotFoundException e) @@ -206,7 +241,7 @@ public class FilterConnection extends AbstractConnection private final ByteBufferPool _bufferPool; private final FilteredEndPoint _filterEndPoint; private final int _outputBufferSize; - private final List _listeners = new CopyOnWriteArrayList<>(); + private final List _filters = new CopyOnWriteArrayList<>(); public FilterConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, int outputBufferSize) { @@ -226,30 +261,30 @@ public class FilterConnection extends AbstractConnection 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 public void onOpen() { super.onOpen(); - for (Listener listener: _listeners) - listener.opened(getEndPoint()); + for (Filter filter: _filters) + filter.opened(getEndPoint()); getFilterEndPoint().getConnection().onOpen(); } @Override public void onClose() { - for (Listener listener: _listeners) - listener.closed(getEndPoint()); + for (Filter filter: _filters) + filter.closed(getEndPoint()); _filterEndPoint.getConnection().onClose(); super.onClose(); } @@ -372,8 +407,8 @@ public class FilterConnection extends AbstractConnection if (orig>0) buffer.position(buffer.position()+orig); - for (Listener listener: _listeners) - listener.incoming(getEndPoint() ,buffer); + for (Filter filter: _filters) + filter.incoming(getEndPoint() ,buffer); if (orig>0) buffer.position(buffer.position()-orig); @@ -410,8 +445,8 @@ public class FilterConnection extends AbstractConnection } } - for (Listener listener: _listeners) - listener.outgoing(getEndPoint() ,_outBuffer); + for (Filter filter: _filters) + filter.outgoing(getEndPoint() ,_outBuffer); boolean flushed = getEndPoint().flush(_outBuffer); if (BufferUtil.isEmpty(_outBuffer)) @@ -461,6 +496,11 @@ public class FilterConnection extends AbstractConnection { return getEndPoint().isInputShutdown(); } + + public EndPoint getWrappedEndPoint() + { + return getEndPoint(); + } @Override public String toString() diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java index 900e19c6294..1030a020b5f 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java @@ -327,12 +327,7 @@ public class SslConnection extends AbstractConnection // TODO does this need idle timeouts super(null,getEndPoint().getLocalAddress(), getEndPoint().getRemoteAddress()); } - - public EndPoint getEncryptedEndPoint() - { - return getEndPoint(); - } - + @Override protected FillInterest getFillInterest() { diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/FilteredSelectChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/FilteredSelectChannelEndPointTest.java index de2fab13c3a..575cd88e91e 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/FilteredSelectChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/FilteredSelectChannelEndPointTest.java @@ -34,7 +34,7 @@ public class FilteredSelectChannelEndPointTest extends SelectChannelEndPointTest protected Connection newConnection(SocketChannel channel, EndPoint endpoint) { 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()); filter.getFilterEndPoint().setConnection(connection); return filter; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/FilterConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/FilterConnectionFactory.java new file mode 100644 index 00000000000..108d2d15d37 --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/FilterConnectionFactory.java @@ -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 _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); + } +} + + diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java index 9d47500e042..ec8b505cce2 100644 --- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java +++ b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java @@ -23,8 +23,12 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; +import javax.net.ssl.SSLEngine; + import org.eclipse.jetty.io.Connection; 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.npn.NextProtoNego; import org.eclipse.jetty.server.AbstractConnectionFactory; @@ -96,8 +100,20 @@ public class NPNServerConnectionFactory extends AbstractConnectionFactory String dft=_defaultProtocol; if (dft==null) dft=_protocols.get(0); + + 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((DecryptedEndPoint)endPoint, connector,protocols,_defaultProtocol),connector,endPoint); + return configure(new NextProtoNegoServerConnection(endPoint, engine, connector,protocols,_defaultProtocol),connector,endPoint); } @Override diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NextProtoNegoServerConnection.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NextProtoNegoServerConnection.java index 93b3bc15c3b..40731ad4443 100644 --- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NextProtoNegoServerConnection.java +++ b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NextProtoNegoServerConnection.java @@ -42,13 +42,13 @@ public class NextProtoNegoServerConnection extends AbstractConnection implements private final String defaultProtocol; private String nextProtocol; // No need to be volatile: it is modified and read by the same thread - public NextProtoNegoServerConnection(DecryptedEndPoint endPoint, Connector connector, Listprotocols, String defaultProtocol) + public NextProtoNegoServerConnection(EndPoint endPoint, SSLEngine engine, Connector connector, Listprotocols, String defaultProtocol) { super(endPoint, connector.getExecutor()); this.connector = connector; this.protocols = protocols; this.defaultProtocol = defaultProtocol; - engine = endPoint.getSslConnection().getSSLEngine(); + this.engine = engine; NextProtoNego.put(engine, this); }