From 91a94f8213c61c7ea09a7e7681d703fc655496ec Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Mon, 21 Jan 2013 16:43:57 +1100 Subject: [PATCH 1/6] 362226 HttpConnection "wait" call causes thread resource exhaustion --- .../jetty/client/BlockingHttpConnection.java | 52 +++++++++++- .../eclipse/jetty/client/IdleTimeoutTest.java | 80 +++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java index 50a0c0b8449..b3ab2a046e0 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/BlockingHttpConnection.java @@ -40,6 +40,7 @@ public class BlockingHttpConnection extends AbstractHttpConnection private boolean _requestComplete; private Buffer _requestContentChunk; + private boolean _expired=false; BlockingHttpConnection(Buffers requestBuffers, Buffers responseBuffers, EndPoint endPoint) { @@ -49,8 +50,52 @@ public class BlockingHttpConnection extends AbstractHttpConnection protected void reset() throws IOException { _requestComplete = false; + _expired = false; super.reset(); } + + + @Override + protected void exchangeExpired(HttpExchange exchange) + { + synchronized (this) + { + super.exchangeExpired(exchange); + _expired = true; + this.notifyAll(); + } + } + + + + @Override + public void onIdleExpired(long idleForMs) + { + try + { + LOG.debug("onIdleExpired {}ms {} {}",idleForMs,this,_endp); + _expired = true; + _endp.close(); + } + catch(IOException e) + { + LOG.ignore(e); + + try + { + _endp.close(); + } + catch(IOException e2) + { + LOG.ignore(e2); + } + } + + synchronized(this) + { + this.notifyAll(); + } + } @Override public Connection handle() throws IOException @@ -71,13 +116,18 @@ public class BlockingHttpConnection extends AbstractHttpConnection synchronized (this) { exchange=_exchange; - while (exchange == null) { try { this.wait(); exchange=_exchange; + if (_expired) + { + failed = true; + throw new InterruptedException(); + } + } catch (InterruptedException e) { diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java new file mode 100644 index 00000000000..d05e46f13e6 --- /dev/null +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java @@ -0,0 +1,80 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 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.client; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * IdleTimeoutTest + * + * Warning - this is a slow test. Uncomment the ignore to run it. + * + */ +public class IdleTimeoutTest +{ + public int _repetitions = 30; + + @Ignore + //@Test + public void testIdleTimeoutOnBlockingConnector() throws Exception + { + final HttpClient client = new HttpClient(); + client.setMaxConnectionsPerAddress(4); + client.setConnectorType(HttpClient.CONNECTOR_SOCKET); + client.setTimeout(TimeUnit.DAYS.toMillis(1)); // very long timeout on data + client.setIdleTimeout(500); // very short idle timeout + client.start(); + + final CountDownLatch counter = new CountDownLatch(_repetitions); + + Thread runner = new Thread() + { + public void run() + { + try + { + for (int i=0; i<_repetitions; i++) + { + ContentExchange exchange = new ContentExchange(); + exchange.setURL("http://www.google.com/?i="+i); + client.send(exchange); + exchange.waitForDone(); + counter.countDown(); + System.err.println(counter.getCount()); + Thread.sleep(1000); //wait long enough for idle timeout to expire + } + } + catch (Exception e) + { + Assert.fail(e.getMessage()); + } + } + }; + + runner.start(); + if (!counter.await(80, TimeUnit.SECONDS)) + Assert.fail("Test did not complete in time"); + + } +} From 92af54c3fcf250625c985618bc3c3b57555c88a9 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Tue, 22 Jan 2013 08:58:35 +1100 Subject: [PATCH 2/6] Make IdleTimeoutTest jdk1.5 compliant --- .../src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java index d05e46f13e6..930a378d284 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java @@ -42,7 +42,7 @@ public class IdleTimeoutTest final HttpClient client = new HttpClient(); client.setMaxConnectionsPerAddress(4); client.setConnectorType(HttpClient.CONNECTOR_SOCKET); - client.setTimeout(TimeUnit.DAYS.toMillis(1)); // very long timeout on data + client.setTimeout(TimeUnit.SECONDS.toMillis(86400)); // very long timeout on data client.setIdleTimeout(500); // very short idle timeout client.start(); From a7aab0b6c60d80a01c8922381c153c118be4da80 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 23 Jan 2013 13:56:05 -0700 Subject: [PATCH 3/6] Bumping up jetty-version-maven-plugin to 1.0.9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ff63325000b..a9df1ef1234 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ org.eclipse.jetty.toolchain jetty-version-maven-plugin - 1.0.7 + 1.0.9 org.apache.maven.plugins From 161a14d9d0b3d4d4f8f744f2171c834ed47399ad Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 24 Jan 2013 14:07:25 +1100 Subject: [PATCH 4/6] 381521 Only set Vary header when content could be compressed --- .../http/gzip/AbstractCompressedStream.java | 54 +++++--- .../http/gzip/CompressedResponseWrapper.java | 4 +- .../jetty/server/handler/GzipHandler.java | 28 +++- .../eclipse/jetty/servlets/GzipFilter.java | 127 ++++++++++-------- .../jetty/servlets/IncludableGzipFilter.java | 33 ++++- .../jetty/servlets/gzip/GzipTester.java | 3 +- 6 files changed, 165 insertions(+), 84 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java index 8787d5efc92..8317914d9ce 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/AbstractCompressedStream.java @@ -40,6 +40,7 @@ import org.eclipse.jetty.util.ByteArrayOutputStream2; public abstract class AbstractCompressedStream extends ServletOutputStream { private final String _encoding; + protected final String _vary; protected final CompressedResponseWrapper _wrapper; protected final HttpServletResponse _response; protected OutputStream _out; @@ -52,12 +53,13 @@ public abstract class AbstractCompressedStream extends ServletOutputStream * Instantiates a new compressed stream. * */ - public AbstractCompressedStream(String encoding,HttpServletRequest request, CompressedResponseWrapper wrapper) + public AbstractCompressedStream(String encoding,HttpServletRequest request, CompressedResponseWrapper wrapper,String vary) throws IOException { _encoding=encoding; _wrapper = wrapper; _response = (HttpServletResponse)wrapper.getResponse(); + _vary=vary; if (_wrapper.getMinCompressSize()==0) doCompress(); @@ -106,7 +108,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream { long length=_wrapper.getContentLength(); if (length > 0 && length < _wrapper.getMinCompressSize()) - doNotCompress(); + doNotCompress(false); else doCompress(); } @@ -137,13 +139,14 @@ public abstract class AbstractCompressedStream extends ServletOutputStream _wrapper.setContentLength(length); } if (length < _wrapper.getMinCompressSize()) - doNotCompress(); + doNotCompress(false); else doCompress(); } else if (_out == null) { - doNotCompress(); + // No output + doNotCompress(false); } if (_compressedOutputStream != null) @@ -168,7 +171,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream { long length=_wrapper.getContentLength(); if (length > 0 && length < _wrapper.getMinCompressSize()) - doNotCompress(); + doNotCompress(false); else doCompress(); } @@ -226,23 +229,30 @@ public abstract class AbstractCompressedStream extends ServletOutputStream if (_response.isCommitted()) throw new IllegalStateException(); - setHeader("Content-Encoding", _encoding); - if (_response.containsHeader("Content-Encoding")) + if (_encoding!=null) { - _out=_compressedOutputStream=createStream(); - - if (_bOut!=null) + setHeader("Content-Encoding", _encoding); + if (_response.containsHeader("Content-Encoding")) { - _out.write(_bOut.getBuf(),0,_bOut.getCount()); - _bOut=null; + setHeader("Vary",_vary); + _out=_compressedOutputStream=createStream(); + if (_out!=null) + { + if (_bOut!=null) + { + _out.write(_bOut.getBuf(),0,_bOut.getCount()); + _bOut=null; + } + + String etag=_wrapper.getETag(); + if (etag!=null) + setHeader("ETag",etag.substring(0,etag.length()-1)+'-'+_encoding+'"'); + return; + } } - - String etag=_wrapper.getETag(); - if (etag!=null) - setHeader("ETag",etag.substring(0,etag.length()-1)+'-'+_encoding+'"'); } - else - doNotCompress(); + + doNotCompress(true); // Send vary as it could have been compressed if encoding was present } } @@ -252,12 +262,14 @@ public abstract class AbstractCompressedStream extends ServletOutputStream * @throws IOException * Signals that an I/O exception has occurred. */ - public void doNotCompress() throws IOException + public void doNotCompress(boolean sendVary) throws IOException { if (_compressedOutputStream != null) throw new IllegalStateException("Compressed output stream is already assigned."); if (_out == null || _bOut != null) { + if (sendVary) + setHeader("Vary",_vary); if (_wrapper.getETag()!=null) setHeader("ETag",_wrapper.getETag()); @@ -289,7 +301,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream { long length=_wrapper.getContentLength(); if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize())) - doNotCompress(); + doNotCompress(false); else if (lengthToWrite > _wrapper.getMinCompressSize()) doCompress(); else @@ -299,7 +311,7 @@ public abstract class AbstractCompressedStream extends ServletOutputStream { long length=_wrapper.getContentLength(); if (_response.isCommitted() || (length >= 0 && length < _wrapper.getMinCompressSize())) - doNotCompress(); + doNotCompress(false); else if (lengthToWrite >= (_bOut.getBuf().length - _bOut.getCount())) doCompress(); } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java index 5be638eab47..0ddf8199871 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/gzip/CompressedResponseWrapper.java @@ -138,8 +138,6 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp (_mimeTypes==null && ct!=null && ct.contains("gzip") || _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct))))) { - // Remove the vary header, because of content type. - setHeader("Vary",null); noCompression(); } } @@ -318,7 +316,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp { try { - _compressedStream.doNotCompress(); + _compressedStream.doNotCompress(false); } catch (IOException e) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java index 51d82db7e4d..68075f49e57 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GzipHandler.java @@ -68,6 +68,7 @@ public class GzipHandler extends HandlerWrapper protected Set _excluded; protected int _bufferSize = 8192; protected int _minGzipSize = 256; + protected String _vary = "Accept-Encoding, User-Agent"; /* ------------------------------------------------------------ */ /** @@ -161,6 +162,31 @@ public class GzipHandler extends HandlerWrapper } } + /* ------------------------------------------------------------ */ + /** + * @return The value of the Vary header set if a response can be compressed. + */ + public String getVary() + { + return _vary; + } + + /* ------------------------------------------------------------ */ + /** + * Set the value of the Vary header sent with responses that could be compressed. + *

+ * By default it is set to 'Accept-Encoding, User-Agent' since IE6 is excluded by + * default from the excludedAgents. If user-agents are not to be excluded, then + * this can be set to 'Accept-Encoding'. Note also that shared caches may cache + * many copies of a resource that is varied by User-Agent - one per variation of the + * User-Agent, unless the cache does some normalization of the UA string. + * @param vary The value of the Vary header set if a response can be compressed. + */ + public void setVary(String vary) + { + _vary = vary; + } + /* ------------------------------------------------------------ */ /** * Get the buffer size. @@ -297,7 +323,7 @@ public class GzipHandler extends HandlerWrapper @Override protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException { - return new AbstractCompressedStream("gzip",request,this) + return new AbstractCompressedStream("gzip",request,this,_vary) { @Override protected DeflaterOutputStream createStream() throws IOException diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 36ecb1fd352..e49e9f1ee22 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -104,15 +104,21 @@ import org.eclipse.jetty.util.log.Logger; * instead. * * excludePathPatterns Same as excludePath, but accepts regex patterns for more complex matching. + * + * vary Set to the value of the Vary header sent with responses that could be compressed. By default it is + * set to 'Vary: Accept-Encoding, User-Agent' since IE6 is excluded by default from the excludedAgents. + * If user-agents are not to be excluded, then this can be set to 'Vary: Accept-Encoding'. Note also + * that shared caches may cache copies of a resource that is varied by User-Agent - one per variation of + * the User-Agent, unless the cache does some normalization of the UA string. * */ public class GzipFilter extends UserAgentFilter { private static final Logger LOG = Log.getLogger(GzipFilter.class); public final static String GZIP="gzip"; - public final static String ETAG_GZIP="-gzip\""; + public final static String ETAG_GZIP="--gzip\""; public final static String DEFLATE="deflate"; - public final static String ETAG_DEFLATE="-deflate\""; + public final static String ETAG_DEFLATE="--deflate\""; public final static String ETAG="o.e.j.s.GzipFilter.ETag"; protected ServletContext _context; @@ -125,6 +131,7 @@ public class GzipFilter extends UserAgentFilter protected Set _excludedAgentPatterns; protected Set _excludedPaths; protected Set _excludedPathPatterns; + protected String _vary="Accept-Encoding, User-Agent"; private static final int STATE_SEPARATOR = 0; private static final int STATE_Q = 1; @@ -202,6 +209,10 @@ public class GzipFilter extends UserAgentFilter while (tok.hasMoreTokens()) _excludedPathPatterns.add(Pattern.compile(tok.nextToken())); } + + tmp=filterConfig.getInitParameter("vary"); + if (tmp!=null) + _vary=tmp; } /* ------------------------------------------------------------ */ @@ -224,9 +235,9 @@ public class GzipFilter extends UserAgentFilter HttpServletRequest request=(HttpServletRequest)req; HttpServletResponse response=(HttpServletResponse)res; - // Exclude URIs - no Vary because no matter what client, this URI is always excluded + // If not a GET or an Excluded URI - no Vary because no matter what client, this URI is always excluded String requestURI = request.getRequestURI(); - if (isExcludedPath(requestURI)) + if (!HttpMethods.GET.equalsIgnoreCase(request.getMethod()) || isExcludedPath(requestURI)) { super.doFilter(request,response,chain); return; @@ -244,54 +255,45 @@ public class GzipFilter extends UserAgentFilter return; } } - - // Inform caches that responses may vary according to Accept-Encoding (this may be nulled later) - response.setHeader("Vary","Accept-Encoding"); - // Exclude User-Agents + // Excluded User-Agents String ua = getUserAgent(request); - String compressionType = selectCompression(request.getHeader("accept-encoding")); + boolean ua_excluded=ua!=null&&isExcludedAgent(ua); - // If this request is not excluded by agent and if it can be compressed - if (!isExcludedAgent(ua) && compressionType!=null && !response.containsHeader("Content-Encoding") && !HttpMethods.HEAD.equalsIgnoreCase(request.getMethod())) + // Acceptable compression type + String compressionType = ua_excluded?null:selectCompression(request.getHeader("accept-encoding")); + + // Special handling for etags + String etag = request.getHeader("If-None-Match"); + if (etag!=null) { - // Special handling for etags - String etag = request.getHeader("If-None-Match"); - if (etag!=null) - { - if (etag.endsWith(ETAG_GZIP)) - request.setAttribute(ETAG,etag.substring(0,etag.length()-ETAG_GZIP.length())+'"'); - else if (etag.endsWith(ETAG_DEFLATE)) - request.setAttribute(ETAG,etag.substring(0,etag.length()-ETAG_DEFLATE.length())+'"'); - } - - CompressedResponseWrapper wrappedResponse = createWrappedResponse(request,response,compressionType); - - boolean exceptional=true; - try - { - super.doFilter(request,wrappedResponse,chain); - exceptional=false; - } - finally - { - Continuation continuation = ContinuationSupport.getContinuation(request); - if (continuation.isSuspended() && continuation.isResponseWrapped()) - { - continuation.addContinuationListener(new ContinuationListenerWaitingForWrappedResponseToFinish(wrappedResponse)); - } - else if (exceptional && !response.isCommitted()) - { - wrappedResponse.resetBuffer(); - wrappedResponse.noCompression(); - } - else - wrappedResponse.finish(); - } + int dd=etag.indexOf("--"); + if (dd>0) + request.setAttribute(ETAG,etag.substring(0,dd)+(etag.endsWith("\"")?"\"":"")); } - else + + CompressedResponseWrapper wrappedResponse = createWrappedResponse(request,response,compressionType); + + boolean exceptional=true; + try { - super.doFilter(request,new VaryResponseWrapper(response),chain); + super.doFilter(request,wrappedResponse,chain); + exceptional=false; + } + finally + { + Continuation continuation = ContinuationSupport.getContinuation(request); + if (continuation.isSuspended() && continuation.isResponseWrapped()) + { + continuation.addContinuationListener(new ContinuationListenerWaitingForWrappedResponseToFinish(wrappedResponse)); + } + else if (exceptional && !response.isCommitted()) + { + wrappedResponse.resetBuffer(); + wrappedResponse.noCompression(); + } + else + wrappedResponse.finish(); } } @@ -387,14 +389,32 @@ public class GzipFilter extends UserAgentFilter protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType) { CompressedResponseWrapper wrappedResponse = null; - if (compressionType.equals(GZIP)) + if (compressionType==null) { wrappedResponse = new CompressedResponseWrapper(request,response) { @Override protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException { - return new AbstractCompressedStream(compressionType,request,this) + return new AbstractCompressedStream(null,request,this,_vary) + { + @Override + protected DeflaterOutputStream createStream() throws IOException + { + return null; + } + }; + } + }; + } + else if (compressionType.equals(GZIP)) + { + wrappedResponse = new CompressedResponseWrapper(request,response) + { + @Override + protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException + { + return new AbstractCompressedStream(compressionType,request,this,_vary) { @Override protected DeflaterOutputStream createStream() throws IOException @@ -412,7 +432,7 @@ public class GzipFilter extends UserAgentFilter @Override protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException { - return new AbstractCompressedStream(compressionType,request,this) + return new AbstractCompressedStream(compressionType,request,this,_vary) { @Override protected DeflaterOutputStream createStream() throws IOException @@ -422,7 +442,7 @@ public class GzipFilter extends UserAgentFilter }; } }; - } + } else { throw new IllegalStateException(compressionType + " not supported"); @@ -572,11 +592,8 @@ public class GzipFilter extends UserAgentFilter ct=ct.substring(0,colon); } - if (_mimeTypes!=null && !_mimeTypes.contains(StringUtil.asciiToLowerCase(ct))) - // Remove the vary header, because of content type. - super.setHeader("Vary",null); - else - super.setHeader("Vary","Accept-Encoding"); + if (_mimeTypes!=null && _mimeTypes.contains(StringUtil.asciiToLowerCase(ct))) + super.setHeader("Vary",_vary); } } diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java index 8ff4608a707..5ba2be0022f 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/IncludableGzipFilter.java @@ -70,14 +70,41 @@ public class IncludableGzipFilter extends GzipFilter protected CompressedResponseWrapper createWrappedResponse(HttpServletRequest request, HttpServletResponse response, final String compressionType) { CompressedResponseWrapper wrappedResponse = null; - if (compressionType.equals(GZIP)) + if (compressionType==null) { wrappedResponse = new IncludableResponseWrapper(request,response) { @Override protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException { - return new AbstractCompressedStream(compressionType,request,this) + return new AbstractCompressedStream(null,request,this,_vary) + { + @Override + protected DeflaterOutputStream createStream() throws IOException + { + return null; + } + + @Override + protected void setHeader(String name, String value) + { + super.setHeader(name, value); + HttpServletResponse response = (HttpServletResponse)getResponse(); + if (!response.containsHeader(name)) + response.setHeader("org.eclipse.jetty.server.include." + name, value); + } + }; + } + }; + } + else if (compressionType.equals(GZIP)) + { + wrappedResponse = new IncludableResponseWrapper(request,response) + { + @Override + protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException + { + return new AbstractCompressedStream(compressionType,request,this,_vary) { @Override protected DeflaterOutputStream createStream() throws IOException @@ -104,7 +131,7 @@ public class IncludableGzipFilter extends GzipFilter @Override protected AbstractCompressedStream newCompressedStream(HttpServletRequest request,HttpServletResponse response) throws IOException { - return new AbstractCompressedStream(compressionType,request,this) + return new AbstractCompressedStream(compressionType,request,this,_vary) { @Override protected DeflaterOutputStream createStream() throws IOException diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java index 7146a34e677..7cac0d3afd8 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java @@ -306,13 +306,13 @@ public class GzipTester { Assert.assertThat("Response.method",response.getMethod(),nullValue()); Assert.assertThat("Response.status",response.getStatus(),is(status)); + Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString(compressionType))); if (expectedFilesize != (-1)) { Assert.assertThat("Response.header[Content-Length]",response.getHeader("Content-Length"),notNullValue()); int serverLength = Integer.parseInt(response.getHeader("Content-Length")); Assert.assertThat("Response.header[Content-Length]",serverLength,is(expectedFilesize)); } - Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString(compressionType))); } private HttpTester executeRequest(String uri) throws IOException, Exception @@ -465,6 +465,7 @@ public class GzipTester ServletHolder servletHolder = servletTester.addServlet(servletClass,"/"); servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath()); FilterHolder holder = servletTester.addFilter(gzipFilterClass,"/*",0); + holder.setInitParameter("vary","Accept-Encoding"); return holder; } From c9d026703f85df4f23c21e4bae753dc2a4151dee Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 25 Jan 2013 09:42:51 +1100 Subject: [PATCH 5/6] removed System.outs --- .../java/org/eclipse/jetty/server/ShutdownMonitor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java index 9965e6de013..3edf45b3760 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java @@ -255,7 +255,7 @@ public class ShutdownMonitor extends Thread { if (isAlive()) { - System.out.printf("ShutdownMonitor already started"); + System.err.printf("ShutdownMonitor already started"); return; // cannot start it again } startListenSocket(); @@ -270,8 +270,9 @@ public class ShutdownMonitor extends Thread private void startListenSocket() { if (this.port < 0) - { - System.out.println("ShutdownMonitor not in use (port < 0): " + port); + { + if (DEBUG) + System.err.println("ShutdownMonitor not in use (port < 0): " + port); return; } From 7fd04a186f5b4a6b900b9266f215d9994b00d954 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 25 Jan 2013 11:47:47 +1100 Subject: [PATCH 6/6] cleanup after merge --- .../test/java/org/eclipse/jetty/client/IdleTimeoutTest.java | 5 ++++- .../java/org/eclipse/jetty/servlets/gzip/GzipTester.java | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java index 930a378d284..e1c5225c46d 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/IdleTimeoutTest.java @@ -36,9 +36,10 @@ public class IdleTimeoutTest public int _repetitions = 30; @Ignore - //@Test + @Test public void testIdleTimeoutOnBlockingConnector() throws Exception { + /* TODO port to new client final HttpClient client = new HttpClient(); client.setMaxConnectionsPerAddress(4); client.setConnectorType(HttpClient.CONNECTOR_SOCKET); @@ -75,6 +76,8 @@ public class IdleTimeoutTest runner.start(); if (!counter.await(80, TimeUnit.SECONDS)) Assert.fail("Test did not complete in time"); + + */ } } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java index 1013462a2cc..a40a8372e2e 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/gzip/GzipTester.java @@ -298,7 +298,7 @@ public class GzipTester private void assertResponseHeaders(int expectedFilesize, int status, HttpTester.Response response) { Assert.assertThat("Response.status",response.getStatus(),is(status)); - Assert.assertThat("Response.header[Content-Encoding]",response.getHeader("Content-Encoding"),not(containsString(compressionType))); + Assert.assertThat("Response.header[Content-Encoding]",response.get("Content-Encoding"),not(containsString(compressionType))); if (expectedFilesize != (-1)) { Assert.assertEquals(expectedFilesize,response.getContentBytes().length); diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index eb2b19f1459..d7408ff771c 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -201,6 +201,12 @@ websocket-servlet ${project.version} + + org.eclipse.jetty.websocket + websocket-server + ${project.version} + test + org.eclipse.jetty jetty-webapp