diff --git a/VERSION.txt b/VERSION.txt index 643741997a3..cad370f8ddf 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,5 +1,13 @@ jetty-9.4.0-SNAPSHOT +jetty-9.3.7.v20160115 - 15 January 2016 + + 471171 Support SYNC_FLUSH in GzipHandler + + 485469 permessage-deflate extension causes protocol error in Firefox/Chrome + + 485714 Update SSL configuration to mitigate SLOTH vulnerability + + 485884 WebAppContext defaults should be same for xml or war deployment + + 485969 WebSocket upgrade response should honor HttpConfiguration server + version settings + jetty-9.3.7.RC1 - 13 January 2016 + 481986 Dead JSR 356 Server Session still being tracked after Session/Connection closure diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_71.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_71.mod new file mode 100644 index 00000000000..3628757cbfd --- /dev/null +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_71.mod @@ -0,0 +1,8 @@ +[name] +protonego-boot + +[files] +http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar + +[exec] +-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_72.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_72.mod new file mode 100644 index 00000000000..3628757cbfd --- /dev/null +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_72.mod @@ -0,0 +1,8 @@ +[name] +protonego-boot + +[files] +http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar + +[exec] +-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java index 7b7303d3170..fdebfd668cd 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java @@ -244,6 +244,28 @@ public class WebAppProvider extends ScanningAppProvider return _tempDirectory; } + /* ------------------------------------------------------------ */ + protected void initializeWebAppContextDefaults(WebAppContext webapp) + { + if (_defaultsDescriptor != null) + webapp.setDefaultsDescriptor(_defaultsDescriptor); + webapp.setExtractWAR(_extractWars); + webapp.setParentLoaderPriority(_parentLoaderPriority); + if (_configurationClasses != null) + webapp.setConfigurationClasses(_configurationClasses); + + if (_tempDirectory != null) + { + /* Since the Temp Dir is really a context base temp directory, + * Lets set the Temp Directory in a way similar to how WebInfConfiguration does it, + * instead of setting the WebAppContext.setTempDirectory(File). + * If we used .setTempDirectory(File) all webapps will wind up in the + * same temp / work directory, overwriting each others work. + */ + webapp.setAttribute(WebAppContext.BASETEMPDIR, _tempDirectory); + } + } + /* ------------------------------------------------------------ */ @Override public ContextHandler createContextHandler(final App app) throws Exception @@ -267,9 +289,7 @@ public class WebAppProvider extends ScanningAppProvider if (context instanceof WebAppContext) { WebAppContext webapp = (WebAppContext)context; - webapp.setParentLoaderPriority(_parentLoaderPriority); - if (_defaultsDescriptor != null) - webapp.setDefaultsDescriptor(_defaultsDescriptor); + initializeWebAppContextDefaults(webapp); } } }; @@ -327,31 +347,10 @@ public class WebAppProvider extends ScanningAppProvider context = "/" + context; } - webAppContext.setContextPath(context); webAppContext.setWar(file.getAbsolutePath()); - if (_defaultsDescriptor != null) - { - webAppContext.setDefaultsDescriptor(_defaultsDescriptor); - } - webAppContext.setExtractWAR(_extractWars); - webAppContext.setParentLoaderPriority(_parentLoaderPriority); - if (_configurationClasses != null) - { - webAppContext.setConfigurationClasses(_configurationClasses); - } + initializeWebAppContextDefaults(webAppContext); - if (_tempDirectory != null) - { - /* Since the Temp Dir is really a context base temp directory, - * Lets set the Temp Directory in a way similar to how WebInfConfiguration does it, - * instead of setting the - * WebAppContext.setTempDirectory(File). - * If we used .setTempDirectory(File) all webapps will wind up in the - * same temp / work directory, overwriting each others work. - */ - webAppContext.setAttribute(WebAppContext.BASETEMPDIR, _tempDirectory); - } return webAppContext; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java index 6f9666e302e..ec1d4774534 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java @@ -68,6 +68,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory private int _minGzipSize=DEFAULT_MIN_GZIP_SIZE; private int _compressionLevel=Deflater.DEFAULT_COMPRESSION; private boolean _checkGzExists = true; + private boolean _syncFlush = false; // non-static, as other GzipHandler instances may have different configurations private final ThreadLocal _deflater = new ThreadLocal(); @@ -193,6 +194,27 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory _methods.include(m); } + /* ------------------------------------------------------------ */ + /** + * @return True if {@link Deflater#SYNC_FLUSH} is used, else {@link Deflater#NO_FLUSH} + */ + public boolean isSyncFlush() + { + return _syncFlush; + } + + /* ------------------------------------------------------------ */ + /** + *

Set the {@link Deflater} flush mode to use. {@link Deflater#SYNC_FLUSH} + * should be used if the application wishes to stream the data, but this may + * hurt compression performance. + * @param syncFlush True if {@link Deflater#SYNC_FLUSH} is used, else {@link Deflater#NO_FLUSH} + */ + public void setSyncFlush(boolean syncFlush) + { + _syncFlush = syncFlush; + } + /* ------------------------------------------------------------ */ /** * Add included mime types. Inclusion takes precedence over @@ -465,7 +487,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } // install interceptor and handle - out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,baseRequest.getHttpChannel(),out.getInterceptor())); + out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,baseRequest.getHttpChannel(),out.getInterceptor(),_syncFlush)); if (_handler!=null) _handler.handle(target,baseRequest, request, response); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java index c7fc799ccee..f717c2656af 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHttpOutputInterceptor.java @@ -56,27 +56,29 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor private final HttpChannel _channel; private final HttpField _vary; private final int _bufferSize; + private final boolean _syncFlush; private Deflater _deflater; private ByteBuffer _buffer; - public GzipHttpOutputInterceptor(GzipFactory factory, HttpChannel channel, HttpOutput.Interceptor next) + public GzipHttpOutputInterceptor(GzipFactory factory, HttpChannel channel, HttpOutput.Interceptor next,boolean syncFlush) { - this(factory,VARY_ACCEPT_ENCODING_USER_AGENT,channel.getHttpConfiguration().getOutputBufferSize(),channel,next); + this(factory,VARY_ACCEPT_ENCODING_USER_AGENT,channel.getHttpConfiguration().getOutputBufferSize(),channel,next,syncFlush); } - public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, HttpChannel channel, HttpOutput.Interceptor next) + public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, HttpChannel channel, HttpOutput.Interceptor next,boolean syncFlush) { - this(factory,vary,channel.getHttpConfiguration().getOutputBufferSize(),channel,next); + this(factory,vary,channel.getHttpConfiguration().getOutputBufferSize(),channel,next,syncFlush); } - public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, int bufferSize, HttpChannel channel, HttpOutput.Interceptor next) + public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, int bufferSize, HttpChannel channel, HttpOutput.Interceptor next,boolean syncFlush) { _factory=factory; _channel=channel; _interceptor=next; _vary=vary; _bufferSize=bufferSize; + _syncFlush=syncFlush; } public HttpOutput.Interceptor getNextInterceptor() @@ -353,7 +355,7 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor int len=_buffer.capacity()-_buffer.limit() - (_last?8:0); if (len>0) { - int produced=_deflater.deflate(_buffer.array(),off,len,Deflater.NO_FLUSH); + int produced=_deflater.deflate(_buffer.array(),off,len,_syncFlush?Deflater.SYNC_FLUSH:Deflater.NO_FLUSH); _buffer.limit(_buffer.limit()+produced); } boolean finished=_deflater.finished(); diff --git a/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_71.mod b/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_71.mod new file mode 100644 index 00000000000..3628757cbfd --- /dev/null +++ b/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_71.mod @@ -0,0 +1,8 @@ +[name] +protonego-boot + +[files] +http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar + +[exec] +-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_72.mod b/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_72.mod new file mode 100644 index 00000000000..3628757cbfd --- /dev/null +++ b/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_72.mod @@ -0,0 +1,8 @@ +[name] +protonego-boot + +[files] +http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar + +[exec] +-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/browser/JsrBrowserDebugTool.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/browser/JsrBrowserDebugTool.java index 691a41a7572..ce8d230bbb6 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/browser/JsrBrowserDebugTool.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/browser/JsrBrowserDebugTool.java @@ -21,6 +21,8 @@ package org.eclipse.jetty.websocket.jsr356.server.browser; import javax.servlet.ServletException; import javax.websocket.DeploymentException; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.DefaultServlet; @@ -79,7 +81,11 @@ public class JsrBrowserDebugTool private void setupServer(int port) throws DeploymentException, ServletException { server = new Server(); - ServerConnector connector = new ServerConnector(server); + + HttpConfiguration httpConf = new HttpConfiguration(); + httpConf.setSendServerVersion(true); + + ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConf)); connector.setPort(port); server.addConnector(connector); diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java index 6fc9b538fcf..ac32ad6d729 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java @@ -407,12 +407,13 @@ public abstract class CompressExtension extends AbstractExtension { Frame frame = entry.frame; BatchMode batchMode = entry.batchMode; - if (OpCode.isControlFrame(frame.getOpCode()) || !frame.hasPayload()) + if (OpCode.isControlFrame(frame.getOpCode())) { + // Do not deflate control frames nextOutgoingFrame(frame,this,batchMode); return; } - + compress(entry,true); } @@ -434,7 +435,7 @@ public abstract class CompressExtension extends AbstractExtension // no input supplied needsCompress = false; } - + ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] output = new byte[outputLength]; @@ -486,7 +487,8 @@ public abstract class CompressExtension extends AbstractExtension } else if (fin) { - // Special case: 8.2.3.6. Generating an Empty Fragment Manually + // Special case: 7.2.3.6. Generating an Empty Fragment Manually + // https://tools.ietf.org/html/rfc7692#section-7.2.3.6 payload = ByteBuffer.wrap(new byte[] { 0x00 }); } diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/PerMessageDeflateExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/PerMessageDeflateExtension.java index c307e5356bc..93ea4fbcbfb 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/PerMessageDeflateExtension.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/PerMessageDeflateExtension.java @@ -33,7 +33,7 @@ import org.eclipse.jetty.websocket.common.OpCode; /** * Per Message Deflate Compression extension for WebSocket. *

- * Attempts to follow draft-ietf-hybi-permessage-compression-12 + * Attempts to follow Compression Extensions for WebSocket */ public class PerMessageDeflateExtension extends CompressExtension { diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java index e30b4cac5de..c55f7a0a018 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java @@ -36,11 +36,15 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnection; +import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.util.DecoratedObjectFactory; @@ -618,6 +622,9 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc if (LOG.isDebugEnabled()) LOG.debug("Handshake Response: {}", handshaker); + if (getSendServerVersion(connector)) + response.setHeader("Server",HttpConfiguration.SERVER_VERSION); + // Process (version specific) handshake response handshaker.doHandshakeResponse(request, response); @@ -626,4 +633,19 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc return true; } + + private boolean getSendServerVersion(Connector connector) + { + ConnectionFactory connFactory = connector.getConnectionFactory(HttpVersion.HTTP_1_1.asString()); + if (connFactory == null) + return false; + + if (connFactory instanceof HttpConnectionFactory) + { + HttpConfiguration httpConf = ((HttpConnectionFactory)connFactory).getHttpConfiguration(); + if (httpConf != null) + return httpConf.getSendServerVersion(); + } + return false; + } } diff --git a/pom.xml b/pom.xml index 9457f6fb87f..7a45f56fa72 100644 --- a/pom.xml +++ b/pom.xml @@ -1001,5 +1001,29 @@ 8.1.6.v20151105 + + 8u71 + + + java.version + 1.8.0_71 + + + + 8.1.7.v20160121 + + + + 8u72 + + + java.version + 1.8.0_72 + + + + 8.1.7.v20160121 + + diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index 3d65131d19d..6b051ee0eb4 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -1,3 +1,4 @@ + org.eclipse.jetty.tests