447515 Remove GzipFilter

Added a module to apply GzipHandler to the entire server
This commit is contained in:
Greg Wilkins 2014-10-24 10:48:33 +11:00
parent ac1b111d57
commit 67e686c108
6 changed files with 141 additions and 41 deletions

View File

@ -0,0 +1,65 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<!-- =============================================================== -->
<!-- Mixin the GZIP Handler -->
<!-- This applies the GZIP Handler to the entire server -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get id="next" name="handler" />
<Set name="handler">
<New id="GzipHandler" class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
<Set name="handler"><Ref refid="next" /></Set>
<Set name="minGzipSize"><Property name="gzip.minGzipSize" default="2048"/></Set>
<Set name="checkGzExists"><Property name="gzip.checkGzExists" default="false"/></Set>
<Set name="compressionLevel"><Property name="gzip.compressionLevel" default="-1"/></Set>
<Set name="excludedAgentPatterns">
<Array type="String">
<Item><Property name="gzip.excludedUserAgent" default=".*MSIE.6\.0.*"/></Item>
</Array>
</Set>
<Set name="includedMethods">
<Array type="String">
<Item>GET</Item>
</Array>
</Set>
<!--
<Set name="includedPaths">
<Array type="String">
<Item>/*</Item>
</Array>
</Set>
-->
<!--
<Set name="excludedPaths">
<Array type="String">
<Item>*.gz</Item>
</Array>
</Set>
-->
<!--
<Call name="addIncludedMimeTypes">
<Arg><Array type="String">
<Item>some/type</Item>
</Array></Arg>
</Call>
-->
<!--
<Call name="addExcludedMimeTypes">
<Arg><Array type="String">
<Item>some/type</Item>
</Array></Arg>
</Call>
-->
</New>
</Set>
</Configure>

View File

@ -0,0 +1,18 @@
#
# GZIP module
# Applies GzipHandler to entire server
#
[depend]
server
[xml]
etc/jetty-gzip.xml
[ini-template]
### Gzip Handler
gzip.minGzipSize=2048
gzip.checkGzExists=false
gzip.compressionLevel=-1
gzip.excludedUserAgent=.*MSIE.6\.0.*

View File

@ -104,7 +104,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
return _channel;
}
public Interceptor getFilter()
public Interceptor getInterceptor()
{
return _filter;
}

View File

@ -37,7 +37,6 @@ import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.PathMap;
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.Request;
@ -59,19 +58,19 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
public final static int DEFAULT_MIN_GZIP_SIZE=16;
private int _minGzipSize=DEFAULT_MIN_GZIP_SIZE;
private int _deflateCompressionLevel=Deflater.DEFAULT_COMPRESSION;
private int _compressionLevel=Deflater.DEFAULT_COMPRESSION;
private boolean _checkGzExists = true;
// non-static, as other GzipHandler instances may have different configurations
private final ThreadLocal<Deflater> _deflater = new ThreadLocal<Deflater>();
private final Set<String> _methods=new HashSet<>();
private final Set<String> _includedMethods=new HashSet<>();
private final Set<Pattern> _excludedAgentPatterns=new HashSet<>();
private final PathMap<Boolean> _excludedPaths=new PathMap<>();
private final PathMap<Boolean> _includedPaths=new PathMap<>();
private final Set<String> _excludedMimeTypes=new HashSet<>();
private final Set<String> _includedMimeTypes=new HashSet<>();
private HttpField _vary=GzipHttpOutputInterceptor.VARY;
private HttpField _vary;
private final Set<String> _uaCache = new ConcurrentHashSet<>();
private int _uaCacheSize = 1024;
@ -82,7 +81,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
*/
public GzipHandler()
{
_methods.add(HttpMethod.GET.asString());
_includedMethods.add(HttpMethod.GET.asString());
for (String type:MimeTypes.getKnownMimeTypes())
{
if (type.startsWith("image/")||
@ -96,6 +95,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
_excludedMimeTypes.add("application/bzip2");
_excludedMimeTypes.add("application/x-rar-compressed");
LOG.debug("{} excluding mimes {}",this,_excludedMimeTypes);
_excludedAgentPatterns.add(Pattern.compile(".*MSIE 6.0.*"));
}
/* ------------------------------------------------------------ */
@ -130,7 +131,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
public void addIncludedMethods(String... methods)
{
for (String m : methods)
_methods.add(m);
_includedMethods.add(m);
}
/* ------------------------------------------------------------ */
@ -161,9 +162,9 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
/* ------------------------------------------------------------ */
public int getDeflateCompressionLevel()
public int getCompressionLevel()
{
return _deflateCompressionLevel;
return _compressionLevel;
}
/* ------------------------------------------------------------ */
@ -204,7 +205,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
Deflater df = _deflater.get();
if (df==null)
df=new Deflater(_deflateCompressionLevel,true);
df=new Deflater(_compressionLevel,true);
else
_deflater.set(null);
@ -252,7 +253,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
/* ------------------------------------------------------------ */
public String[] getMethods()
{
return _methods.toArray(new String[_methods.size()]);
return _includedMethods.toArray(new String[_includedMethods.size()]);
}
/* ------------------------------------------------------------ */
@ -266,6 +267,14 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
return _minGzipSize;
}
/* ------------------------------------------------------------ */
@Override
protected void doStart() throws Exception
{
_vary=(_excludedAgentPatterns.size()>0)?GzipHttpOutputInterceptor.VARY_ACCEPT_ENCODING_USER_AGENT:GzipHttpOutputInterceptor.VARY_ACCEPT_ENCODING;
super.doStart();
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
@ -278,7 +287,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
LOG.debug("{} handle {} in {}",this,baseRequest,context);
// If not a supported method - no Vary because no matter what client, this URI is always excluded
if (!_methods.contains(baseRequest.getMethod()))
if (!_includedMethods.contains(baseRequest.getMethod()))
{
LOG.debug("{} excluded by method {}",this,request);
_handler.handle(target,baseRequest, request, response);
@ -333,8 +342,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
HttpOutput out = channel.getResponse().getHttpOutput();
out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,channel,out.getFilter()));
HttpOutput out = channel.getResponse().getHttpOutput();
HttpOutput.Interceptor interceptor = out.getInterceptor();
if (!(interceptor instanceof GzipHttpOutputInterceptor))
out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,channel,interceptor));
_handler.handle(target,baseRequest, request, response);
@ -422,9 +433,9 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
/* ------------------------------------------------------------ */
public void setDeflateCompressionLevel(int deflateCompressionLevel)
public void setCompressionLevel(int compressionLevel)
{
_deflateCompressionLevel = deflateCompressionLevel;
_compressionLevel = compressionLevel;
}
/* ------------------------------------------------------------ */
@ -454,7 +465,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
/* ------------------------------------------------------------ */
public void setIncludedMethods(String... methods)
{
_methods.clear();
_includedMethods.clear();
addIncludedMethods(methods);
}
@ -487,22 +498,5 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
_minGzipSize = minGzipSize;
}
/* ------------------------------------------------------------ */
/**
* Set the value of the Vary header sent with responses that could be compressed.
* <p>
* 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=new PreEncodedHttpField(HttpHeader.VARY,vary);
}
}

View File

@ -44,7 +44,8 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
private final static PreEncodedHttpField CONTENT_ENCODING_GZIP=new PreEncodedHttpField(HttpHeader.CONTENT_ENCODING,"gzip");
private final static byte[] GZIP_HEADER = new byte[] { (byte)0x1f, (byte)0x8b, Deflater.DEFLATED, 0, 0, 0, 0, 0, 0, 0 };
public final static HttpField VARY=new PreEncodedHttpField(HttpHeader.VARY,HttpHeader.ACCEPT_ENCODING+", "+HttpHeader.USER_AGENT);
public final static HttpField VARY_ACCEPT_ENCODING_USER_AGENT=new PreEncodedHttpField(HttpHeader.VARY,HttpHeader.ACCEPT_ENCODING+", "+HttpHeader.USER_AGENT);
public final static HttpField VARY_ACCEPT_ENCODING=new PreEncodedHttpField(HttpHeader.VARY,HttpHeader.ACCEPT_ENCODING.asString());
private enum GZState { MIGHT_COMPRESS, NOT_COMPRESSING, COMMITTING, COMPRESSING, FINISHED};
private final AtomicReference<GZState> _state = new AtomicReference<>(GZState.MIGHT_COMPRESS);
@ -61,7 +62,7 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
public GzipHttpOutputInterceptor(GzipFactory factory, HttpChannel channel, HttpOutput.Interceptor next)
{
this(factory,VARY,channel.getHttpConfiguration().getOutputBufferSize(),channel,next);
this(factory,VARY_ACCEPT_ENCODING_USER_AGENT,channel.getHttpConfiguration().getOutputBufferSize(),channel,next);
}
public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, HttpChannel channel, HttpOutput.Interceptor next)

View File

@ -204,7 +204,7 @@ public class GzipDefaultTest
tester.prepareServerFile("file.txt",filesize);
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
tester.getGzipHandler().setVary("Accept-Encoding");
tester.getGzipHandler().setExcludedAgentPatterns();
try
{
@ -315,7 +315,7 @@ public class GzipDefaultTest
tester.prepareServerFile("file.txt",filesize);
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
tester.getGzipHandler().setVary("Accept-Encoding");
tester.getGzipHandler().setExcludedAgentPatterns();
try
{
@ -400,15 +400,13 @@ public class GzipDefaultTest
}
}
@Test
public void testGzipCompressedByContentTypeWithEncoding() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setContentServlet(HttpContentTypeWithEncoding.class);
tester.getGzipHandler().addIncludedMimeTypes("text/plain");
tester.getGzipHandler().setVary("Accept-Encoding");
tester.getGzipHandler().setExcludedAgentPatterns();
try
{
tester.start();
@ -507,6 +505,30 @@ public class GzipDefaultTest
tester.stop();
}
}
@Test
public void testUserAgentExclusionDefault() throws Exception
{
GzipTester tester = new GzipTester(testingdir,compressionType);
tester.setContentServlet(DefaultServlet.class);
tester.setUserAgent("Some MSIE 6.0 user-agent");
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("file.txt",filesize);
try
{
tester.start();
HttpTester.Response http = tester.assertIsResponseNotGzipCompressed("GET","file.txt",filesize,HttpStatus.OK_200);
Assert.assertEquals("Accept-Encoding, User-Agent",http.get("Vary"));
}
finally
{
tester.stop();
}
}
@Test
public void testUserAgentExclusionByExcludedAgentPatterns() throws Exception