diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java index 8a9b125432e..247a85a40c2 100644 --- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java +++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java @@ -22,12 +22,8 @@ import java.lang.management.ManagementFactory; import org.eclipse.jetty.deploy.DeploymentManager; 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; @@ -49,7 +45,6 @@ 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 { @@ -81,15 +76,13 @@ public class SpdyServer // 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); + ServerConnector httpConnector = new ServerConnector(server,http); httpConnector.setPort(8080); - httpConnector.setIdleTimeout(30000); - + httpConnector.setIdleTimeout(10000); server.addConnector(httpConnector); + // SSL configurations SslContextFactory sslContextFactory = new SslContextFactory(); sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore"); @@ -123,15 +116,10 @@ public class SpdyServer 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); + + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory,npn.getProtocol()); + + ServerConnector spdyConnector = new ServerConnector(server,ssl,npn,spdy3,spdy2,http); spdyConnector.setPort(8443); server.addConnector(spdyConnector); 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 0eb655dd91e..df3f3538457 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 @@ -222,7 +222,7 @@ public abstract class AbstractEndPoint implements EndPoint @Override public String toString() { - return String.format("%s@%x{%s%s,o=%b,is=%b,os=%b,fi=%s,wf=%s}{%s}", + return String.format("%s@%x{%s%s,o=%b,is=%b,os=%b,fi=%s,wf=%s,to=%d}{%s}", getClass().getSimpleName(), hashCode(), getRemoteAddress(), @@ -232,6 +232,7 @@ public abstract class AbstractEndPoint implements EndPoint isOutputShutdown(), _fillInterest, _writeFlusher, + _idleTimeout, getConnection()); } } 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 fa0928642d3..402f72488ed 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 @@ -372,6 +372,14 @@ public class FilterConnection extends AbstractConnection public FilteredEndPoint() { super(null,getEndPoint().getLocalAddress(), getEndPoint().getRemoteAddress()); + setIdleTimeout(getEndPoint().getIdleTimeout()); + } + + @Override + public void setIdleTimeout(long idleTimeout) + { + super.setIdleTimeout(idleTimeout); + getEndPoint().setIdleTimeout(idleTimeout); } @Override 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 03e99867c74..5e9c8ca8363 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 @@ -315,8 +315,8 @@ public class SslConnection extends AbstractConnection public DecryptedEndPoint() { - // TODO does this need idle timeouts super(null,getEndPoint().getLocalAddress(), getEndPoint().getRemoteAddress()); + setIdleTimeout(getEndPoint().getIdleTimeout()); } @Override diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java index a07374b29f1..a63579159d5 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java @@ -141,7 +141,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co private final ByteBufferPool _byteBufferPool; private final Thread[] _acceptors; private volatile CountDownLatch _stopping; - private long _idleTimeout = 200000; + private long _idleTimeout = 30000; private String _defaultProtocol; private ConnectionFactory _defaultConnectionFactory; diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java index eff5ca31590..7d887996c20 100644 --- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java +++ b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/http/HttpTransportOverSPDY.java @@ -21,6 +21,8 @@ package org.eclipse.jetty.spdy.server.http; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.http.HttpFields; @@ -28,6 +30,7 @@ import org.eclipse.jetty.http.HttpGenerator; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpChannelConfig; import org.eclipse.jetty.server.HttpTransport; @@ -115,15 +118,27 @@ public class HttpTransportOverSPDY implements HttpTransport sendToStream(content, lastContent); } - private void sendToStream(ByteBuffer content, boolean lastContent) + private void sendToStream(ByteBuffer content, boolean lastContent) throws IOException { + Future future = stream.data(new ByteBufferDataInfo(content, lastContent)); try { - stream.data(new ByteBufferDataInfo(content, lastContent)).get(); + if (endPoint.getIdleTimeout()>0) + future.get(endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS); + else + future.get(); + } + catch (ExecutionException e) + { + LOG.debug(e); + Throwable cause=e.getCause(); + if (cause instanceof IOException) + throw (IOException)cause; + throw new RuntimeIOException(cause); } catch (Exception e) { - endPoint.close(); + throw new RuntimeIOException(e); } } diff --git a/test-jetty-webapp/pom.xml b/test-jetty-webapp/pom.xml index 789da10a2df..df56c84db86 100644 --- a/test-jetty-webapp/pom.xml +++ b/test-jetty-webapp/pom.xml @@ -201,6 +201,12 @@ 2.1 provided + + org.eclipse.jetty.spdy + spdy-http-server + ${project.version} + test + javax.servlet jstl diff --git a/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java b/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java index 8ccc9bbdf18..906ba3315db 100644 --- a/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java +++ b/test-jetty-webapp/src/main/java/com/acme/ChatServlet.java @@ -43,7 +43,7 @@ public class ChatServlet extends HttpServlet { // inner class to hold message queue for each chat room member - class Member + class Member implements AsyncListener { final String _name; final AtomicReference _async=new AtomicReference<>(); @@ -54,6 +54,35 @@ public class ChatServlet extends HttpServlet _name=name; } + @Override + public void onTimeout(AsyncEvent event) throws IOException + { + AsyncContext async = _async.get(); + if (async!=null && _async.compareAndSet(async,null)) + { + HttpServletResponse response = (HttpServletResponse)async.getResponse(); + response.setContentType("text/json;charset=utf-8"); + PrintWriter out=response.getWriter(); + out.print("{action:\"poll\"}"); + async.complete(); + } + } + + @Override + public void onStartAsync(AsyncEvent event) throws IOException + { + event.getAsyncContext().addListener(this); + } + + @Override + public void onError(AsyncEvent event) throws IOException + { + } + + @Override + public void onComplete(AsyncEvent event) throws IOException + { + } } Map> _rooms = new HashMap>(); @@ -145,39 +174,10 @@ public class ChatServlet extends HttpServlet else { AsyncContext async = request.startAsync(); - async.setTimeout(20000); - async.addListener(new AsyncListener() - { - @Override - public void onTimeout(AsyncEvent event) throws IOException - { - - } - - @Override - public void onStartAsync(AsyncEvent event) throws IOException - { - AsyncContext async = member._async.get(); - if (member._async.compareAndSet(async,null)) - { - HttpServletResponse response = (HttpServletResponse)async.getResponse(); - response.setContentType("text/json;charset=utf-8"); - PrintWriter out=response.getWriter(); - out.print("{action:\"poll\"}"); - } - } - - @Override - public void onError(AsyncEvent event) throws IOException - { - } - - @Override - public void onComplete(AsyncEvent event) throws IOException - { - } - }); - member._async.compareAndSet(null,async); + async.setTimeout(10000); + async.addListener(member); + if (!member._async.compareAndSet(null,async)) + throw new IllegalStateException(); } } } diff --git a/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java b/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java index 313aba80e56..27531107a53 100644 --- a/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java +++ b/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java @@ -27,10 +27,13 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.security.HashLoginService; +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.Request; +import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.SslConnectionFactory; @@ -42,6 +45,11 @@ import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.server.session.HashSessionManager; +import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory; +import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory; +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.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.StdErrLog; @@ -74,32 +82,60 @@ public class TestServer MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); server.addBean(mbContainer); server.addBean(Log.getLog()); + - // Setup Connectors - ServerConnector connector0 = new ServerConnector(server); - connector0.setPort(8080); - connector0.setIdleTimeout(30000); - connector0.getConnectionFactory(HttpConnectionFactory.class).getHttpChannelConfig().setSecurePort(8443); - server.addConnector(connector0); - - // Setup Connectors - ServerConnector connector1 = new ServerConnector(server); - connector1.setPort(8081); - connector1.setIdleTimeout(30000); - connector1.getConnectionFactory(HttpConnectionFactory.class).getHttpChannelConfig().setSecurePort(8443); - server.addConnector(connector1); - - - ServerConnector ssl_connector = new ServerConnector(server,new SslContextFactory()); - ssl_connector.setPort(8443); - SslContextFactory cf = ssl_connector.getConnectionFactory(SslConnectionFactory.class).getSslContextFactory(); - cf.setKeyStorePath(jetty_root + "/jetty-server/src/main/config/etc/keystore"); - cf.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - cf.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); - cf.setTrustStorePath(jetty_root + "/jetty-server/src/main/config/etc/keystore"); - cf.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); - server.addConnector(ssl_connector); + // 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); + ServerConnector httpConnector = new ServerConnector(server,http); + httpConnector.setPort(8080); + httpConnector.setIdleTimeout(30000); + server.addConnector(httpConnector); + + // SSL configurations + SslContextFactory sslContextFactory = new SslContextFactory(); + sslContextFactory.setKeyStorePath(jetty_root + "/jetty-server/src/main/config/etc/keystore"); + sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); + sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); + sslContextFactory.setTrustStorePath(jetty_root + "/jetty-server/src/main/config/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 + SPDYServerConnectionFactory.checkNPNAvailable(); + 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); + SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory,npn.getProtocol()); + ServerConnector spdyConnector = new ServerConnector(server,ssl,npn,spdy3,spdy2,http); + spdyConnector.setPort(8443); + spdyConnector.setIdleTimeout(30000); + server.addConnector(spdyConnector); + + + + // Handlers HandlerCollection handlers = new HandlerCollection(); ContextHandlerCollection contexts = new ContextHandlerCollection(); RequestLogHandler requestLogHandler = new RequestLogHandler();