diff options
author | Greg Wilkins | 2013-05-09 04:16:54 +0000 |
---|---|---|
committer | Greg Wilkins | 2013-05-09 04:16:54 +0000 |
commit | 4dcc9b39fcad2580b5f0ea79f52626e46bec0f9c (patch) | |
tree | 60a040e2520abb6821bc8cf1b5e04e0735d70dc8 | |
parent | 4a95621c8b2fa6cab7e76683d920300e1adfd1d0 (diff) | |
download | org.eclipse.jetty.project-4dcc9b39fcad2580b5f0ea79f52626e46bec0f9c.tar.gz org.eclipse.jetty.project-4dcc9b39fcad2580b5f0ea79f52626e46bec0f9c.tar.xz org.eclipse.jetty.project-4dcc9b39fcad2580b5f0ea79f52626e46bec0f9c.zip |
407614 added excludedMimeTypes to gzipFilter
7 files changed, 149 insertions, 67 deletions
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java index 312830537c..5bd40b22d7 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java @@ -22,10 +22,12 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; +import java.util.Set; import org.eclipse.jetty.util.ArrayTrie; import org.eclipse.jetty.util.BufferUtil; @@ -194,7 +196,7 @@ public class MimeTypes _mimeMap.put(StringUtil.asciiToLowerCase(ext),normalizeMimeType(mimeMap.get(ext))); } } - + /* ------------------------------------------------------------ */ /** Get the MIME type by filename extension. * @param filename A file name @@ -245,6 +247,12 @@ public class MimeTypes } /* ------------------------------------------------------------ */ + public static Set<String> getKnownMimeTypes() + { + return new HashSet<>(__dftMimeMap.values()); + } + + /* ------------------------------------------------------------ */ private static String normalizeMimeType(String type) { MimeTypes.Type t =CACHE.get(type); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java index 9693ca616c..4a84ad96ce 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java @@ -668,13 +668,13 @@ public class DefaultServletTest defholder.setInitParameter("gzip", "true"); defholder.setInitParameter("resourceBase", resBasePath); - String response = connector.getResponses("GET /context/data0.txt HTTP/1.1\r\nHost:localhost:8080\r\n\r\n"); + String response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\n\r\n"); assertResponseContains("Content-Length: 12", response); assertResponseContains("Hello Text 0",response); assertResponseContains("Vary: Accept-Encoding",response); assertResponseNotContains("Content-Encoding: gzip",response); - response = connector.getResponses("GET /context/data0.txt HTTP/1.1\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\n\r\n"); + response = connector.getResponses("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:gzip\r\n\r\n"); assertResponseContains("Content-Length: 9", response); assertResponseContains("fake gzip",response); assertResponseContains("Vary: Accept-Encoding",response); 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 03752cb7f1..6747b64a20 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 @@ -18,6 +18,7 @@ package org.eclipse.jetty.servlets; +import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Locale; @@ -39,9 +40,12 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.servlets.GzipFilterDefaultTest.GetServlet; import org.eclipse.jetty.servlets.gzip.AbstractCompressedStream; import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper; import org.eclipse.jetty.servlets.gzip.GzipOutputStream; +import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -52,8 +56,8 @@ import org.eclipse.jetty.util.log.Logger; * <li>accept-encoding header is set to either gzip, deflate or a combination of those</li> * <li>The response status code is >=200 and <300 * <li>The content length is unknown or more than the <code>minGzipSize</code> initParameter or the minGzipSize is 0(default)</li> - * <li>The content-type is in the comma separated list of mimeTypes set in the <code>mimeTypes</code> initParameter or - * if no mimeTypes are defined the content-type is not "application/gzip"</li> + * <li>If a list of mimeTypes is set by the <code>mimeTypes</code> init parameter, then the Content-Type is in the list.</li> + * <li>If no mimeType list is set, then the content-type is not in the list defined by <code>excludedMimeTypes</code></li> * <li>No content-encoding is specified by the resource</li> * </ul> * @@ -71,44 +75,52 @@ import org.eclipse.jetty.util.log.Logger; * is set to a comma separated list of user agents, then these agents will be excluded from gzip content. * </p> * <p>Init Parameters:</p> - * <PRE> - * bufferSize The output buffer size. Defaults to 8192. Be careful as values <= 0 will lead to an + * <dl> + * <dt>bufferSize</dt> <dd>The output buffer size. Defaults to 8192. Be careful as values <= 0 will lead to an * {@link IllegalArgumentException}. * See: {@link java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream, int)} * and: {@link java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream, Deflater, int)} - * - * minGzipSize Content will only be compressed if content length is either unknown or greater + * </dd> + * <dt>minGzipSize</dt> <dd>Content will only be compressed if content length is either unknown or greater * than <code>minGzipSize</code>. - * - * deflateCompressionLevel The compression level used for deflate compression. (0-9). + * </dd> + * <dt>deflateCompressionLevel</dt> <dd>The compression level used for deflate compression. (0-9). * See: {@link java.util.zip.Deflater#Deflater(int, boolean)} - * - * deflateNoWrap The noWrap setting for deflate compression. Defaults to true. (true/false) + * </dd> + * <dt>deflateNoWrap</dt> <dd>The noWrap setting for deflate compression. Defaults to true. (true/false) * See: {@link java.util.zip.Deflater#Deflater(int, boolean)} - * - * methods Comma separated list of HTTP methods to compress. If not set, only GET requests are compressed. - * - * 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 + * </dd> + * <dt>methods</dt> <dd>Comma separated list of HTTP methods to compress. If not set, only GET requests are compressed. + * </dd> + * <dt>mimeTypes</dt> <dd>Comma separated list of mime types to compress. If it is not set, then the excludedMimeTypes list is used. + * </dd> + * <dt>excludedMimeTypes</dt> <dd>Comma separated list of mime types to never compress. If not set, then the default is the commonly known + * image, video, audio and compressed types. + * </dd> + + * <dt>excludedAgents</dt> <dd>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. + * </dd> + * <dt>excludeAgentPatterns</dt> <dd>Same as excludedAgents, but accepts regex patterns for more complex matching. + * </dd> + * <dt>excludePaths</dt> <dd>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 <code>excludePathPatterns</code> * 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 + * </dd> + * <dt>excludePathPatterns</dt> <dd>Same as excludePath, but accepts regex patterns for more complex matching. + * </dd> + * <dt>vary</dt> <dd>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. - * </PRE> + * </dd> + * <dt>checkGzExists</dt> <dd>If set to true, the filter check if a static resource with ".gz" appended exists. If so then + * the normal processing is done so that the default servlet can send the pre existing gz content. + * </dd> + * </dl> */ public class GzipFilter extends UserAgentFilter { @@ -120,11 +132,13 @@ public class GzipFilter extends UserAgentFilter public final static String ETAG="o.e.j.s.GzipFilter.ETag"; protected ServletContext _context; - protected Set<String> _mimeTypes; + protected final Set<String> _mimeTypes=new HashSet<>(); + protected boolean _excludeMimeTypes; protected int _bufferSize=8192; protected int _minGzipSize=256; protected int _deflateCompressionLevel=Deflater.DEFAULT_COMPRESSION; protected boolean _deflateNoWrap = true; + protected boolean _checkGzExists = true; // non-static, as other GzipFilter instances may have different configurations protected final ThreadLocal<Deflater> _deflater = new ThreadLocal<Deflater>(); @@ -169,6 +183,10 @@ public class GzipFilter extends UserAgentFilter if (tmp!=null) _deflateNoWrap=Boolean.parseBoolean(tmp); + tmp=filterConfig.getInitParameter("checkGzExists"); + if (tmp!=null) + _checkGzExists=Boolean.parseBoolean(tmp); + tmp=filterConfig.getInitParameter("methods"); if (tmp!=null) { @@ -180,9 +198,32 @@ public class GzipFilter extends UserAgentFilter _methods.add(HttpMethod.GET.asString()); tmp=filterConfig.getInitParameter("mimeTypes"); - if (tmp!=null) + if (tmp==null) + { + _excludeMimeTypes=true; + tmp=filterConfig.getInitParameter("excludedMimeTypes"); + if (tmp==null) + { + for (String type:MimeTypes.getKnownMimeTypes()) + { + if (type.startsWith("image/")|| + type.startsWith("audio/")|| + type.startsWith("video/")) + _mimeTypes.add(type); + _mimeTypes.add("application/compress"); + _mimeTypes.add("application/zip"); + _mimeTypes.add("application/gzip"); + } + } + else + { + StringTokenizer tok = new StringTokenizer(tmp,",",false); + while (tok.hasMoreTokens()) + _mimeTypes.add(tok.nextToken()); + } + } + else { - _mimeTypes=new HashSet<String>(); StringTokenizer tok = new StringTokenizer(tmp,",",false); while (tok.hasMoreTokens()) _mimeTypes.add(tok.nextToken()); @@ -196,7 +237,7 @@ public class GzipFilter extends UserAgentFilter _excludedAgents.add(tok.nextToken()); } - tmp=filterConfig.getInitParameter("excludeAgentPatterns"); + tmp=filterConfig.getInitParameter("excludeAgentPatterns"); if (tmp!=null) { _excludedAgentPatterns=new HashSet<Pattern>(); @@ -257,17 +298,32 @@ public class GzipFilter extends UserAgentFilter } // Exclude non compressible mime-types known from URI extension. - no Vary because no matter what client, this URI is always excluded - if (_mimeTypes!=null && _mimeTypes.size()>0) + if (_mimeTypes.size()>0) { String mimeType = _context.getMimeType(request.getRequestURI()); - if (mimeType!=null && !_mimeTypes.contains(mimeType)) + if (mimeType!=null && _mimeTypes.contains(mimeType)==_excludeMimeTypes) { // handle normally without setting vary header super.doFilter(request,response,chain); return; } } + + if (_checkGzExists && request.getServletContext()!=null) + { + String path=request.getServletContext().getRealPath(URIUtil.addPaths(request.getServletPath(),request.getPathInfo())); + if (path!=null) + { + File gz=new File(path+".gz"); + if (gz.exists()) + { + // allow default servlet to handle + super.doFilter(request,response,chain); + return; + } + } + } // Excluded User-Agents String ua = getUserAgent(request); @@ -457,7 +513,7 @@ public class GzipFilter extends UserAgentFilter protected void configureWrappedResponse(CompressedResponseWrapper wrappedResponse) { - wrappedResponse.setMimeTypes(_mimeTypes); + wrappedResponse.setMimeTypes(_mimeTypes,_excludeMimeTypes); wrappedResponse.setBufferSize(_bufferSize); wrappedResponse.setMinCompressSize(_minGzipSize); } 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 44690347f8..fe805deb91 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 @@ -27,12 +27,14 @@ import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import java.util.zip.GZIPOutputStream; +import javax.servlet.DispatcherType; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.io.UncheckedPrintWriter; +import org.eclipse.jetty.server.Response; import org.eclipse.jetty.servlets.gzip.AbstractCompressedStream; import org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper; @@ -144,10 +146,16 @@ public class IncludableGzipFilter extends GzipFilter @Override public 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); + if (getRequest().getDispatcherType()==DispatcherType.INCLUDE) + { + if (!"etag".equalsIgnoreCase(name) && !name.startsWith("content-")) + { + HttpServletResponse response = (HttpServletResponse)getResponse(); + response.setHeader("org.eclipse.jetty.server.include."+name,value); + } + } + else + super.setHeader(name,value); } @Override diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/CompressedResponseWrapper.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/CompressedResponseWrapper.java index 2e1d426f56..fe0459ff86 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/CompressedResponseWrapper.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/CompressedResponseWrapper.java @@ -42,6 +42,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp public static final int DEFAULT_MIN_COMPRESS_SIZE = 256; private Set<String> _mimeTypes; + private boolean _excludeMimeTypes; private int _bufferSize=DEFAULT_BUFFER_SIZE; private int _minCompressSize=DEFAULT_MIN_COMPRESS_SIZE; protected HttpServletRequest _request; @@ -67,6 +68,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp } /* ------------------------------------------------------------ */ + @Override public int getBufferSize() { return _bufferSize; @@ -92,16 +94,15 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setMimeTypes(java.util.Set) */ - public void setMimeTypes(Set<String> mimeTypes) + public void setMimeTypes(Set<String> mimeTypes,boolean excludeMimeTypes) { + _excludeMimeTypes=excludeMimeTypes; _mimeTypes = mimeTypes; } /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setBufferSize(int) */ @Override public void setBufferSize(int bufferSize) @@ -127,18 +128,17 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp { super.setContentType(ct); - if (ct!=null) + if (_compressedStream==null || _compressedStream.getOutputStream()==null) { - int colon=ct.indexOf(";"); - if (colon>0) - ct=ct.substring(0,colon); - } + if (ct!=null) + { + int colon=ct.indexOf(";"); + if (colon>0) + ct=ct.substring(0,colon); - if ((_compressedStream==null || _compressedStream.getOutputStream()==null) && - (_mimeTypes==null && ct!=null && ct.contains("gzip") || - _mimeTypes!=null && (ct==null||!_mimeTypes.contains(StringUtil.asciiToLowerCase(ct))))) - { - noCompression(); + if (_mimeTypes.contains(StringUtil.asciiToLowerCase(ct))==_excludeMimeTypes) + noCompression(); + } } } @@ -146,6 +146,7 @@ public abstract class CompressedResponseWrapper extends HttpServletResponseWrapp /** * @see org.eclipse.jetty.servlets.gzip.CompressedResponseWrapper#setStatus(int, java.lang.String) */ + @SuppressWarnings("deprecation") @Override public void setStatus(int sc, String sm) { diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipHandler.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipHandler.java index ec125b9429..eaa5acc89f 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipHandler.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/gzip/GzipHandler.java @@ -62,8 +62,9 @@ public class GzipHandler extends HandlerWrapper { private static final Logger LOG = Log.getLogger(GzipHandler.class); - protected Set<String> _mimeTypes; - protected Set<String> _excluded; + final protected Set<String> _mimeTypes=new HashSet<>(); + protected boolean _excludeMimeTypes=false; + protected Set<String> _excludedUA; protected int _bufferSize = 8192; protected int _minGzipSize = 256; protected String _vary = "Accept-Encoding, User-Agent"; @@ -96,7 +97,9 @@ public class GzipHandler extends HandlerWrapper */ public void setMimeTypes(Set<String> mimeTypes) { - _mimeTypes = mimeTypes; + _excludeMimeTypes=false; + _mimeTypes.clear(); + _mimeTypes.addAll(mimeTypes); } /* ------------------------------------------------------------ */ @@ -110,7 +113,8 @@ public class GzipHandler extends HandlerWrapper { if (mimeTypes != null) { - _mimeTypes = new HashSet<String>(); + _excludeMimeTypes=false; + _mimeTypes.clear(); StringTokenizer tok = new StringTokenizer(mimeTypes,",",false); while (tok.hasMoreTokens()) { @@ -121,13 +125,22 @@ public class GzipHandler extends HandlerWrapper /* ------------------------------------------------------------ */ /** + * Set the mime types. + */ + public void setExcludeMimeTypes(boolean exclude) + { + _excludeMimeTypes=exclude; + } + + /* ------------------------------------------------------------ */ + /** * Get the excluded user agents. * * @return excluded user agents */ public Set<String> getExcluded() { - return _excluded; + return _excludedUA; } /* ------------------------------------------------------------ */ @@ -139,7 +152,7 @@ public class GzipHandler extends HandlerWrapper */ public void setExcluded(Set<String> excluded) { - _excluded = excluded; + _excludedUA = excluded; } /* ------------------------------------------------------------ */ @@ -153,10 +166,10 @@ public class GzipHandler extends HandlerWrapper { if (excluded != null) { - _excluded = new HashSet<String>(); + _excludedUA = new HashSet<String>(); StringTokenizer tok = new StringTokenizer(excluded,",",false); while (tok.hasMoreTokens()) - _excluded.add(tok.nextToken()); + _excludedUA.add(tok.nextToken()); } } @@ -244,10 +257,10 @@ public class GzipHandler extends HandlerWrapper if (ae != null && ae.indexOf("gzip")>=0 && !response.containsHeader("Content-Encoding") && !HttpMethod.HEAD.is(request.getMethod())) { - if (_excluded!=null) + if (_excludedUA!=null) { String ua = request.getHeader("User-Agent"); - if (_excluded.contains(ua)) + if (_excludedUA.contains(ua)) { _handler.handle(target,baseRequest, request, response); return; @@ -326,7 +339,7 @@ public class GzipHandler extends HandlerWrapper return new CompressedResponseWrapper(request,response) { { - super.setMimeTypes(GzipHandler.this._mimeTypes); + super.setMimeTypes(GzipHandler.this._mimeTypes,GzipHandler.this._excludeMimeTypes); super.setBufferSize(GzipHandler.this._bufferSize); super.setMinCompressSize(GzipHandler.this._minGzipSize); } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PipelineHelper.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PipelineHelper.java index 95f0a23412..6e182a57c4 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PipelineHelper.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/PipelineHelper.java @@ -47,10 +47,6 @@ public class PipelineHelper public PipelineHelper(URI uri, String encodingHeader) { - if (LOG instanceof StdErrLog) - { - ((StdErrLog)LOG).setLevel(StdErrLog.LEVEL_DEBUG); - } this.uri = uri; this.endpoint = new InetSocketAddress(uri.getHost(),uri.getPort()); this.encodingHeader = encodingHeader; |