From 52a89397d949a1d651497538e02139661084b7ef Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Thu, 23 Oct 2008 19:55:17 +0000 Subject: [PATCH] SWF-566 Make org.springframework.js.resource.ResourceServlet more reusable setAllowedResourcePaths now accepts a comma separated String instead of String[]. This has better compatibility with HttpServletBean. Added support for Ant style wildcard compressed mime types. "text/*" is now the default. This property is configurable with setCompressedMimeType, accepting a comma separated String. --- .../js/resource/ResourceServlet.java | 64 +++++++++++++++---- .../js/resource/ResourceServletTests.java | 12 ++++ 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/spring-js/src/main/java/org/springframework/js/resource/ResourceServlet.java b/spring-js/src/main/java/org/springframework/js/resource/ResourceServlet.java index 9144d5ed..69af63fb 100644 --- a/spring-js/src/main/java/org/springframework/js/resource/ResourceServlet.java +++ b/spring-js/src/main/java/org/springframework/js/resource/ResourceServlet.java @@ -22,8 +22,10 @@ import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.zip.GZIPOutputStream; @@ -64,9 +66,23 @@ public class ResourceServlet extends HttpServletBean { private boolean gzipEnabled = true; - private String[] allowedResourcePaths = new String[] { "/**/*.css", "/**/*.gif", "/**/*.ico", "/**/*.jpeg", - "/**/*.jpg", "/**/*.js", "/**/*.png", "META-INF/**/*.css", "META-INF/**/*.gif", "META-INF/**/*.ico", - "META-INF/**/*.jpeg", "META-INF/**/*.jpg", "META-INF/**/*.js", "META-INF/**/*.png" }; + private Set allowedResourcePaths = new HashSet(); + { + allowedResourcePaths.add("/**/*.css"); + allowedResourcePaths.add("/**/*.gif"); + allowedResourcePaths.add("/**/*.ico"); + allowedResourcePaths.add("/**/*.jpeg"); + allowedResourcePaths.add("/**/*.jpg"); + allowedResourcePaths.add("/**/*.js"); + allowedResourcePaths.add("/**/*.png"); + allowedResourcePaths.add("META-INF/**/*.css"); + allowedResourcePaths.add("META-INF/**/*.gif"); + allowedResourcePaths.add("META-INF/**/*.ico"); + allowedResourcePaths.add("META-INF/**/*.jpeg"); + allowedResourcePaths.add("META-INF/**/*.jpg"); + allowedResourcePaths.add("META-INF/**/*.js"); + allowedResourcePaths.add("META-INF/**/*.png"); + }; private Map defaultMimeTypes = new HashMap(); { @@ -81,8 +97,7 @@ public class ResourceServlet extends HttpServletBean { private Set compressedMimeTypes = new HashSet(); { - compressedMimeTypes.add("text/css"); - compressedMimeTypes.add("text/javascript"); + compressedMimeTypes.add("text/*"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -133,7 +148,7 @@ public class ResourceServlet extends HttpServletBean { String mimeType = response.getContentType(); if (gzipEnabled && StringUtils.hasText(acceptEncoding) && acceptEncoding.indexOf("gzip") > -1 - && compressedMimeTypes.contains(mimeType)) { + && matchesCompressedMimeTypes(mimeType)) { log.debug("Enabling GZIP compression for the current response."); return new GZIPResponseStream(response); } else { @@ -141,6 +156,18 @@ public class ResourceServlet extends HttpServletBean { } } + private boolean matchesCompressedMimeTypes(String mimeType) { + PathMatcher pathMatcher = new AntPathMatcher(); + Iterator compressedMimeTypesIt = compressedMimeTypes.iterator(); + while (compressedMimeTypesIt.hasNext()) { + String compressedMimeType = (String) compressedMimeTypesIt.next(); + if (pathMatcher.match(compressedMimeType, mimeType)) { + return true; + } + } + return false; + } + private void prepareResponse(HttpServletResponse response, URL[] resources, String rawResourcePath) throws IOException { long lastModified = -1; @@ -256,8 +283,9 @@ public class ResourceServlet extends HttpServletBean { return false; } PathMatcher pathMatcher = new AntPathMatcher(); - for (int i = 0; i < allowedResourcePaths.length; i++) { - String pattern = allowedResourcePaths[i]; + Iterator allowedResourcePathsIt = allowedResourcePaths.iterator(); + while (allowedResourcePathsIt.hasNext()) { + String pattern = (String) allowedResourcePathsIt.next(); if (pathMatcher.match(pattern, resourcePath)) { return true; } @@ -355,13 +383,25 @@ public class ResourceServlet extends HttpServletBean { } /** - * Set allowed resources as an array of URL patterns, e.g. "META-INF/** /*.js", The paths may be any Ant-style - * pattern parsable by AntPathMatcher. + * Set allowed resources as an comma separated String of URL patterns, e.g. "META-INF/** /*.js", The paths may be + * any Ant-style pattern parsable by AntPathMatcher. * * @see AntPathMatcher */ - public void setAllowedResourcePaths(String[] allowedResourcePaths) { - this.allowedResourcePaths = allowedResourcePaths; + public void setAllowedResourcePaths(String allowedResourcePaths) { + this.allowedResourcePaths = new HashSet(Arrays.asList(StringUtils.tokenizeToStringArray(allowedResourcePaths, + ",", true, true))); + } + + /** + * Set comma separated MIME types that should have gzip compression applied. Typically, gzip compression is only + * useful for text based content. Ant-style patterns are supported, e.g. "text/*". + * + * @see AntPathMatcher + */ + public void setCompressedMimeTypes(String compressedMimeTypes) { + this.compressedMimeTypes = new HashSet(Arrays.asList(StringUtils.tokenizeToStringArray(compressedMimeTypes, + ",", true, true))); } /** diff --git a/spring-js/src/test/java/org/springframework/js/resource/ResourceServletTests.java b/spring-js/src/test/java/org/springframework/js/resource/ResourceServletTests.java index 9c7353c5..ca1259c9 100644 --- a/spring-js/src/test/java/org/springframework/js/resource/ResourceServletTests.java +++ b/spring-js/src/test/java/org/springframework/js/resource/ResourceServletTests.java @@ -36,6 +36,7 @@ public class ResourceServletTests extends TestCase { servlet.doGet(request, response); assertEquals(200, response.getStatus()); + assertNull(response.getHeader("Content-Encoding")); } public final void testExecute_CombinedResources() throws Exception { @@ -50,6 +51,17 @@ public class ResourceServletTests extends TestCase { assertEquals(200, response.getStatus()); } + public final void testExecute_CompressedResponse() throws Exception { + + String requestPath = "/dojo/dojo.js"; + request.setPathInfo(requestPath); + request.addHeader("Accept-Encoding", "gzip"); + servlet.doGet(request, response); + + assertEquals(200, response.getStatus()); + assertEquals("gzip", response.getHeader("Content-Encoding")); + } + public final void testExecute_ResourceNotFound() throws Exception { String requestPath = "/xxx/xxx.js";