447515 Remove GzipFilter

Moved all usages of GzipFilter to GzipHandler
added support to ServerContextHandler to create a GzipHandler
This commit is contained in:
Greg Wilkins 2014-10-24 08:17:05 +11:00
parent b65aed7d10
commit 738c47bc55
41 changed files with 738 additions and 1284 deletions

View File

@ -38,7 +38,7 @@ import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.servlets.gzip.GzipHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;

View File

@ -10,6 +10,7 @@ au=audio/basic
avi=video/x-msvideo
bcpio=application/x-bcpio
bin=application/octet-stream
bmp=image/bmp
cab=application/x-cabinet
cdf=application/x-netcdf
class=application/java-vm
@ -50,6 +51,7 @@ jar=application/java-archive
java=text/plain
jnlp=application/x-java-jnlp-file
jpe=image/jpeg
jp2=image/jpeg2000
jpeg=image/jpeg
jpg=image/jpeg
js=application/javascript
@ -112,6 +114,7 @@ ps=application/postscript
qml=text/x-qml
qt=video/quicktime
ra=audio/x-pn-realaudio
rar=application/x-rar-compressed
ram=audio/x-pn-realaudio
ras=image/x-cmu-raster
rdf=application/rdf+xml
@ -169,6 +172,7 @@ wmlsc=application/vnd.wap.wmlscriptc
wrl=model/vrml
wtls-ca-certificate=application/vnd.wap.wtls-ca-certificate
xbm=image/x-xbitmap
xcf=image/xcf
xht=application/xhtml+xml
xhtml=application/xhtml+xml
xls=application/vnd.ms-excel

View File

@ -339,13 +339,18 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
handleException(e);
}
}
catch (EofException|QuietServletException e)
{
error=true;
LOG.debug(e);
_state.error(e);
_request.setHandled(true);
handleException(e);
}
catch (Exception e)
{
error=true;
if (e instanceof EofException)
LOG.debug(e);
else
LOG.warn(String.valueOf(_request.getHttpURI()), e);
LOG.warn(String.valueOf(_request.getHttpURI()), e);
_state.error(e);
_request.setHandled(true);
handleException(e);

View File

@ -88,6 +88,22 @@ public class HandlerWrapper extends AbstractHandlerContainer
updateBean(old,_handler);
}
/* ------------------------------------------------------------ */
/** Replace the current handler with another HandlerWrapper
* linked to the current handler. This is equivalent to:<pre>
* wrapper.setHandler(getHandler());
* setHandler(wrapper);
* </pre>
* @param wrapper
*/
public void insertHandler(HandlerWrapper wrapper)
{
if (wrapper==null || wrapper.getHandler()!=null)
throw new IllegalArgumentException();
wrapper.setHandler(getHandler());
setHandler(wrapper);
}
/* ------------------------------------------------------------ */
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.util.zip.Deflater;
@ -26,7 +26,7 @@ public interface GzipFactory
{
Deflater getDeflater(Request request, long content_length);
boolean isExcludedMimeType(String mimetype);
boolean isMimeTypeGzipable(String mimetype);
void recycle(Deflater deflater);
}

View File

@ -16,14 +16,13 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import java.util.zip.Deflater;
@ -37,6 +36,7 @@ import org.eclipse.jetty.http.HttpHeader;
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;
@ -55,22 +55,22 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
public final static String GZIP = "gzip";
public final static String DEFLATE = "deflate";
public final static String ETAG_GZIP="--gzip";
public final static String ETAG = "o.e.j.s.GzipFilter.ETag";
public final static String ETAG = "o.e.j.s.Gzip.ETag";
public final static int DEFAULT_MIN_GZIP_SIZE=16;
private final Set<String> _mimeTypes=new HashSet<>();
private boolean _excludeMimeTypes;
private int _minGzipSize=DEFAULT_MIN_GZIP_SIZE;
private int _deflateCompressionLevel=Deflater.DEFAULT_COMPRESSION;
private boolean _checkGzExists = true;
// non-static, as other GzipFilter instances may have different configurations
// non-static, as other GzipHandler instances may have different configurations
private final ThreadLocal<Deflater> _deflater = new ThreadLocal<Deflater>();
private final MimeTypes _knownMimeTypes= new MimeTypes();
private final Set<String> _methods=new HashSet<>();
private final Set<Pattern> _excludedAgentPatterns=new HashSet<>();
private final Set<Pattern> _excludedPathPatterns=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 final Set<String> _uaCache = new ConcurrentHashSet<>();
@ -83,19 +83,90 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
public GzipHandler()
{
_methods.add(HttpMethod.GET.asString());
_excludeMimeTypes=true;
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");
_excludedMimeTypes.add(type);
}
_excludedMimeTypes.add("application/compress");
_excludedMimeTypes.add("application/zip");
_excludedMimeTypes.add("application/gzip");
_excludedMimeTypes.add("application/bzip2");
_excludedMimeTypes.add("application/x-rar-compressed");
LOG.debug("{} excluding mimes {}",this,_excludedMimeTypes);
}
/* ------------------------------------------------------------ */
public void addExcludedAgentPatterns(String... patterns)
{
for (String s : patterns)
_excludedAgentPatterns.add(Pattern.compile(s));
}
/* ------------------------------------------------------------ */
/**
* Set the mime types.
*/
public void addExcludedMimeTypes(String... types)
{
_excludedMimeTypes.addAll(Arrays.asList(types));
}
/* ------------------------------------------------------------ */
/**
* @param pathspecs Path specs (as per servlet spec) to exclude. If a
* ServletContext is available, the paths are relative to the context path,
* otherwise they are absolute
*/
public void addExcludedPaths(String... pathspecs)
{
for (String ps : pathspecs)
_excludedPaths.put(ps,Boolean.TRUE);
}
/* ------------------------------------------------------------ */
public void addIncludedMethods(String... methods)
{
for (String m : methods)
_methods.add(m);
}
/* ------------------------------------------------------------ */
/**
* Set the mime types.
*/
public void addIncludedMimeTypes(String... types)
{
_includedMimeTypes.addAll(Arrays.asList(types));
}
/* ------------------------------------------------------------ */
/**
* @param pathspecs Path specs (as per servlet spec) to include. If a
* ServletContext is available, the paths are relative to the context path,
* otherwise they are absolute
*/
public void addIncludedPaths(String... pathspecs)
{
for (String ps : pathspecs)
_includedPaths.put(ps,Boolean.TRUE);
}
/* ------------------------------------------------------------ */
public boolean getCheckGzExists()
{
return _checkGzExists;
}
/* ------------------------------------------------------------ */
public int getDeflateCompressionLevel()
{
return _deflateCompressionLevel;
}
/* ------------------------------------------------------------ */
@Override
public Deflater getDeflater(Request request, long content_length)
{
@ -139,6 +210,50 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
return df;
}
/* ------------------------------------------------------------ */
public String[] getExcludedAgentPatterns()
{
Pattern[] ps = _excludedAgentPatterns.toArray(new Pattern[_excludedAgentPatterns.size()]);
String[] s = new String[ps.length];
int i=0;
for (Pattern p: ps)
s[i++]=p.toString();
return s;
}
/* ------------------------------------------------------------ */
public String[] getExcludedMimeTypes()
{
return _excludedMimeTypes.toArray(new String[_excludedMimeTypes.size()]);
}
/* ------------------------------------------------------------ */
public String[] getExcludedPaths()
{
String[] ps = _excludedPaths.keySet().toArray(new String[_excludedPaths.size()]);
return ps;
}
/* ------------------------------------------------------------ */
public String[] getIncludedMimeTypes()
{
return _includedMimeTypes.toArray(new String[_includedMimeTypes.size()]);
}
/* ------------------------------------------------------------ */
public String[] getIncludedPaths()
{
String[] ps = _includedPaths.keySet().toArray(new String[_includedPaths.size()]);
return ps;
}
/* ------------------------------------------------------------ */
public String[] getMethods()
{
return _methods.toArray(new String[_methods.size()]);
}
/* ------------------------------------------------------------ */
/**
@ -158,18 +273,21 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
LOG.debug("{} doFilter {}",this,request);
ServletContext context = baseRequest.getServletContext();
String path = context==null?baseRequest.getRequestURI():URIUtil.addPaths(baseRequest.getServletPath(),baseRequest.getPathInfo());
LOG.debug("{} handle {} in {}",this,baseRequest,context);
// If not a supported method or it is an Excluded URI or an excluded UA - no Vary because no matter what client, this URI is always excluded
String requestURI = request.getRequestURI();
if (!_methods.contains(request.getMethod()))
// If not a supported method - no Vary because no matter what client, this URI is always excluded
if (!_methods.contains(baseRequest.getMethod()))
{
LOG.debug("{} excluded by method {}",this,request);
_handler.handle(target,baseRequest, request, response);
return;
}
if (isExcludedPath(requestURI))
// If not a supported URI- no Vary because no matter what client, this URI is always excluded
// Use pathInfo because this is be
if (!isPathGzipable(path))
{
LOG.debug("{} excluded by path {}",this,request);
_handler.handle(target,baseRequest, request, response);
@ -177,38 +295,25 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
// Exclude non compressible mime-types known from URI extension. - no Vary because no matter what client, this URI is always excluded
if (_mimeTypes.size()>0 && _excludeMimeTypes)
String mimeType = context==null?null:context.getMimeType(path);
if (mimeType!=null)
{
ServletContext context = request.getServletContext();
String mimeType = context==null?_knownMimeTypes.getMimeByExtension(request.getRequestURI()):context.getMimeType(request.getRequestURI());
if (mimeType!=null)
mimeType = MimeTypes.getContentTypeWithoutCharset(mimeType);
if (!isMimeTypeGzipable(mimeType))
{
mimeType = MimeTypes.getContentTypeWithoutCharset(mimeType);
if (_mimeTypes.contains(mimeType))
{
LOG.debug("{} excluded by path suffix {}",this,request);
// handle normally without setting vary header
_handler.handle(target,baseRequest, request, response);
return;
}
LOG.debug("{} excluded by path suffix mime type {}",this,request);
// handle normally without setting vary header
_handler.handle(target,baseRequest, request, response);
return;
}
}
//If the Content-Encoding is already set, then we won't compress
if (response.getHeader("Content-Encoding") != null)
{
_handler.handle(target,baseRequest, request, response);
return;
}
if (_checkGzExists && request.getServletContext()!=null)
if (_checkGzExists && context!=null)
{
String path=request.getServletContext().getRealPath(URIUtil.addPaths(request.getServletPath(),request.getPathInfo()));
if (path!=null)
String realpath=request.getServletContext().getRealPath(path);
if (realpath!=null)
{
File gz=new File(path+".gz");
File gz=new File(realpath+".gz");
if (gz.exists())
{
LOG.debug("{} gzip exists {}",this,request);
@ -235,40 +340,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
public int getDeflateCompressionLevel()
{
return _deflateCompressionLevel;
}
public void setDeflateCompressionLevel(int deflateCompressionLevel)
{
_deflateCompressionLevel = deflateCompressionLevel;
}
public boolean getCheckGzExists()
{
return _checkGzExists;
}
public void setCheckGzExists(boolean checkGzExists)
{
_checkGzExists = checkGzExists;
}
public String[] getMethods()
{
return _methods.toArray(new String[_methods.size()]);
}
public void setMethods(String[] methods)
{
_methods.clear();
for (String m : methods)
_methods.add(m);
}
/* ------------------------------------------------------------ */
/**
* Checks to see if the userAgent is excluded
*
@ -276,11 +348,10 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
* the user agent
* @return boolean true if excluded
*/
private boolean isExcludedAgent(String ua)
protected boolean isExcludedAgent(String ua)
{
if (ua == null)
return false;
if (_excludedAgentPatterns != null)
{
@ -303,37 +374,38 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
return false;
}
/* ------------------------------------------------------------ */
@Override
public boolean isExcludedMimeType(String mimetype)
public boolean isMimeTypeGzipable(String mimetype)
{
return _mimeTypes.contains(mimetype) == _excludeMimeTypes;
if (_includedMimeTypes.size()>0 && _includedMimeTypes.contains(mimetype))
return true;
return !_excludedMimeTypes.contains(mimetype);
}
/* ------------------------------------------------------------ */
/**
* Checks to see if the path is excluded
* Checks to see if the path is included and/pr excluded
*
* @param requestURI
* the request uri
* @return boolean true if excluded
* @return boolean true if gzipable
*/
private boolean isExcludedPath(String requestURI)
protected boolean isPathGzipable(String requestURI)
{
if (requestURI == null)
return true;
if (_includedPaths.size()>0 && _includedPaths.containsMatch(requestURI))
return true;
if (_excludedPaths.size()>0 && _excludedPaths.containsMatch(requestURI))
return false;
if (_excludedPathPatterns != null)
{
for (Pattern pattern : _excludedPathPatterns)
{
if (pattern.matcher(requestURI).matches())
{
return true;
}
}
}
return false;
return true;
}
/* ------------------------------------------------------------ */
@Override
public void recycle(Deflater deflater)
{
@ -343,87 +415,64 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
/* ------------------------------------------------------------ */
public void setCheckGzExists(boolean checkGzExists)
{
_checkGzExists = checkGzExists;
}
/* ------------------------------------------------------------ */
public void setDeflateCompressionLevel(int deflateCompressionLevel)
{
_deflateCompressionLevel = deflateCompressionLevel;
}
/* ------------------------------------------------------------ */
public void setExcludedAgentPatterns(String... patterns)
{
_excludedAgentPatterns.clear();
addExcludedAgentPatterns(patterns);
}
/* ------------------------------------------------------------ */
/**
* Set the mime types.
*/
public void setExcludeMimeTypes(boolean exclude)
public void setExcludedMimeTypes(String... types)
{
_excludeMimeTypes=exclude;
_excludedMimeTypes.clear();
addExcludedMimeTypes(types);
}
public String[] getMimeTypes()
/* ------------------------------------------------------------ */
public void setExcludedPaths(String... pathspecs)
{
return _mimeTypes.toArray(new String[_mimeTypes.size()]);
}
public void setMimeTypes(String[] types)
{
_mimeTypes.clear();
_mimeTypes.addAll(Arrays.asList(types));
}
public boolean isExcludeMimeTypes()
{
return _excludeMimeTypes;
_excludedPaths.clear();
addExcludedPaths(pathspecs);
}
public String[] getExcludedPathPatterns()
/* ------------------------------------------------------------ */
public void setIncludedMethods(String... methods)
{
Pattern[] ps = _excludedPathPatterns.toArray(new Pattern[_excludedPathPatterns.size()]);
String[] s = new String[ps.length];
int i=0;
for (Pattern p: ps)
s[i++]=p.toString();
return s;
_methods.clear();
addIncludedMethods(methods);
}
public void setExcludedPathPatterns(String[] patterns)
{
_excludedPathPatterns.clear();
for (String s : patterns)
_excludedPathPatterns.add(Pattern.compile(s));
}
public String[] getExcludedAgentPatterns()
{
Pattern[] ps = _excludedAgentPatterns.toArray(new Pattern[_excludedAgentPatterns.size()]);
String[] s = new String[ps.length];
int i=0;
for (Pattern p: ps)
s[i++]=p.toString();
return s;
}
public void setExcludedAgentPatterns(String[] patterns)
{
_excludedAgentPatterns.clear();
for (String s : patterns)
_excludedAgentPatterns.add(Pattern.compile(s));
}
/* ------------------------------------------------------------ */
/**
* Set the mime types.
*
* @param mimeTypes
* the mime types to set
*/
public void setMimeTypes(String mimeTypes)
public void setIncludedMimeTypes(String... types)
{
if (mimeTypes != null)
{
_excludeMimeTypes=false;
_mimeTypes.clear();
StringTokenizer tok = new StringTokenizer(mimeTypes,",",false);
while (tok.hasMoreTokens())
{
_mimeTypes.add(tok.nextToken());
}
}
_includedMimeTypes.clear();
addIncludedMimeTypes(types);
}
/* ------------------------------------------------------------ */
public void setIncludedPaths(String... pathspecs)
{
_includedPaths.clear();
addIncludedPaths(pathspecs);
}
/* ------------------------------------------------------------ */

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.nio.ByteBuffer;
import java.nio.channels.WritePendingException;
@ -31,7 +31,6 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.servlets.GzipFilter;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IteratingNestedCallback;
@ -155,7 +154,7 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
if (ct!=null)
{
ct=MimeTypes.getContentTypeWithoutCharset(ct);
if (_factory.isExcludedMimeType(StringUtil.asciiToLowerCase(ct)))
if (!_factory.isMimeTypeGzipable(StringUtil.asciiToLowerCase(ct)))
{
LOG.debug("{} exclude by mimeType {}",this,ct);
noCompression();
@ -204,7 +203,7 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
_channel.getResponse().setContentLength(-1);
String etag=fields.get(HttpHeader.ETAG);
if (etag!=null)
fields.put(HttpHeader.ETAG,etag.substring(0,etag.length()-1)+GzipFilter.ETAG_GZIP+ '"');
fields.put(HttpHeader.ETAG,etag.substring(0,etag.length()-1)+GzipHandler.ETAG_GZIP+ '"');
LOG.debug("{} compressing {}",this,_deflater);
_state.set(GZState.COMPRESSING);

View File

@ -17,7 +17,7 @@
//
/**
* Jetty Servlets : GZIP Filter Classes
* Jetty GZIP Handler
*/
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;

View File

@ -772,8 +772,8 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
if (ifnm!=null && content.getETagValue()!=null)
{
// Look for GzipFiltered version of etag
if (content.getETagValue().equals(request.getAttribute("o.e.j.s.GzipFilter.ETag")))
// Look for Gzip'd version of etag
if (content.getETagValue().equals(request.getAttribute("o.e.j.s.Gzip.ETag")))
{
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
response.setHeader(HttpHeader.ETAG.asString(),ifnm);

View File

@ -57,6 +57,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.BaseHolder.Source;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
@ -80,6 +81,7 @@ public class ServletContextHandler extends ContextHandler
{
public final static int SESSIONS=1;
public final static int SECURITY=2;
public final static int GZIP=4;
public final static int NO_SESSIONS=0;
public final static int NO_SECURITY=0;
@ -90,6 +92,7 @@ public class ServletContextHandler extends ContextHandler
protected SessionHandler _sessionHandler;
protected SecurityHandler _securityHandler;
protected ServletHandler _servletHandler;
protected GzipHandler _gzipHandler;
protected int _options;
protected JspConfigDescriptor _jspConfig;
@ -135,6 +138,7 @@ public class ServletContextHandler extends ContextHandler
this(parent,contextPath,sessionHandler,securityHandler,servletHandler,errorHandler,0);
}
/* ------------------------------------------------------------ */
public ServletContextHandler(HandlerContainer parent, String contextPath, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler,int options)
{
super((ContextHandler.Context)null);
@ -166,43 +170,82 @@ public class ServletContextHandler extends ContextHandler
{
HandlerWrapper handler=this;
// Skip any injected handlers
while (handler.getHandler() instanceof HandlerWrapper)
{
HandlerWrapper wrapper = (HandlerWrapper)handler.getHandler();
if (wrapper instanceof SessionHandler ||
wrapper instanceof SecurityHandler ||
wrapper instanceof ServletHandler)
break;
handler=wrapper;
}
// link session handler
if (getSessionHandler()!=null)
{
if (handler==this)
super.setHandler(_sessionHandler);
else
handler.setHandler(_sessionHandler);
while (!(handler.getHandler() instanceof SessionHandler) &&
!(handler.getHandler() instanceof SecurityHandler) &&
!(handler.getHandler() instanceof GzipHandler) &&
!(handler.getHandler() instanceof ServletHandler) &&
handler.getHandler() instanceof HandlerWrapper)
handler=(HandlerWrapper)handler.getHandler();
if (handler.getHandler()!=_sessionHandler)
{
if (handler== this)
super.setHandler(_sessionHandler);
else
handler.setHandler(_sessionHandler);
}
handler=_sessionHandler;
}
// link security handler
if (getSecurityHandler()!=null)
{
if (handler==this)
super.setHandler(_securityHandler);
else
handler.setHandler(_securityHandler);
while (!(handler.getHandler() instanceof SecurityHandler) &&
!(handler.getHandler() instanceof GzipHandler) &&
!(handler.getHandler() instanceof ServletHandler) &&
handler.getHandler() instanceof HandlerWrapper)
handler=(HandlerWrapper)handler.getHandler();
if (handler.getHandler()!=_securityHandler)
{
if (handler== this)
super.setHandler(_securityHandler);
else
handler.setHandler(_securityHandler);
}
handler=_securityHandler;
}
// link gzip handler
if (getGzipHandler()!=null)
{
while (!(handler.getHandler() instanceof GzipHandler) &&
!(handler.getHandler() instanceof ServletHandler) &&
handler.getHandler() instanceof HandlerWrapper)
handler=(HandlerWrapper)handler.getHandler();
if (handler.getHandler()!=_gzipHandler)
{
if (handler== this)
super.setHandler(_gzipHandler);
else
handler.setHandler(_gzipHandler);
}
handler=_gzipHandler;
}
// link servlet handler
if (getServletHandler()!=null)
{
if (handler==this)
super.setHandler(_servletHandler);
else
handler.setHandler(_servletHandler);
while (!(handler.getHandler() instanceof ServletHandler) &&
handler.getHandler() instanceof HandlerWrapper)
handler=(HandlerWrapper)handler.getHandler();
if (handler.getHandler()!=_servletHandler)
{
if (handler== this)
super.setHandler(_servletHandler);
else
handler.setHandler(_servletHandler);
}
handler=_servletHandler;
}
}
}
/* ------------------------------------------------------------ */
@ -335,6 +378,18 @@ public class ServletContextHandler extends ContextHandler
return _sessionHandler;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the gzipHandler.
*/
@ManagedAttribute(value="context gzip handler", readonly=true)
public GzipHandler getGzipHandler()
{
if (_gzipHandler==null && (_options&GZIP)!=0 && !isStarted())
_gzipHandler=new GzipHandler();
return _gzipHandler;
}
/* ------------------------------------------------------------ */
/** conveniance method to add a servlet.
*/
@ -457,6 +512,23 @@ public class ServletContextHandler extends ContextHandler
super.callContextDestroyed(l, e);
}
private boolean replaceHandler(Handler handler,Handler replace)
{
HandlerWrapper wrapper=this;
while(true)
{
if (wrapper.getHandler()==handler)
{
wrapper.setHandler(replace);
return true;
}
if (!(wrapper.getHandler() instanceof HandlerWrapper))
return false;
wrapper = (HandlerWrapper)wrapper.getHandler();
}
}
/* ------------------------------------------------------------ */
/**
* @param sessionHandler The sessionHandler to set.
@ -466,10 +538,17 @@ public class ServletContextHandler extends ContextHandler
if (isStarted())
throw new IllegalStateException("STARTED");
Handler next=null;
if (_sessionHandler!=null)
{
next=_sessionHandler.getHandler();
_sessionHandler.setHandler(null);
replaceHandler(_sessionHandler,sessionHandler);
}
_sessionHandler = sessionHandler;
if (next!=null && _sessionHandler.getHandler()==null)
_sessionHandler.setHandler(next);
relinkHandlers();
}
@ -482,12 +561,44 @@ public class ServletContextHandler extends ContextHandler
if (isStarted())
throw new IllegalStateException("STARTED");
Handler next=null;
if (_securityHandler!=null)
{
next=_securityHandler.getHandler();
_securityHandler.setHandler(null);
replaceHandler(_securityHandler,securityHandler);
}
_securityHandler = securityHandler;
if (next!=null && _securityHandler.getHandler()==null)
_securityHandler.setHandler(next);
relinkHandlers();
}
/* ------------------------------------------------------------ */
/**
* @param gzipHandler The {@link GzipHandler} to set on this context.
*/
public void setGzipHandler(GzipHandler gzipHandler)
{
if (isStarted())
throw new IllegalStateException("STARTED");
Handler next=null;
if (_gzipHandler!=null)
{
next=_gzipHandler.getHandler();
_gzipHandler.setHandler(null);
replaceHandler(_gzipHandler,gzipHandler);
}
_gzipHandler = gzipHandler;
if (next!=null && _gzipHandler.getHandler()==null)
_gzipHandler.setHandler(next);
relinkHandlers();
}
/* ------------------------------------------------------------ */
/**
* @param servletHandler The servletHandler to set.
@ -502,29 +613,12 @@ public class ServletContextHandler extends ContextHandler
{
next=_servletHandler.getHandler();
_servletHandler.setHandler(null);
replaceHandler(_servletHandler,servletHandler);
}
_servletHandler = servletHandler;
if (next!=null && _servletHandler.getHandler()==null)
_servletHandler.setHandler(next);
relinkHandlers();
_servletHandler.setHandler(next);
}
/* ------------------------------------------------------------ */
@Override
public void setHandler(Handler handler)
{
if (handler instanceof ServletHandler)
setServletHandler((ServletHandler) handler);
else if (handler instanceof SessionHandler)
setSessionHandler((SessionHandler) handler);
else if (handler instanceof SecurityHandler)
setSecurityHandler((SecurityHandler)handler);
else if (handler == null || handler instanceof HandlerWrapper)
{
super.setHandler(handler);
relinkHandlers();
}
else
throw new IllegalArgumentException();
}

View File

@ -48,7 +48,9 @@ import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.server.session.SessionHandler;
import org.hamcrest.Matchers;
import org.junit.After;
@ -172,6 +174,55 @@ public class ServletContextHandlerTest
response = _connector.getResponses(request.toString());
assertResponseContains("Hello World", response);
}
@Test
public void testHandlerBeforeServletHandler() throws Exception
{
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
HandlerWrapper extra = new HandlerWrapper();
context.getSessionHandler().insertHandler(extra);
context.addServlet(TestServlet.class,"/test");
context.setContextPath("/");
_server.setHandler(context);
_server.start();
StringBuffer request = new StringBuffer();
request.append("GET /test HTTP/1.0\n");
request.append("Host: localhost\n");
request.append("\n");
String response = _connector.getResponses(request.toString());
assertResponseContains("Test", response);
assertEquals(extra,context.getSessionHandler().getHandler());
}
@Test
public void testGzipHandlerOption() throws Exception
{
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS|ServletContextHandler.GZIP);
GzipHandler gzip = context.getGzipHandler();
_server.start();
assertEquals(context.getSessionHandler(),context.getHandler());
assertEquals(gzip,context.getSessionHandler().getHandler());
assertEquals(context.getServletHandler(),gzip.getHandler());
}
@Test
public void testGzipHandlerSet() throws Exception
{
ServletContextHandler context = new ServletContextHandler();
context.setSessionHandler(new SessionHandler());
context.setGzipHandler(new GzipHandler());
GzipHandler gzip = context.getGzipHandler();
_server.start();
assertEquals(context.getSessionHandler(),context.getHandler());
assertEquals(gzip,context.getSessionHandler().getHandler());
assertEquals(context.getServletHandler(),gzip.getHandler());
}
@Test
public void testReplaceServletHandlerWithServlet() throws Exception
@ -268,7 +319,7 @@ public class ServletContextHandlerTest
ResourceHandler rh = new ResourceHandler();
servletContextHandler.setHandler(rh);
servletContextHandler.insertHandler(rh);
assertEquals(shandler, servletContextHandler.getServletHandler());
assertEquals(rh, servletContextHandler.getHandler());
assertEquals(rh.getHandler(), shandler);

View File

@ -18,483 +18,36 @@
package org.eclipse.jetty.servlets;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import java.util.zip.Deflater;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.servlets.gzip.GzipFactory;
import org.eclipse.jetty.servlets.gzip.GzipHttpOutputInterceptor;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */
/** Async GZIP Filter
* This filter is a gzip filter using jetty internal mechanism to apply gzip compression
* to output that is compatible with async IO and does not need to wrap the response nor output stream.
* The filter will gzip the content of a response if: <ul>
* <li>The filter is mapped to a matching path</li>
* <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>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>
*
* <p>
* Compressing the content can greatly improve the network bandwidth usage, but at a cost of memory and
* CPU cycles. If this filter is mapped for static content, then use of efficient direct NIO may be
* prevented, thus use of the gzip mechanism of the {@link org.eclipse.jetty.servlet.DefaultServlet} is
* advised instead.
* </p>
* <p>
* This filter extends {@link UserAgentFilter} and if the the initParameter <code>excludedAgents</code>
* is set to a comma separated list of user agents, then these agents will be excluded from gzip content.
* </p>
* <p>Init Parameters:</p>
* <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)}
* </dd>
* <dt>minGzipSize</dt> <dd>Content will only be compressed if content length is either unknown or greater
* than <code>minGzipSize</code>.
* </dd>
* <dt>deflateCompressionLevel</dt> <dd>The compression level used for deflate compression. (0-9).
* See: {@link java.util.zip.Deflater#Deflater(int, boolean)}
* </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
* </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.
* </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.
* </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>
/**
*/
@Deprecated
public class GzipFilter extends UserAgentFilter implements GzipFactory
public class GzipFilter implements Filter
{
private static final Logger LOG = Log.getLogger(GzipFilter.class);
public final static String GZIP = "gzip";
public static final String DEFLATE = "deflate";
public final static String ETAG_GZIP="--gzip";
public final static String ETAG = "o.e.j.s.GzipFilter.ETag";
public final static int DEFAULT_MIN_GZIP_SIZE=256;
protected ServletContext _context;
protected final Set<String> _mimeTypes=new HashSet<>();
protected boolean _excludeMimeTypes;
protected int _bufferSize=32*1024;
protected int _minGzipSize=DEFAULT_MIN_GZIP_SIZE;
protected int _deflateCompressionLevel=Deflater.DEFAULT_COMPRESSION;
protected boolean _checkGzExists = true;
// non-static, as other GzipFilter instances may have different configurations
protected final ThreadLocal<Deflater> _deflater = new ThreadLocal<Deflater>();
protected final static ThreadLocal<byte[]> _buffer= new ThreadLocal<byte[]>();
protected final Set<String> _methods=new HashSet<String>();
protected Set<String> _excludedAgents;
protected Set<Pattern> _excludedAgentPatterns;
protected Set<String> _excludedPaths;
protected Set<Pattern> _excludedPathPatterns;
protected HttpField _vary=GzipHttpOutputInterceptor.VARY;
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#init(javax.servlet.FilterConfig)
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
super.init(filterConfig);
_context=filterConfig.getServletContext();
String tmp=filterConfig.getInitParameter("bufferSize");
if (tmp!=null)
_bufferSize=Integer.parseInt(tmp);
LOG.debug("{} bufferSize={}",this,_bufferSize);
tmp=filterConfig.getInitParameter("minGzipSize");
if (tmp!=null)
_minGzipSize=Integer.parseInt(tmp);
LOG.debug("{} minGzipSize={}",this,_minGzipSize);
tmp=filterConfig.getInitParameter("deflateCompressionLevel");
if (tmp!=null)
_deflateCompressionLevel=Integer.parseInt(tmp);
LOG.debug("{} deflateCompressionLevel={}",this,_deflateCompressionLevel);
tmp=filterConfig.getInitParameter("checkGzExists");
if (tmp!=null)
_checkGzExists=Boolean.parseBoolean(tmp);
LOG.debug("{} checkGzExists={}",this,_checkGzExists);
tmp=filterConfig.getInitParameter("methods");
if (tmp!=null)
{
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_methods.add(tok.nextToken().trim().toUpperCase(Locale.ENGLISH));
}
else
_methods.add(HttpMethod.GET.asString());
LOG.debug("{} methods={}",this,_methods);
tmp=filterConfig.getInitParameter("mimeTypes");
if (tmp==null)
{
_excludeMimeTypes=true;
tmp=filterConfig.getInitParameter("excludedMimeTypes");
if (tmp==null)
{
for (String type:MimeTypes.getKnownMimeTypes())
{
if (type.equals("image/svg+xml")) //always compressable (unless .svgz file)
continue;
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().trim());
}
}
else
{
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_mimeTypes.add(tok.nextToken().trim());
}
LOG.debug("{} mimeTypes={}",this,_mimeTypes);
LOG.debug("{} excludeMimeTypes={}",this,_excludeMimeTypes);
tmp=filterConfig.getInitParameter("excludedAgents");
if (tmp!=null)
{
_excludedAgents=new HashSet<String>();
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_excludedAgents.add(tok.nextToken().trim());
}
LOG.debug("{} excludedAgents={}",this,_excludedAgents);
tmp=filterConfig.getInitParameter("excludeAgentPatterns");
if (tmp!=null)
{
_excludedAgentPatterns=new HashSet<Pattern>();
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_excludedAgentPatterns.add(Pattern.compile(tok.nextToken().trim()));
}
LOG.debug("{} excludedAgentPatterns={}",this,_excludedAgentPatterns);
tmp=filterConfig.getInitParameter("excludePaths");
if (tmp!=null)
{
_excludedPaths=new HashSet<String>();
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_excludedPaths.add(tok.nextToken().trim());
}
LOG.debug("{} excludedPaths={}",this,_excludedPaths);
tmp=filterConfig.getInitParameter("excludePathPatterns");
if (tmp!=null)
{
_excludedPathPatterns=new HashSet<Pattern>();
StringTokenizer tok = new StringTokenizer(tmp,",",false);
while (tok.hasMoreTokens())
_excludedPathPatterns.add(Pattern.compile(tok.nextToken().trim()));
}
LOG.debug("{} excludedPathPatterns={}",this,_excludedPathPatterns);
tmp=filterConfig.getInitParameter("vary");
if (tmp!=null)
_vary=new PreEncodedHttpField(HttpHeader.VARY,tmp);
LOG.debug("{} vary={}",this,_vary);
{
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#destroy()
*/
@Override
public void destroy()
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.servlets.UserAgentFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
{
LOG.debug("{} doFilter {}",this,req);
HttpServletRequest request=(HttpServletRequest)req;
HttpServletResponse response=(HttpServletResponse)res;
// If not a supported method or it is an Excluded URI or an excluded UA - no Vary because no matter what client, this URI is always excluded
String requestURI = request.getRequestURI();
if (!_methods.contains(request.getMethod()))
{
LOG.debug("{} excluded by method {}",this,request);
super.doFilter(request,response,chain);
return;
}
if (isExcludedPath(requestURI))
{
LOG.debug("{} excluded by path {}",this,request);
super.doFilter(request,response,chain);
return;
}
// Exclude non compressible mime-types known from URI extension. - no Vary because no matter what client, this URI is always excluded
if (_mimeTypes.size()>0 && _excludeMimeTypes)
{
String mimeType = _context.getMimeType(request.getRequestURI());
if (mimeType!=null)
{
mimeType = MimeTypes.getContentTypeWithoutCharset(mimeType);
if (_mimeTypes.contains(mimeType))
{
LOG.debug("{} excluded by path suffix {}",this,request);
// handle normally without setting vary header
super.doFilter(request,response,chain);
return;
}
}
}
//If the Content-Encoding is already set, then we won't compress
if (response.getHeader("Content-Encoding") != null)
{
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())
{
LOG.debug("{} gzip exists {}",this,request);
// allow default servlet to handle
super.doFilter(request,response,chain);
return;
}
}
}
// Special handling for etags
String etag = request.getHeader("If-None-Match");
if (etag!=null)
{
if (etag.contains(ETAG_GZIP))
request.setAttribute(ETAG,etag.replace(ETAG_GZIP,""));
}
HttpChannel channel = HttpChannel.getCurrentHttpChannel();
HttpOutput out = channel.getResponse().getHttpOutput();
// TODO recycle the GzipHttpOutputFilter
out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,channel,out.getFilter()));
super.doFilter(request,response,chain);
}
/**
* Checks to see if the userAgent is excluded
*
* @param ua
* the user agent
* @return boolean true if excluded
*/
private boolean isExcludedAgent(String ua)
{
if (ua == null)
return false;
if (_excludedAgents != null)
{
if (_excludedAgents.contains(ua))
{
return true;
}
}
if (_excludedAgentPatterns != null)
{
for (Pattern pattern : _excludedAgentPatterns)
{
if (pattern.matcher(ua).matches())
{
return true;
}
}
}
return false;
}
/**
* Checks to see if the path is excluded
*
* @param requestURI
* the request uri
* @return boolean true if excluded
*/
private boolean isExcludedPath(String requestURI)
{
if (requestURI == null)
return false;
if (_excludedPaths != null)
{
for (String excludedPath : _excludedPaths)
{
if (requestURI.startsWith(excludedPath))
{
return true;
}
}
}
if (_excludedPathPatterns != null)
{
for (Pattern pattern : _excludedPathPatterns)
{
if (pattern.matcher(requestURI).matches())
{
return true;
}
}
}
return false;
chain.doFilter(request,response);
}
@Override
public Deflater getDeflater(Request request, long content_length)
{
String ua = getUserAgent(request);
if (ua!=null && isExcludedAgent(ua))
{
LOG.debug("{} excluded user agent {}",this,request);
return null;
}
if (content_length>=0 && content_length<_minGzipSize)
{
LOG.debug("{} excluded minGzipSize {}",this,request);
return null;
}
// If not HTTP/2, then we must check the accept encoding header
if (request.getHttpVersion()!=HttpVersion.HTTP_2)
{
HttpField accept = request.getHttpFields().getField(HttpHeader.ACCEPT_ENCODING);
if (accept==null)
{
LOG.debug("{} excluded !accept {}",this,request);
return null;
}
boolean gzip = accept.contains("gzip");
if (!gzip)
{
LOG.debug("{} excluded not gzip accept {}",this,request);
return null;
}
}
Deflater df = _deflater.get();
if (df==null)
df=new Deflater(_deflateCompressionLevel,true);
else
_deflater.set(null);
return df;
public void destroy()
{
}
@Override
public void recycle(Deflater deflater)
{
deflater.reset();
if (_deflater.get()==null)
_deflater.set(deflater);
}
@Override
public boolean isExcludedMimeType(String mimetype)
{
return _mimeTypes.contains(mimetype) == _excludeMimeTypes;
}
}

View File

@ -1,159 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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.servlets;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/* ------------------------------------------------------------ */
/** User Agent Filter.
* <p>
* This filter allows efficient matching of user agent strings for
* downstream or extended filters to use for browser specific logic.
* </p>
* <p>
* The filter is configured with the following init parameters:
* <dl>
* <dt>attribute</dt><dd>If set, then the request attribute of this name is set with the matched user agent string</dd>
* <dt>cacheSize</dt><dd>The size of the user-agent cache, used to avoid reparsing of user agent strings. The entire cache is flushed
* when this size is reached</dd>
* <dt>userAgent</dt><dd>A regex {@link Pattern} to extract the essential elements of the user agent.
* The concatenation of matched pattern groups is used as the user agent name</dd>
* <dl>
* An example value for pattern is <code>(?:Mozilla[^\(]*\(compatible;\s*+([^;]*);.*)|(?:.*?([^\s]+/[^\s]+).*)</code>. These two
* pattern match the common compatibility user-agent strings and extract the real user agent, failing that, the first
* element of the agent string is returned.
*
*
*/
@Deprecated
public class UserAgentFilter implements Filter
{
private static final String __defaultPattern = "(?:Mozilla[^\\(]*\\(compatible;\\s*+([^;]*);.*)|(?:.*?([^\\s]+/[^\\s]+).*)";
private Pattern _pattern = Pattern.compile(__defaultPattern);
private Map<String, String> _agentCache = new ConcurrentHashMap<String, String>();
private int _agentCacheSize=1024;
private String _attribute;
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see javax.servlet.Filter#destroy()
*/
public void destroy()
{
}
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
if (_attribute!=null && _pattern!=null)
{
String ua=getUserAgent(request);
request.setAttribute(_attribute,ua);
}
chain.doFilter(request,response);
}
/* ------------------------------------------------------------ */
/* (non-Javadoc)
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
public void init(FilterConfig filterConfig) throws ServletException
{
_attribute=filterConfig.getInitParameter("attribute");
String p=filterConfig.getInitParameter("userAgent");
if (p!=null)
_pattern=Pattern.compile(p);
String size=filterConfig.getInitParameter("cacheSize");
if (size!=null)
_agentCacheSize=Integer.parseInt(size);
}
/* ------------------------------------------------------------ */
public String getUserAgent(ServletRequest request)
{
String ua=((HttpServletRequest)request).getHeader("User-Agent");
return getUserAgent(ua);
}
/* ------------------------------------------------------------ */
/** Get UserAgent.
* The configured agent patterns are used to match against the passed user agent string.
* If any patterns match, the concatenation of pattern groups is returned as the user agent
* string. Match results are cached.
* @param ua A user agent string
* @return The matched pattern groups or the original user agent string
*/
public String getUserAgent(String ua)
{
if (ua == null)
return null;
String tag = _agentCache.get(ua);
if (tag == null)
{
if (_pattern != null)
{
Matcher matcher = _pattern.matcher(ua);
if (matcher.matches())
{
if (matcher.groupCount() > 0)
{
for (int g = 1; g <= matcher.groupCount(); g++)
{
String group = matcher.group(g);
if (group != null)
tag = tag == null ? group : tag + group;
}
}
else
{
tag = matcher.group();
}
}
}
if (tag == null)
tag = ua;
if (_agentCache.size() >= _agentCacheSize)
_agentCache.clear();
_agentCache.put(ua, tag);
}
return tag;
}
}

View File

@ -16,28 +16,17 @@
// ========================================================================
//
package org.eclipse.jetty.servlets;
package org.eclipse.jetty.server.handler.gzip;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.gzip.GzipTester;
import org.eclipse.jetty.servlets.gzip.TestServletBufferTypeLengthWrite;
import org.eclipse.jetty.servlets.gzip.TestServletLengthStreamTypeWrite;
import org.eclipse.jetty.servlets.gzip.TestServletLengthTypeStreamWrite;
import org.eclipse.jetty.servlets.gzip.TestServletStreamLengthTypeWrite;
import org.eclipse.jetty.servlets.gzip.TestServletStreamLengthTypeWriteWithFlush;
import org.eclipse.jetty.servlets.gzip.TestServletStreamTypeLengthWrite;
import org.eclipse.jetty.servlets.gzip.TestServletTypeLengthStreamWrite;
import org.eclipse.jetty.servlets.gzip.TestServletTypeStreamLengthWrite;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.hamcrest.Matchers;
import org.junit.Assert;
@ -50,12 +39,12 @@ import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Test the GzipFilter support for Content-Length setting variations.
* Test the GzipHandler support for Content-Length setting variations.
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@RunWith(Parameterized.class)
public class GzipFilterContentLengthTest
public class GzipContentLengthTest
{
@Rule
@ -90,22 +79,22 @@ public class GzipFilterContentLengthTest
{
return Arrays.asList(new Object[][]
{
{ GzipFilter.class, TestServletLengthStreamTypeWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletLengthTypeStreamWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletStreamLengthTypeWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletStreamLengthTypeWriteWithFlush.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletStreamTypeLengthWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletTypeLengthStreamWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletTypeStreamLengthWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletBufferTypeLengthWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletLengthStreamTypeWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletLengthTypeStreamWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletStreamLengthTypeWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletStreamLengthTypeWriteWithFlush.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletStreamTypeLengthWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletTypeLengthStreamWrite.class, GzipFilter.GZIP },
{ GzipFilter.class, TestServletTypeStreamLengthWrite.class, GzipFilter.GZIP },
{ TestServletLengthStreamTypeWrite.class},
{ TestServletLengthTypeStreamWrite.class},
{ TestServletStreamLengthTypeWrite.class},
{ TestServletStreamLengthTypeWriteWithFlush.class },
{ TestServletStreamTypeLengthWrite.class},
{ TestServletTypeLengthStreamWrite.class},
{ TestServletTypeStreamLengthWrite.class},
{ TestServletBufferTypeLengthWrite.class},
{ TestServletLengthStreamTypeWrite.class},
{ TestServletLengthTypeStreamWrite.class},
{ TestServletStreamLengthTypeWrite.class},
{ TestServletStreamLengthTypeWriteWithFlush.class},
{ TestServletStreamTypeLengthWrite.class},
{ TestServletTypeLengthStreamWrite.class},
{ TestServletTypeStreamLengthWrite.class},
});
}
@ -114,32 +103,28 @@ public class GzipFilterContentLengthTest
private static final int LARGE = defaultHttp.getOutputBufferSize() * 8;
private static final int MEDIUM = defaultHttp.getOutputBufferSize();
private static final int SMALL = defaultHttp.getOutputBufferSize() / 4;
private static final int TINY = GzipFilter.DEFAULT_MIN_GZIP_SIZE / 2;
private static final int TINY = GzipHandler.DEFAULT_MIN_GZIP_SIZE / 2;
private String compressionType;
public GzipFilterContentLengthTest(Class<? extends Filter> testFilter,Class<? extends Servlet> testServlet, String compressionType)
public GzipContentLengthTest(Class<? extends Servlet> testServlet)
{
this.testFilter = testFilter;
this.testServlet = testServlet;
this.compressionType = compressionType;
this.compressionType = GzipHandler.GZIP;
}
@Rule
public TestingDir testingdir = new TestingDir();
private Class<? extends Filter> testFilter;
private Class<? extends Servlet> testServlet;
private void assertIsGzipCompressed(String filename, int filesize) throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
File testfile = tester.prepareServerFile(testServlet.getSimpleName() + "-" + filename,filesize);
FilterHolder holder = tester.setContentServlet(testServlet);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(testServlet);
try
{
@ -155,12 +140,10 @@ public class GzipFilterContentLengthTest
private void assertIsNotGzipCompressed(String filename, int filesize) throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
File testfile = tester.prepareServerFile(testServlet.getSimpleName() + "-" + filename,filesize);
FilterHolder holder = tester.setContentServlet(testServlet);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(testServlet);
try
{
@ -212,7 +195,7 @@ public class GzipFilterContentLengthTest
/**
* Tests for problems with Content-Length header on small size files
* that are not being compressed encountered when using GzipFilter
* that are not being compressed encountered when using GzipHandler
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@ -224,7 +207,7 @@ public class GzipFilterContentLengthTest
/**
* Tests for problems with Content-Length header on small size files
* that are not being compressed encountered when using GzipFilter
* that are not being compressed encountered when using GzipHandler
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@ -236,7 +219,7 @@ public class GzipFilterContentLengthTest
/**
* Tests for problems with Content-Length header on medium size files
* that are not being compressed encountered when using GzipFilter
* that are not being compressed encountered when using GzipHandler
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/
@ -248,7 +231,7 @@ public class GzipFilterContentLengthTest
/**
* Tests for problems with Content-Length header on large size files
* that were not being compressed encountered when using GzipFilter
* that were not being compressed encountered when using GzipHandler
*
* @see <a href="Eclipse Bug 354014">http://bugs.eclipse.org/354014</a>
*/

View File

@ -0,0 +1,110 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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.server.handler.gzip;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests {@link GzipHandler} in combination with {@link DefaultServlet} for ability to configure {@link GzipHandler} to
* ignore recompress situations from upstream.
*/
@RunWith(Parameterized.class)
public class GzipDefaultNoRecompressTest
{
@Parameters
public static List<Object[]> data()
{
return Arrays.asList(new Object[][]
{
// Some already compressed files
{ "test_quotes.gz", "application/gzip" , GzipHandler.GZIP },
{ "test_quotes.bz2", "application/bzip2", GzipHandler.GZIP },
{ "test_quotes.zip", "application/zip" , GzipHandler.GZIP },
{ "test_quotes.rar", "application/x-rar-compressed", GzipHandler.GZIP },
// Some images (common first)
{ "jetty_logo.png", "image/png", GzipHandler.GZIP},
{ "jetty_logo.gif", "image/gif", GzipHandler.GZIP},
{ "jetty_logo.jpeg", "image/jpeg", GzipHandler.GZIP},
{ "jetty_logo.jpg", "image/jpeg", GzipHandler.GZIP},
// Lesser encountered images (usually found being requested from non-browser clients)
{ "jetty_logo.bmp", "image/bmp", GzipHandler.GZIP },
{ "jetty_logo.tif", "image/tiff", GzipHandler.GZIP },
{ "jetty_logo.tiff", "image/tiff", GzipHandler.GZIP },
{ "jetty_logo.xcf", "image/xcf", GzipHandler.GZIP },
{ "jetty_logo.jp2", "image/jpeg2000", GzipHandler.GZIP },
//qvalue disables compression
{ "test_quotes.txt", "text/plain", GzipHandler.GZIP+";q=0"},
{ "test_quotes.txt", "text/plain", GzipHandler.GZIP+"; q = 0 "},
});
}
@Rule
public TestingDir testingdir = new TestingDir();
private String alreadyCompressedFilename;
private String expectedContentType;
private String compressionType;
public GzipDefaultNoRecompressTest(String testFilename, String expectedContentType, String compressionType)
{
this.alreadyCompressedFilename = testFilename;
this.expectedContentType = expectedContentType;
this.compressionType = compressionType;
}
@Test
public void testNotGzipHandlered_Default_AlreadyCompressed() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
copyTestFileToServer(alreadyCompressedFilename);
tester.setContentServlet(TestStaticMimeTypeServlet.class);
try
{
tester.start();
tester.assertIsResponseNotGziped(alreadyCompressedFilename,alreadyCompressedFilename + ".sha1",expectedContentType);
}
finally
{
tester.stop();
}
}
private void copyTestFileToServer(String testFilename) throws IOException
{
File testFile = MavenTestingUtils.getTestResourceFile(testFilename);
File outFile = testingdir.getFile(testFilename);
IO.copy(testFile,outFile);
}
}

View File

@ -16,11 +16,10 @@
// ========================================================================
//
package org.eclipse.jetty.servlets;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
@ -30,25 +29,21 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.gzip.GzipTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
/**
* Test the GzipFilter support built into the {@link DefaultServlet}
* Test the GzipHandler support built into the {@link DefaultServlet}
*/
public class GzipFilterDefaultTest
public class GzipDefaultTest
{
private Class<? extends Filter> testFilter;
private String compressionType;
public GzipFilterDefaultTest()
public GzipDefaultTest()
{
this.testFilter=GzipFilter.class;
this.compressionType = GzipFilter.GZIP;
this.compressionType = GzipHandler.GZIP;
}
public static class HttpStatusServlet extends HttpServlet
@ -115,14 +110,12 @@ public class GzipFilterDefaultTest
public void testIsGzipByMethod() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() * 2;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(GetServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
holder.setInitParameter("methods","POST, WIBBLE");
tester.setContentServlet(GetServlet.class);
tester.getGzipHandler().setIncludedMethods("POST","WIBBLE");
try
{
@ -164,17 +157,15 @@ public class GzipFilterDefaultTest
public void testIsGzipCompressedEmpty() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
tester.prepareServerFile("empty.txt",0);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
try
{
tester.start();
HttpTester.Response http = tester.assertIsResponseNotGzipCompressed("GET","empty.txt",0,200);
tester.assertIsResponseNotGzipCompressed("GET","empty.txt",0,200);
}
finally
{
@ -186,19 +177,17 @@ public class GzipFilterDefaultTest
public void testIsGzipCompressedTiny() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() / 4;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
try
{
tester.start();
HttpTester.Response http = tester.assertIsResponseGzipCompressed("GET","file.txt");
Assert.assertEquals("Accept-Encoding",http.get("Vary"));
Assert.assertEquals("Accept-Encoding, User-Agent",http.get("Vary"));
}
finally
{
@ -210,13 +199,12 @@ public class GzipFilterDefaultTest
public void testIsGzipCompressedLarge() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
tester.getGzipHandler().setVary("Accept-Encoding");
try
{
@ -235,19 +223,17 @@ public class GzipFilterDefaultTest
public void testGzipedIfModified() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
try
{
tester.start();
HttpTester.Response http = tester.assertIsResponseGzipCompressed("GET","file.txt",System.currentTimeMillis()-4000);
Assert.assertEquals("Accept-Encoding",http.get("Vary"));
Assert.assertEquals("Accept-Encoding, User-Agent",http.get("Vary"));
}
finally
{
@ -259,14 +245,16 @@ public class GzipFilterDefaultTest
public void testGzippedIfSVG() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
tester.copyTestServerFile("test.svg");
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
tester.getGzipHandler().addIncludedMimeTypes("image/svg+xml");
try
{
tester.start();
HttpTester.Response http = tester.assertIsResponseGzipCompressed("GET","test.svg",System.currentTimeMillis()-4000);
Assert.assertEquals("Accept-Encoding",http.get("Vary"));
Assert.assertEquals("Accept-Encoding, User-Agent",http.get("Vary"));
}
finally
{
@ -278,14 +266,11 @@ public class GzipFilterDefaultTest
public void testNotGzipedIfNotModified() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
holder.setInitParameter("etags","true");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
try
{
@ -303,19 +288,17 @@ public class GzipFilterDefaultTest
public void testIsNotGzipCompressedWithZeroQ() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType+"; q=0");
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() / 4;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
try
{
tester.start();
HttpTester.Response http = tester.assertIsResponseNotGzipCompressed("GET","file.txt", filesize, HttpStatus.OK_200);
Assert.assertEquals("Accept-Encoding",http.get("Vary"));
Assert.assertEquals("Accept-Encoding, User-Agent",http.get("Vary"));
}
finally
{
@ -327,13 +310,12 @@ public class GzipFilterDefaultTest
public void testIsGzipCompressedWithQ() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType,"something;q=0.1,"+compressionType+";q=0.5");
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() / 4;
tester.prepareServerFile("file.txt",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
tester.getGzipHandler().setVary("Accept-Encoding");
try
{
@ -351,13 +333,11 @@ public class GzipFilterDefaultTest
public void testIsNotGzipCompressedByContentType() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("file.mp3",filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
try
{
@ -376,14 +356,12 @@ public class GzipFilterDefaultTest
public void testIsNotGzipCompressedByExcludedContentType() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("test_quotes.txt", filesize);
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("excludedMimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
tester.getGzipHandler().setExcludedMimeTypes("text/plain");
try
{
@ -402,14 +380,13 @@ public class GzipFilterDefaultTest
public void testIsNotGzipCompressedByExcludedContentTypeWithCharset() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("test_quotes.txt", filesize);
tester.addMimeType("txt","text/plain;charset=UTF-8");
FilterHolder holder = tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
holder.setInitParameter("excludedMimeTypes","text/plain");
tester.setContentServlet(org.eclipse.jetty.servlet.DefaultServlet.class);
tester.getGzipHandler().addExcludedMimeTypes("text/plain");
try
{
@ -429,9 +406,9 @@ public class GzipFilterDefaultTest
public void testGzipCompressedByContentTypeWithEncoding() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
FilterHolder holder = tester.setContentServlet(HttpContentTypeWithEncoding.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(HttpContentTypeWithEncoding.class);
tester.getGzipHandler().addIncludedMimeTypes("text/plain");
tester.getGzipHandler().setVary("Accept-Encoding");
try
{
tester.start();
@ -449,13 +426,11 @@ public class GzipFilterDefaultTest
public void testIsNotGzipCompressedByDeferredContentType() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("file.mp3.deferred",filesize);
FilterHolder holder = tester.setContentServlet(GetServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(GetServlet.class);
try
{
@ -473,11 +448,9 @@ public class GzipFilterDefaultTest
public void testIsNotGzipCompressedHttpStatus() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
// Test error code 204
FilterHolder holder = tester.setContentServlet(HttpStatusServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(HttpStatusServlet.class);
try
{
@ -495,11 +468,9 @@ public class GzipFilterDefaultTest
public void testIsNotGzipCompressedHttpBadRequestStatus() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
// Test error code 400
FilterHolder holder = tester.setContentServlet(HttpErrorServlet.class);
holder.setInitParameter("mimeTypes","text/plain");
tester.setContentServlet(HttpErrorServlet.class);
try
{
@ -517,10 +488,10 @@ public class GzipFilterDefaultTest
public void testUserAgentExclusion() throws Exception
{
GzipTester tester = new GzipTester(testingdir,compressionType);
tester.setGzipFilterClass(testFilter);
FilterHolder holder = tester.setContentServlet(DefaultServlet.class);
holder.setInitParameter("excludedAgents","bar, foo");
tester.setContentServlet(DefaultServlet.class);
tester.getGzipHandler().setExcludedAgentPatterns("bar","foo");
tester.setUserAgent("foo");
int filesize = tester.getOutputBufferSize() * 4;
@ -541,11 +512,9 @@ public class GzipFilterDefaultTest
public void testUserAgentExclusionByExcludedAgentPatterns() throws Exception
{
GzipTester tester = new GzipTester(testingdir,compressionType);
tester.setGzipFilterClass(testFilter);
FilterHolder holder = tester.setContentServlet(DefaultServlet.class);
holder.setInitParameter("excludedAgents","bar");
holder.setInitParameter("excludeAgentPatterns","fo.*");
tester.setContentServlet(DefaultServlet.class);
tester.getGzipHandler().setExcludedAgentPatterns("bar","fo.*");
tester.setUserAgent("foo");
int filesize = tester.getOutputBufferSize() * 4;
@ -566,10 +535,9 @@ public class GzipFilterDefaultTest
public void testExcludePaths() throws Exception
{
GzipTester tester = new GzipTester(testingdir,compressionType);
tester.setGzipFilterClass(testFilter);
FilterHolder holder = tester.setContentServlet(DefaultServlet.class);
holder.setInitParameter("excludePaths","/bar/, /context/");
tester.setContentServlet(DefaultServlet.class);
tester.getGzipHandler().setExcludedPaths("*.txt");
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("file.txt",filesize);
@ -586,13 +554,13 @@ public class GzipFilterDefaultTest
}
@Test
public void testExcludePathPatterns() throws Exception
public void testIncludedPaths() throws Exception
{
GzipTester tester = new GzipTester(testingdir,compressionType);
tester.setGzipFilterClass(testFilter);
FilterHolder holder = tester.setContentServlet(DefaultServlet.class);
holder.setInitParameter("excludePathPatterns","/cont.*");
tester.setContentServlet(DefaultServlet.class);
tester.getGzipHandler().setExcludedPaths("*.txt");
tester.getGzipHandler().setIncludedPaths("/file.txt");
int filesize = tester.getOutputBufferSize() * 4;
tester.prepareServerFile("file.txt",filesize);
@ -600,27 +568,27 @@ public class GzipFilterDefaultTest
try
{
tester.start();
tester.assertIsResponseNotGzipCompressed("GET","file.txt",filesize,HttpStatus.OK_200);
tester.assertIsResponseGzipCompressed("GET","file.txt");
}
finally
{
tester.stop();
}
}
@Test
public void testIsNotGzipCompressedSVGZ() throws Exception
{
GzipTester tester = new GzipTester(testingdir,compressionType);
tester.setGzipFilterClass(testFilter);
FilterHolder holder = tester.setContentServlet(DefaultServlet.class);
tester.setContentServlet(DefaultServlet.class);
tester.copyTestServerFile("test.svgz");
try
{
tester.start();
tester.assertIsResponseNotGzipFiltered("test.svgz", "test.svgz.sha1", "image/svg+xml", "gzip");
tester.assertIsResponseNotGziped("test.svgz", "test.svgz.sha1", "image/svg+xml", "gzip");
}
finally
{

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
@ -35,7 +35,6 @@ import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -43,8 +42,6 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletResponse;
@ -52,10 +49,9 @@ import org.eclipse.jetty.http.DateGenerator;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlet.ServletTester;
import org.eclipse.jetty.servlets.GzipFilter;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.TestingDir;
@ -64,26 +60,32 @@ import org.junit.Assert;
public class GzipTester
{
private Class<? extends Filter> gzipFilterClass = GzipFilter.class;
private String encoding = "ISO8859_1";
private String userAgent = null;
private final ServletTester tester = new ServletTester();;
private final ServletTester tester = new ServletTester("/context",ServletContextHandler.GZIP);
private TestingDir testdir;
private String accept;
private String compressionType;
public GzipTester(TestingDir testingdir, String compressionType, String accept)
{
this.testdir = testingdir;
this.compressionType = compressionType;
this.accept=accept;
}
public GzipTester(TestingDir testingdir, String compressionType)
{
this.testdir = testingdir;
this.compressionType = compressionType;
this.accept=compressionType;
this.accept=compressionType;
}
public GzipHandler getGzipHandler()
{
return tester.getContext().getGzipHandler();
}
public int getOutputBufferSize()
@ -105,7 +107,6 @@ public class GzipTester
{
return assertIsResponseGzipCompressed(method,requestedFilename,serverFilename,-1);
}
public HttpTester.Response assertNonStaticContentIsResponseGzipCompressed(String method, String path, String expected) throws Exception
{
@ -138,11 +139,11 @@ public class GzipTester
try
{
bais = new ByteArrayInputStream(response.getContentBytes());
if (compressionType.startsWith(GzipFilter.GZIP))
if (compressionType.startsWith(GzipHandler.GZIP))
{
in = new GZIPInputStream(bais);
}
else if (compressionType.startsWith(GzipFilter.DEFLATE))
else if (compressionType.startsWith(GzipHandler.DEFLATE))
{
in = new InflaterInputStream(bais, new Inflater(true));
}
@ -217,11 +218,11 @@ public class GzipTester
try
{
bais = new ByteArrayInputStream(response.getContentBytes());
if (compressionType.startsWith(GzipFilter.GZIP))
if (compressionType.startsWith(GzipHandler.GZIP))
{
in = new GZIPInputStream(bais);
}
else if (compressionType.startsWith(GzipFilter.DEFLATE))
else if (compressionType.startsWith(GzipHandler.DEFLATE))
{
in = new InflaterInputStream(bais, new Inflater(true));
}
@ -269,10 +270,10 @@ public class GzipTester
/**
* Makes sure that the response contains an unfiltered file contents.
* <p>
* This is used to test exclusions and passthroughs in the GzipFilter.
* This is used to test exclusions and passthroughs in the GzipHandler.
* <p>
* An example is to test that it is possible to configure GzipFilter to not recompress content that shouldn't be
* compressed by the GzipFilter.
* An example is to test that it is possible to configure GzipHandler to not recompress content that shouldn't be
* compressed by the GzipHandler.
*
* @param requestedFilename
* the filename used to on the GET request,.
@ -281,18 +282,18 @@ public class GzipTester
* contents are what is intended.
* @param expectedContentType
*/
public void assertIsResponseNotGzipFiltered(String requestedFilename, String testResourceSha1Sum, String expectedContentType) throws Exception
public void assertIsResponseNotGziped(String requestedFilename, String testResourceSha1Sum, String expectedContentType) throws Exception
{
assertIsResponseNotGzipFiltered(requestedFilename, testResourceSha1Sum, expectedContentType,null);
assertIsResponseNotGziped(requestedFilename, testResourceSha1Sum, expectedContentType,null);
}
/**
* Makes sure that the response contains an unfiltered file contents.
* <p>
* This is used to test exclusions and passthroughs in the GzipFilter.
* This is used to test exclusions and passthroughs in the GzipHandler.
* <p>
* An example is to test that it is possible to configure GzipFilter to not recompress content that shouldn't be
* compressed by the GzipFilter.
* An example is to test that it is possible to configure GzipHandler to not recompress content that shouldn't be
* compressed by the GzipHandler.
*
* @param requestedFilename
* the filename used to on the GET request,.
@ -302,7 +303,7 @@ public class GzipTester
* @param expectedContentType
* @param expectedContentEncoding can be non-null in some circumstances, eg when dealing with pre-gzipped .svgz files
*/
public void assertIsResponseNotGzipFiltered(String requestedFilename, String testResourceSha1Sum, String expectedContentType, String expectedContentEncoding) throws Exception
public void assertIsResponseNotGziped(String requestedFilename, String testResourceSha1Sum, String expectedContentType, String expectedContentEncoding) throws Exception
{
//System.err.printf("[GzipTester] requesting /context/%s%n",requestedFilename);
HttpTester.Request request = HttpTester.newRequest();
@ -325,7 +326,7 @@ public class GzipTester
String prefix = requestedFilename + " / Response";
Assert.assertThat(prefix + ".status",response.getStatus(),is(HttpServletResponse.SC_OK));
Assert.assertThat(prefix + ".header[Content-Length]",response.get("Content-Length"),notNullValue());
Assert.assertThat(prefix + ".header[Content-Encoding] (should not be recompressed by GzipFilter)",response.get("Content-Encoding"),
Assert.assertThat(prefix + ".header[Content-Encoding] (should not be recompressed by GzipHandler)",response.get("Content-Encoding"),
expectedContentEncoding == null? nullValue() : notNullValue());
if (expectedContentEncoding != null)
Assert.assertThat(prefix + ".header[Content-Encoding]",response.get("Content-Encoding"),is(expectedContentEncoding));
@ -378,7 +379,7 @@ public class GzipTester
}
/**
* Asserts that the requested filename results in a properly structured GzipFilter response, where the content is
* Asserts that the requested filename results in a properly structured GzipHandler response, where the content is
* not compressed, and the content-length is returned appropriately.
*
* @param filename
@ -410,7 +411,7 @@ public class GzipTester
/**
* Asserts that the request results in a properly structured GzipFilter response, where the content is
* Asserts that the request results in a properly structured GzipHandler response, where the content is
* not compressed, and the content-length is returned appropriately.
*
* @param expectedResponse
@ -431,7 +432,7 @@ public class GzipTester
}
/**
* Asserts that the request results in a properly structured GzipFilter response, where the content is
* Asserts that the request results in a properly structured GzipHandler response, where the content is
* not compressed, and the content-length is returned appropriately.
*
* @param expectedFilesize
@ -598,32 +599,18 @@ public class GzipTester
}
/**
* Set the servlet that provides content for the GzipFilter in being tested.
* Set the servlet that provides content for the GzipHandler in being tested.
*
* @param servletClass
* the servlet that will provide content.
* @return the FilterHolder for configuring the GzipFilter's initParameters with
*/
public FilterHolder setContentServlet(Class<? extends Servlet> servletClass) throws IOException
public void setContentServlet(Class<? extends Servlet> servletClass) throws IOException
{
tester.setContextPath("/context");
tester.setResourceBase(testdir.getDir().getCanonicalPath());
ServletHolder servletHolder = tester.addServlet(servletClass,"/");
servletHolder.setInitParameter("baseDir",testdir.getDir().getAbsolutePath());
servletHolder.setInitParameter("etags","true");
FilterHolder holder = tester.addFilter(gzipFilterClass,"/*",EnumSet.allOf(DispatcherType.class));
holder.setInitParameter("vary","Accept-Encoding");
return holder;
}
public Class<? extends Filter> getGzipFilterClass()
{
return gzipFilterClass;
}
public void setGzipFilterClass(Class<? extends Filter> gzipFilterClass)
{
this.gzipFilterClass = gzipFilterClass;
}
public void setEncoding(String encoding)

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
public final class Hex
{

View File

@ -16,28 +16,25 @@
// ========================================================================
//
package org.eclipse.jetty.servlets;
package org.eclipse.jetty.server.handler.gzip;
import javax.servlet.Servlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.gzip.GzipTester;
import org.eclipse.jetty.servlets.gzip.TestMinGzipSizeServlet;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Rule;
import org.junit.Test;
/**
* Perform specific tests on the IncludableGzipFilter's ability to manage
* Perform specific tests on the IncludableGzipHandler's ability to manage
* minGzipSize initialization parameter.
*
* @see <a href="Eclipse Bug 366106">http://bugs.eclipse.org/366106</a>
*/
public class IncludableGzipFilterMinSizeTest
public class IncludedGzipMinSizeTest
{
public IncludableGzipFilterMinSizeTest()
public IncludedGzipMinSizeTest()
{
this.compressionType = GzipFilter.GZIP;
this.compressionType = GzipHandler.GZIP;
}
@Rule
@ -50,21 +47,18 @@ public class IncludableGzipFilterMinSizeTest
public void testUnderMinSize() throws Exception
{
GzipTester tester = new GzipTester(testdir, compressionType);
// Use IncludableGzipFilter
tester.setGzipFilterClass(GzipFilter.class);
FilterHolder holder = tester.setContentServlet(testServlet);
tester.setContentServlet(testServlet);
// A valid mime type that we will never use in this test.
// configured here to prevent mimeType==null logic
holder.setInitParameter("mimeTypes","application/soap+xml");
holder.setInitParameter("minGzipSize", "2048");
holder.setInitParameter("uncheckedPrintWriter","true");
tester.getGzipHandler().addIncludedMimeTypes("application/soap+xml");
tester.getGzipHandler().setMinGzipSize(2048);
tester.copyTestServerFile("small_script.js");
try {
tester.start();
tester.assertIsResponseNotGzipFiltered("small_script.js",
tester.assertIsResponseNotGziped("small_script.js",
"small_script.js.sha1",
"text/javascript; charset=utf-8");
} finally {
@ -76,13 +70,10 @@ public class IncludableGzipFilterMinSizeTest
public void testOverMinSize() throws Exception
{
GzipTester tester = new GzipTester(testdir, compressionType);
// Use IncludableGzipFilter
tester.setGzipFilterClass(GzipFilter.class);
FilterHolder holder = tester.setContentServlet(testServlet);
holder.setInitParameter("mimeTypes","application/soap+xml,text/javascript,application/javascript");
holder.setInitParameter("minGzipSize", "2048");
holder.setInitParameter("uncheckedPrintWriter","true");
tester.setContentServlet(testServlet);
tester.getGzipHandler().addIncludedMimeTypes("application/soap+xml","text/javascript","application/javascript");
tester.getGzipHandler().setMinGzipSize(2048);
tester.copyTestServerFile("big_script.js");

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets;
package org.eclipse.jetty.server.handler.gzip;
import static org.junit.Assert.assertEquals;
@ -35,7 +35,6 @@ import java.util.zip.InflaterInputStream;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletTester;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.BufferUtil;
@ -45,7 +44,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class IncludableGzipFilterTest
public class IncludedGzipTest
{
@Rule
@ -68,9 +67,9 @@ public class IncludableGzipFilterTest
private ServletTester tester;
private String compressionType;
public IncludableGzipFilterTest()
public IncludedGzipTest()
{
this.compressionType = GzipFilter.GZIP;
this.compressionType = GzipHandler.GZIP;
}
@Before
@ -88,8 +87,10 @@ public class IncludableGzipFilterTest
tester=new ServletTester("/context");
tester.getContext().setResourceBase(testdir.getDir().getCanonicalPath());
tester.getContext().addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, "/");
FilterHolder holder = tester.getContext().addFilter(GzipFilter.class,"/*",null);
holder.setInitParameter("mimeTypes","text/plain");
GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(tester.getContext().getHandler());
tester.getContext().setHandler(gzipHandler);
tester.start();
}
@ -101,7 +102,7 @@ public class IncludableGzipFilterTest
}
@Test
public void testGzipFilter() throws Exception
public void testGzip() throws Exception
{
// generated and parsed test
@ -119,11 +120,11 @@ public class IncludableGzipFilterTest
InputStream testIn = null;
ByteArrayInputStream compressedResponseStream = new ByteArrayInputStream(response.getContentBytes());
if (compressionType.equals(GzipFilter.GZIP))
if (compressionType.equals(GzipHandler.GZIP))
{
testIn = new GZIPInputStream(compressedResponseStream);
}
else if (compressionType.equals(GzipFilter.DEFLATE))
else if (compressionType.equals(GzipHandler.DEFLATE))
{
testIn = new InflaterInputStream(compressedResponseStream, new Inflater(true));
}

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
import java.io.OutputStream;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.ByteArrayOutputStream;
import java.io.File;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -27,11 +27,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
* {@link GzipHandler} in the past.
*
* Using a real-world pattern of:
*

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
@ -25,11 +25,9 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
* {@link GzipHandler} in the past.
*
* Using a real-world pattern of:
*

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
@ -25,11 +25,9 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
* {@link GzipHandler} in the past.
*
* Using a real-world pattern of:
*

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
@ -25,11 +25,9 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
* {@link GzipHandler} in the past.
*
* Using a real-world pattern of:
*

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
@ -25,11 +25,9 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
* {@link GzipHandler} in the past.
*
* Using a real-world pattern of:
*
@ -53,7 +51,7 @@ public class TestServletStreamLengthTypeWriteWithFlush extends TestDirContentSer
ServletOutputStream out = response.getOutputStream();
// set content-length of uncompressed content (GzipFilter should handle this)
// set content-length of uncompressed content (GzipHandler should handle this)
response.setContentLength(dataBytes.length);
if (fileName.endsWith("txt"))

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
@ -25,11 +25,9 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
* {@link GzipHandler} in the past.
*
* Using a real-world pattern of:
*

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
@ -25,11 +25,9 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
* {@link GzipHandler} in the past.
*
* Using a real-world pattern of:
*

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;
@ -25,11 +25,9 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlets.GzipFilter;
/**
* A sample servlet to serve static content, using a order of construction that has caused problems for
* {@link GzipFilter} in the past.
* {@link GzipHandler} in the past.
*
* Using a real-world pattern of:
*

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.servlets.gzip;
package org.eclipse.jetty.server.handler.gzip;
import java.io.IOException;

View File

@ -1,145 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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.servlets;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Filter;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlets.gzip.GzipTester;
import org.eclipse.jetty.servlets.gzip.TestStaticMimeTypeServlet;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests {@link GzipFilter} in combination with {@link DefaultServlet} for ability to configure {@link GzipFilter} to
* ignore recompress situations from upstream.
*/
@RunWith(Parameterized.class)
public class GzipFilterDefaultNoRecompressTest
{
@SuppressWarnings("deprecation")
@Parameters
public static List<Object[]> data()
{
return Arrays.asList(new Object[][]
{
// Some already compressed files
/* 00 */ { GzipFilter.class, "test_quotes.gz", "application/gzip", GzipFilter.GZIP },
/* 01 */ { GzipFilter.class, "test_quotes.bz2", "application/bzip2", GzipFilter.GZIP },
/* 02 */ { GzipFilter.class, "test_quotes.zip", "application/zip", GzipFilter.GZIP },
/* 03 */ { GzipFilter.class, "test_quotes.rar", "application/octet-stream", GzipFilter.GZIP },
// Some images (common first)
/* 04 */ { GzipFilter.class, "jetty_logo.png", "image/png", GzipFilter.GZIP },
/* 05 */ { GzipFilter.class, "jetty_logo.gif", "image/gif", GzipFilter.GZIP },
/* 06 */ { GzipFilter.class, "jetty_logo.jpeg", "image/jpeg", GzipFilter.GZIP },
/* 07 */ { GzipFilter.class, "jetty_logo.jpg", "image/jpeg", GzipFilter.GZIP },
// Lesser encountered images (usually found being requested from non-browser clients)
/* 08 */ { GzipFilter.class, "jetty_logo.bmp", "image/bmp", GzipFilter.GZIP },
/* 09 */ { GzipFilter.class, "jetty_logo.tga", "application/tga", GzipFilter.GZIP },
/* 10 */ { GzipFilter.class, "jetty_logo.tif", "image/tiff", GzipFilter.GZIP },
/* 11 */ { GzipFilter.class, "jetty_logo.tiff", "image/tiff", GzipFilter.GZIP },
/* 12 */ { GzipFilter.class, "jetty_logo.xcf", "image/xcf", GzipFilter.GZIP },
/* 13 */ { GzipFilter.class, "jetty_logo.jp2", "image/jpeg2000", GzipFilter.GZIP },
//qvalue disables compression
/* 14 */ { GzipFilter.class, "test_quotes.txt", "text/plain", GzipFilter.GZIP+";q=0"},
/* 15 */ { GzipFilter.class, "test_quotes.txt", "text/plain", GzipFilter.GZIP+"; q = 0 "},
// Some already compressed files
/* 16 */ { GzipFilter.class, "test_quotes.gz", "application/gzip", GzipFilter.GZIP },
/* 17 */ { GzipFilter.class, "test_quotes.bz2", "application/bzip2", GzipFilter.GZIP },
/* 18 */ { GzipFilter.class, "test_quotes.zip", "application/zip", GzipFilter.GZIP },
/* 19 */ { GzipFilter.class, "test_quotes.rar", "application/octet-stream", GzipFilter.GZIP },
// Some images (common first)
/* 20 */ { GzipFilter.class, "jetty_logo.png", "image/png", GzipFilter.GZIP },
/* 21 */ { GzipFilter.class, "jetty_logo.gif", "image/gif", GzipFilter.GZIP },
/* 22 */ { GzipFilter.class, "jetty_logo.jpeg", "image/jpeg", GzipFilter.GZIP },
/* 23 */ { GzipFilter.class, "jetty_logo.jpg", "image/jpeg", GzipFilter.GZIP },
// Lesser encountered images (usually found being requested from non-browser clients)
/* 24 */ { GzipFilter.class, "jetty_logo.bmp", "image/bmp", GzipFilter.GZIP },
/* 25 */ { GzipFilter.class, "jetty_logo.tga", "application/tga", GzipFilter.GZIP },
/* 26 */ { GzipFilter.class, "jetty_logo.tif", "image/tiff", GzipFilter.GZIP },
/* 27 */ { GzipFilter.class, "jetty_logo.tiff", "image/tiff", GzipFilter.GZIP },
/* 28 */ { GzipFilter.class, "jetty_logo.xcf", "image/xcf", GzipFilter.GZIP },
/* 29 */ { GzipFilter.class, "jetty_logo.jp2", "image/jpeg2000", GzipFilter.GZIP },
// qvalue disables compression
/* 30 */ { GzipFilter.class, "test_quotes.txt", "text/plain", GzipFilter.GZIP+";q=0"},
/* 31 */ { GzipFilter.class, "test_quotes.txt", "text/plain", GzipFilter.GZIP+"; q = 0 "}
});
}
@Rule
public TestingDir testingdir = new TestingDir();
private Class<? extends Filter> testFilter;
private String alreadyCompressedFilename;
private String expectedContentType;
private String compressionType;
public GzipFilterDefaultNoRecompressTest(Class<? extends Filter> testFilter,String testFilename, String expectedContentType, String compressionType)
{
this.testFilter = testFilter;
this.alreadyCompressedFilename = testFilename;
this.expectedContentType = expectedContentType;
this.compressionType = compressionType;
}
@Test
public void testNotGzipFiltered_Default_AlreadyCompressed() throws Exception
{
GzipTester tester = new GzipTester(testingdir, compressionType);
tester.setGzipFilterClass(testFilter);
copyTestFileToServer(alreadyCompressedFilename);
FilterHolder holder = tester.setContentServlet(TestStaticMimeTypeServlet.class);
StringBuilder mimeTypes = new StringBuilder();
mimeTypes.append("text/plain");
holder.setInitParameter("mimeTypes",mimeTypes.toString());
try
{
tester.start();
tester.assertIsResponseNotGzipFiltered(alreadyCompressedFilename,alreadyCompressedFilename + ".sha1",expectedContentType);
}
finally
{
tester.stop();
}
}
private void copyTestFileToServer(String testFilename) throws IOException
{
File testFile = MavenTestingUtils.getTestResourceFile(testFilename);
File outFile = testingdir.getFile(testFilename);
IO.copy(testFile,outFile);
}
}

View File

@ -1,6 +1,6 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG
#org.eclipse.jetty.servlets.LEVEL=DEBUG
#org.eclipse.jetty.servlets.GzipFilter.LEVEL=DEBUG
org.eclipse.jetty.server.handler.gzip.GzipHandler.LEVEL=DEBUG
#org.eclipse.jetty.servlets.QoSFilter.LEVEL=DEBUG
#org.eclipse.jetty.servlets.DoSFilter.LEVEL=DEBUG

View File

@ -102,7 +102,7 @@ public class HTTPSPDYServerConnectionFactory extends SPDYServerConnectionFactory
// accept-encoding header as it is redundant to negotiate gzip compression support with the server,
// if clients have to accept it.
// So we inject the accept-encoding header here, even if not set by the client. This will enforce SPDY
// clients to follow the spec and enable gzip compression if GzipFilter or the like is enabled.
// clients to follow the spec and enable gzip compression if enabled.
if (!(headers.get("accept-encoding") != null && headers.get("accept-encoding").getValue().contains
("gzip")))
headers.add("accept-encoding", "gzip");

View File

@ -42,7 +42,7 @@ import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.servlets.gzip.GzipHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.spdy.api.DataInfo;
import org.eclipse.jetty.spdy.api.HeadersInfo;
import org.eclipse.jetty.spdy.api.PushInfo;

View File

@ -117,8 +117,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
"org.eclipse.jetty.websocket.", // webapp cannot change / replace websocket classes
"org.eclipse.jetty.util.log.", // webapp should use server log
"org.eclipse.jetty.servlet.DefaultServlet", // webapp cannot change default servlets
"org.eclipse.jetty.servlets.AsyncGzipFilter", // special case for AsyncGzipFilter
"org.eclipse.jetty.servlets.GzipFilter", // special case for GzipFilter
"org.eclipse.jetty.servlets.PushCacheFilter" //must be loaded by container classpath
} ;

View File

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/rfc2616-webapp</Set>
<Set name="war">
<Property name="test.webapps" default="." />/test-webapp-rfc2616.war
</Set>
<Set name="contextPath">/rfc2616-webapp</Set>
<Set name="war"><Property name="test.webapps" default="." />/test-webapp-rfc2616.war</Set>
<Set name="gzipHandler">
<New class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
<Set name="minGzipSize">1024</Set>
</New>
</Set>
</Configure>

View File

@ -35,6 +35,12 @@ detected.
<Arg type="Boolean">true</Arg>
</Call>
<Set name="gzipHandler">
<New class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
<Set name="minGzipSize">2048</Set>
</New>
</Set>
<!-- Enable symlinks
<Call name="addAliasCheck">
<Arg><New class="org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker"/></Arg>

View File

@ -61,46 +61,6 @@
<url-pattern>/dump/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>GzipFilter</filter-name>
<filter-class>org.eclipse.jetty.servlets.AsyncGzipFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>bufferSize</param-name>
<param-value>8192</param-value>
</init-param>
<init-param>
<param-name>mimeTypes</param-name>
<param-value>text/plain,application/xml,text/html</param-value>
</init-param>
<init-param>
<param-name>minGzipSize</param-name>
<param-value>2048</param-value>
</init-param>
<init-param>
<param-name>userAgent</param-name>
<param-value>(?:Mozilla[^\(]*\(compatible;\s*+([^;]*);.*)|(?:.*?([^\s]+/[^\s]+).*)</param-value>
</init-param>
<init-param>
<param-name>cacheSize</param-name>
<param-value>1024</param-value>
</init-param>
<init-param>
<param-name>excludedAgents</param-name>
<param-value>MSIE 6.0</param-value>
</init-param>
<init-param>
<param-name>uncheckedPrintWriter</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>/dump/gzip/*</url-pattern>
<url-pattern>*.txt</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>com.acme.LoginServlet</servlet-class>

View File

@ -1,25 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>rfc2616-webapp</display-name>
<context-param>
<param-name>org.eclipse.jetty.handler.GzipHandler.minGzipSize</param-name>
<param-value>1024</param-value>
</context-param>
<context-param>
<param-name>org.eclipse.jetty.handler.GzipHandler.includePaths</param-name>
<param-value>/*</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>GZIPFilter</filter-name>
<filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
<init-param>
<param-name>minGzipSize</param-name>
<param-value>1024</param-value>
</init-param>
<init-param>
<param-name>bufferSize</param-name>
<param-value>16384</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>GZIPFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>HttpMethodsServlet</servlet-name>
<servlet-class>org.eclipse.jetty.tests.webapp.HttpMethodsServlet</servlet-class>
@ -28,4 +23,4 @@
<servlet-name>HttpMethodsServlet</servlet-name>
<url-pattern>/httpmethods</url-pattern>
</servlet-mapping>
</web-app>
</web-app>