diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java index 36d38a7dea9..427ea48398b 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java @@ -295,7 +295,6 @@ public class HttpFields /* -------------------------------------------------------------- */ private final ArrayList _fields = new ArrayList(20); private final HashMap _names = new HashMap(32); - private final int _maxCookieVersion; /* ------------------------------------------------------------ */ /** @@ -303,19 +302,8 @@ public class HttpFields */ public HttpFields() { - _maxCookieVersion=1; } - /* ------------------------------------------------------------ */ - /** - * Constructor. - */ - public HttpFields(int maxCookieVersion) - { - _maxCookieVersion=maxCookieVersion; - } - - // TODO externalize this cache so it can be configurable private static ConcurrentMap __cache = new ConcurrentHashMap(); private static int __cacheSize = Integer.getInteger("org.eclipse.jetty.http.HttpFields.CACHE",2000); @@ -971,7 +959,7 @@ public class HttpFields final boolean isHttpOnly, int version) { - String delim=_maxCookieVersion==0?"":__COOKIE_DELIM; + String delim=__COOKIE_DELIM; // Check arguments if (name == null || name.length() == 0) @@ -980,29 +968,18 @@ public class HttpFields // Format value and params StringBuilder buf = new StringBuilder(128); String name_value_params; - boolean quoted = QuotedStringTokenizer.quoteIfNeeded(buf, name, delim); + QuotedStringTokenizer.quoteIfNeeded(buf, name, delim); buf.append('='); String start=buf.toString(); if (value != null && value.length() > 0) - quoted|=QuotedStringTokenizer.quoteIfNeeded(buf, value, delim); - - // upgrade to version 1 cookies if quoted. - if (quoted&&version==0 && _maxCookieVersion>=1) - version=1; + QuotedStringTokenizer.quoteIfNeeded(buf, value, delim); - if (version>_maxCookieVersion) - version=_maxCookieVersion; - - if (version > 0) + if (comment != null && comment.length() > 0) { - buf.append(";Version="); - buf.append(version); - if (comment != null && comment.length() > 0) - { - buf.append(";Comment="); - QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim); - } + buf.append(";Comment="); + QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim); } + if (path != null && path.length() > 0) { buf.append(";Path="); @@ -1019,23 +996,19 @@ public class HttpFields if (maxAge >= 0) { - // Always add the expires param as some browsers still don't handle max-age - buf.append(";Expires="); - if (maxAge == 0) - buf.append(__01Jan1970_COOKIE); - else - formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge); - + // Always add the expires param as some browsers still don't handle max-age + buf.append(";Expires="); + if (maxAge == 0) + buf.append(__01Jan1970_COOKIE); + else + formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge); + if (version >0) { buf.append(";Max-Age="); buf.append(maxAge); } } - else if (version > 0) - { - buf.append(";Discard"); - } if (isSecure) buf.append(";Secure"); diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java index 3ae9a409fd0..4d36e9aa3b7 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java @@ -361,28 +361,18 @@ public class HttpFieldsTest fields.clear(); fields.addSetCookie("everything","wrong","wrong","wrong",0,"to be replaced",true,true,0); fields.addSetCookie("everything","value","domain","path",0,"comment",true,true,0); - assertEquals("everything=value;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",fields.getStringField("Set-Cookie")); + assertEquals("everything=value;Comment=comment;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",fields.getStringField("Set-Cookie")); Enumeration e =fields.getValues("Set-Cookie"); assertTrue(e.hasMoreElements()); - assertEquals("everything=value;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertEquals("everything=value;Comment=comment;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); assertFalse(e.hasMoreElements()); - assertEquals("Thu, 01 Jan 1970 00:00:00 GMT",fields.getStringField("Expires")); - + assertEquals("Thu, 01 Jan 1970 00:00:00 GMT",fields.getStringField("Expires")); fields.clear(); fields.addSetCookie("ev erything","va lue","do main","pa th",1,"co mment",true,true,2); String setCookie=fields.getStringField("Set-Cookie"); - assertTrue(setCookie.startsWith("\"ev erything\"=\"va lue\";Version=1;Comment=\"co mment\";Path=\"pa th\";Domain=\"do main\";Expires=")); + assertTrue(setCookie.startsWith("\"ev erything\"=\"va lue\";Comment=\"co mment\";Path=\"pa th\";Domain=\"do main\";Expires=")); assertTrue(setCookie.endsWith("GMT;Max-Age=1;Secure;HttpOnly")); - - fields.clear(); - fields.addSetCookie("name","value",null,null,-1,null,false,false,0); - setCookie=fields.getStringField("Set-Cookie"); - assertEquals(-1,setCookie.indexOf("Version=")); - fields.clear(); - fields.addSetCookie("name","v a l u e",null,null,-1,null,false,false,0); - setCookie=fields.getStringField("Set-Cookie"); - assertEquals(17,setCookie.indexOf("Version=1")); fields.clear(); fields.addSetCookie("json","{\"services\":[\"cwa\", \"aa\"]}",null,null,-1,null,false,false,-1); @@ -401,12 +391,6 @@ public class HttpFieldsTest e=fields.getValues("Set-Cookie"); assertEquals("name=more;Domain=domain",e.nextElement()); assertEquals("foo=bob;Domain=domain",e.nextElement()); - - fields=new HttpFields(0); - fields.addSetCookie("name","value==",null,null,-1,null,false,false,0); - setCookie=fields.getStringField("Set-Cookie"); - assertEquals("name=value==",setCookie); - } private Set enum2set(Enumeration e) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java index a045673135b..a46a9eacd54 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java @@ -147,7 +147,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection HttpBuffers ab = (HttpBuffers)_connector; _parser = newHttpParser(ab.getRequestBuffers(), endpoint, new RequestHandler()); _requestFields = new HttpFields(); - _responseFields = new HttpFields(server.getMaxCookieVersion()); + _responseFields = new HttpFields(); _request = new Request(this); _response = new Response(this); _generator = newHttpGenerator(ab.getResponseBuffers(), endpoint); @@ -165,7 +165,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection _connector = connector; _parser = parser; _requestFields = new HttpFields(); - _responseFields = new HttpFields(server.getMaxCookieVersion()); + _responseFields = new HttpFields(); _request = request; _response = new Response(this); _generator = generator; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index cd89923c556..6bbb17da2ed 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -137,7 +137,7 @@ public class Response implements HttpServletResponse if (i>=0) { http_only=true; - comment=comment.substring(i,i+HTTP_ONLY_COMMENT.length()).trim(); + comment=comment.replace(HTTP_ONLY_COMMENT,"").trim(); if (comment.length()==0) comment=null; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 593692232f1..5c9c2076efd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -74,7 +74,6 @@ public class Server extends HandlerWrapper implements Attributes private boolean _sendDateHeader = false; //send Date: header private int _graceful=0; private boolean _stopAtShutdown; - private int _maxCookieVersion=1; private boolean _dumpAfterStart=false; private boolean _dumpBeforeStop=false; private boolean _uncheckedPrintWriter=false; @@ -452,21 +451,20 @@ public class Server extends HandlerWrapper implements Attributes } /* ------------------------------------------------------------ */ - /** Get the maximum cookie version. - * @return the maximum set-cookie version sent by this server + /** */ + @Deprecated public int getMaxCookieVersion() { - return _maxCookieVersion; + return 1; } /* ------------------------------------------------------------ */ - /** Set the maximum cookie version. - * @param maxCookieVersion the maximum set-cookie version sent by this server + /** */ + @Deprecated public void setMaxCookieVersion(int maxCookieVersion) { - _maxCookieVersion = maxCookieVersion; } /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index 8f3eac901cf..426ffcf8ac5 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -518,7 +518,7 @@ public class ResponseTest String set = response.getHttpFields().getStringField("Set-Cookie"); - assertEquals("name=value;Path=/path;Domain=domain;Secure;HttpOnly",set); + assertEquals("name=value;Comment=comment;Path=/path;Domain=domain;Secure;HttpOnly",set); } private Response newResponse() 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 f30ff4189ca..9b81e18812c 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 @@ -63,7 +63,37 @@ import org.eclipse.jetty.util.log.Logger; * This filter extends {@link UserAgentFilter} and if the the initParameter excludedAgents * is set to a comma separated list of user agents, then these agents will be excluded from gzip content. *

+ *

Init Parameters:

+ *
+ * bufferSize                 The output buffer size. Defaults to 8192. Be careful as values <= 0 will lead to an 
+ *                            {@link IllegalArgumentException}. 
+ *                            @see java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream, int)
+ *                            @see java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream, Deflater, int)
+ *                      
+ * minGzipSize                Content will only be compressed if content length is either unknown or greater
+ *                            than minGzipSize.
+ *                      
+ * deflateCompressionLevel    The compression level used for deflate compression. (0-9).
+ *                            @see java.util.zip.Deflater#Deflater(int, boolean)
+ *                            
+ * deflateNoWrap              The noWrap setting for deflate compression. Defaults to true. (true/false)
+ *                            @see java.util.zip.Deflater#Deflater(int, boolean)
  *
+ * mimeTypes                  Comma separated list of mime types to compress. See description above.
+ * 
+ * excludedAgents             Comma separated list of user agents to exclude from compression. Does a 
+ *                            {@link String#contains(CharSequence)} to check if the excluded agent occurs
+ *                            in the user-agent header. If it does -> no compression
+ *                            
+ * excludeAgentPatterns       Same as excludedAgents, but accepts regex patterns for more complex matching.
+ * 
+ * excludePaths               Comma separated list of paths to exclude from compression. 
+ *                            Does a {@link String#startsWith(String)} comparison to check if the path matches.
+ *                            If it does match -> no compression. To match subpaths use excludePathPatterns
+ *                            instead.
+ * 
+ * excludePathPatterns        Same as excludePath, but accepts regex patterns for more complex matching.
+ * 
*/ public class GzipFilter extends UserAgentFilter { @@ -74,6 +104,8 @@ public class GzipFilter extends UserAgentFilter protected Set _mimeTypes; protected int _bufferSize=8192; protected int _minGzipSize=256; + protected int _deflateCompressionLevel=Deflater.DEFAULT_COMPRESSION; + protected boolean _deflateNoWrap = true; protected Set _excludedAgents; protected Set _excludedAgentPatterns; protected Set _excludedPaths; @@ -97,6 +129,14 @@ public class GzipFilter extends UserAgentFilter if (tmp!=null) _minGzipSize=Integer.parseInt(tmp); + tmp=filterConfig.getInitParameter("deflateCompressionLevel"); + if (tmp!=null) + _deflateCompressionLevel=Integer.parseInt(tmp); + + tmp=filterConfig.getInitParameter("deflateNoWrap"); + if (tmp!=null) + _deflateNoWrap=Boolean.parseBoolean(tmp); + tmp=filterConfig.getInitParameter("mimeTypes"); if (tmp!=null) { @@ -256,7 +296,7 @@ public class GzipFilter extends UserAgentFilter @Override protected DeflaterOutputStream createStream() throws IOException { - return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(Deflater.DEFAULT_COMPRESSION)); + return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel,_deflateNoWrap)); } }; } 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 95de423bc4b..50ee23ae346 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 @@ -95,7 +95,7 @@ public class IncludableGzipFilter extends GzipFilter @Override protected DeflaterOutputStream createStream() throws IOException { - return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(Deflater.DEFAULT_COMPRESSION)); + return new DeflaterOutputStream(_response.getOutputStream(),new Deflater(_deflateCompressionLevel, _deflateNoWrap)); } }; } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java index 6847351a668..631864af8d7 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/GzipWithPipeliningTest.java @@ -1,7 +1,12 @@ package org.eclipse.jetty.servlets; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileInputStream; @@ -17,6 +22,7 @@ import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import javax.servlet.DispatcherType; @@ -186,7 +192,7 @@ public class GzipWithPipeliningTest InputStream uncompressedStream = null; if (GzipFilter.DEFLATE.equals(encodingHeader)) { - uncompressedStream = new InflaterInputStream(rawInputStream); + uncompressedStream = new InflaterInputStream(rawInputStream, new Inflater(true)); } else { diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java index dd3d5a7d872..4b26b75fde0 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/IncludableGzipFilterTest.java @@ -25,6 +25,7 @@ import java.io.InputStream; import java.util.Arrays; import java.util.Collection; import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import javax.servlet.http.HttpServletResponse; @@ -139,7 +140,7 @@ public class IncludableGzipFilterTest } else if (compressionType.equals(GzipFilter.DEFLATE)) { - testIn = new InflaterInputStream(compressedResponseStream); + testIn = new InflaterInputStream(compressedResponseStream, new Inflater(true)); } ByteArrayOutputStream testOut = new ByteArrayOutputStream(); IO.copy(testIn,testOut); 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 913704c44d7..6a866ec85aa 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 @@ -21,7 +21,7 @@ import java.util.Enumeration; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; - +import java.util.zip.Inflater; import javax.servlet.DispatcherType; import java.util.zip.InflaterInputStream; @@ -104,7 +104,7 @@ public class GzipTester } else if (compressionType.equals(GzipFilter.DEFLATE)) { - in = new InflaterInputStream(bais); + in = new InflaterInputStream(bais, new Inflater(true)); } out = new ByteArrayOutputStream(); IO.copy(in,out); diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java index 8b1ae148ded..1de9e1b121d 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardStream.java @@ -94,7 +94,9 @@ public class StandardStream implements IStream public boolean isHalfClosed() { CloseState closeState = this.closeState; - return closeState == CloseState.LOCALLY_CLOSED || closeState == CloseState.REMOTELY_CLOSED; + return closeState == CloseState.LOCALLY_CLOSED || + closeState == CloseState.REMOTELY_CLOSED || + closeState == CloseState.CLOSED; } @Override