Author: andyhot
Date: Thu Oct 29 23:21:01 2009
New Revision: 831151
URL:
http://svn.apache.org/viewvc?rev=831151&view=revLog:
TAPESTRY-1211: make use of gzip compression optional
Modified:
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/NestedMarkupWriter.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/asset/TestAssetService.java
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/NestedMarkupWriter.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/NestedMarkupWriter.java?rev=831151&r1=831150&r2=831151&view=diff==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/NestedMarkupWriter.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/NestedMarkupWriter.java Thu Oct 29 23:21:01 2009
@@ -26,7 +26,7 @@
public interface NestedMarkupWriter extends IMarkupWriter
{
/**
- * Returns any makrup so far accumulated by the nested markup writer. When the nested markup
+ * Returns any markup so far accumulated by the nested markup writer. When the nested markup
* writer is closed, it invokes {@link org.apache.tapestry.IMarkupWriter#printRaw(String)},
* with this content, on its parent markup writer.
* <p>
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java?rev=831151&r1=831150&r2=831151&view=diff==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/asset/AssetService.java Thu Oct 29 23:21:01 2009
@@ -52,7 +52,7 @@
* that encodes the path of a resource within the classpath. The {@link #service(IRequestCycle)}
* method reads the resource and streams it out.
* <p>
- * TBD: Security issues. Should only be able to retrieve a resource that was previously registerred
+ * TBD: Security issues. Should only be able to retrieve a resource that was previously registered
* in some way ... otherwise, hackers will be able to suck out the .class files of the application!
*
* @author Howard Lewis Ship
@@ -122,6 +122,9 @@
/** @since 4.1 */
private ResourceMatcher _unprotectedMatcher;
+
+ /** @since 4.1.7 */
+ private boolean _neverGzip;
/**
* Startup time for this service; used to set the Last-Modified response header.
@@ -266,7 +269,7 @@
/**
* Utility that helps to resolve css file relative resources included
- * in a css temlpate via "url('../images/foo.gif')" or fix paths containing
+ * in a css template via "url('../images/foo.gif')" or fix paths containing
* relative resource ".." style notation.
*
* @param path The incoming path to check for relativity.
@@ -409,7 +412,7 @@
// compress javascript responses when possible
- if (GzipUtil.shouldCompressContentType(contentType) && GzipUtil.isGzipCapable(_request))
+ if (!_neverGzip && GzipUtil.shouldCompressContentType(contentType) && GzipUtil.isGzipCapable(_request))
{
if (cache.getGzipData() == null)
{
@@ -485,7 +488,13 @@
{
_unprotectedMatcher = matcher;
}
-
+
+ /** @since 4.1.7 */
+ public void setNeverGzip(boolean neverGzip)
+ {
+ _neverGzip = neverGzip;
+ }
+
public void setLog(Log log)
{
_log = log;
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/asset/TestAssetService.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/asset/TestAssetService.java?rev=831151&r1=831150&r2=831151&view=diff==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/asset/TestAssetService.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/asset/TestAssetService.java Thu Oct 29 23:21:01 2009
@@ -164,6 +164,58 @@
verify();
}
+ public void test_Gzip_Response() throws Exception
+ {
+ String requestedResource = "/org/apache/tapestry/pages/Exception.css";
+ WebResponse response = newMock(WebResponse.class);
+ IRequestCycle cycle = newMock(IRequestCycle.class);
+
+ ClassResolver resolver = new DefaultClassResolver();
+ URLConnection url = resolver.getResource(requestedResource).openConnection();
+
+ AssetService service = newAssetServiceAllowingGzip(requestedResource, url, cycle, response, resolver);
+
+ response.setHeader("Content-Encoding", "gzip");
+
+ final int originalLength = url.getContentLength();
+ response.setHeader(EasyMock.matches("ETag"),
+ EasyMock.matches("W/\".*-" + url.getLastModified() + "\""));
+ response.setContentLength(EasyMock.lt(originalLength));
+
+ expect(response.getOutputStream(new ContentType("text/css"))).andReturn(new ByteArrayOutputStream());
+
+ replay();
+
+ service.service(cycle);
+
+ verify();
+ }
+
+ public void test_Gzip_Disabled_Response() throws Exception
+ {
+ String requestedResource = "/org/apache/tapestry/pages/Exception.css";
+ WebResponse response = newMock(WebResponse.class);
+ IRequestCycle cycle = newMock(IRequestCycle.class);
+
+ ClassResolver resolver = new DefaultClassResolver();
+ URLConnection url = resolver.getResource(requestedResource).openConnection();
+
+ AssetService service = newAssetServiceAllowingGzip(requestedResource, url, cycle, response, resolver);
+ service.setNeverGzip(true);
+
+ final int originalLength = url.getContentLength();
+ response.setHeader("ETag", "W/\"" + originalLength + "-" + url.getLastModified() + "\"");
+ response.setContentLength(originalLength);
+
+ expect(response.getOutputStream(new ContentType("text/css"))).andReturn(new ByteArrayOutputStream());
+
+ replay();
+
+ service.service(cycle);
+
+ verify();
+ }
+
public void test_Invalid_Resource()
throws Exception
{
@@ -211,4 +263,37 @@
verify();
}
+
+ private AssetService newAssetServiceAllowingGzip(String requestedResource, URLConnection url,
+ IRequestCycle cycle, WebResponse response, ClassResolver resolver)
+ {
+ WebRequest request = newMock(WebRequest.class);
+ checkOrder(request, false);
+ WebContext context = newMock(WebContext.class);
+ ResourceMatcher matcher = newMock(ResourceMatcher.class);
+
+ AssetService service = new AssetService();
+ service.setRequest(request);
+ service.setResponse(response);
+ service.setLog(LogFactory.getLog("test"));
+ service.setUnprotectedMatcher(matcher);
+ service.setClassResolver(resolver);
+ service.setContext(context);
+
+ expect(cycle.getParameter("path")).andReturn(requestedResource);
+ expect(cycle.getParameter("digest")).andReturn(null);
+
+ expect(matcher.containsResource(requestedResource)).andReturn(true);
+
+ expect(request.getDateHeader("If-Modified-Since")).andReturn(-1L);
+ expect(context.getMimeType(requestedResource)).andReturn("text/css");
+
+ response.setDateHeader("Last-Modified", url.getLastModified());
+ response.setDateHeader("Expires", service._expireTime);
+ response.setHeader("Cache-Control", "public, max-age=" + (AssetService.MONTH_SECONDS * 3));
+
+ expect(request.getHeader("User-Agent")).andReturn("Mozilla").anyTimes();
+ expect(request.getHeader("Accept-Encoding")).andReturn("gzip").anyTimes();
+ return service;
+ }
}