From a30b723c0c98bc3ac0ad37369e86239b54bf138e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Gielen?= Date: Mon, 27 Oct 2008 21:46:04 +0000 Subject: [PATCH] WW-2849: Refatoring to provide better testability for static resource resolution git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/branches/STRUTS_2_0_X@708334 13f79535-47bb-0310-9956-ffa450edef68 --- .../struts2/dispatcher/FilterDispatcher.java | 65 ++++++++++++------- .../dispatcher/FilterDispatcherTest.java | 34 ++++++++++ 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java index a57a5b094..97aa914ba 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java @@ -150,10 +150,12 @@ public class FilterDispatcher implements StrutsStatics, Filter { */ private static final Log LOG = LogFactory.getLog(FilterDispatcher.class); + static final String DEFAULT_STATIC_PACKAGES = "org.apache.struts2.static template org.apache.struts2.interceptor.debugging"; + /** * Store set of path prefixes to use with static resources. */ - private String[] pathPrefixes; + String[] pathPrefixes; /** * Provide a formatted date for setting heading information when caching static content. @@ -203,7 +205,7 @@ public class FilterDispatcher implements StrutsStatics, Filter { dispatcher.init(); String param = filterConfig.getInitParameter("packages"); - String packages = "org.apache.struts2.static template org.apache.struts2.interceptor.debugging"; + String packages = DEFAULT_STATIC_PACKAGES; if (param != null) { packages = param + " " + packages; } @@ -408,7 +410,7 @@ public class FilterDispatcher implements StrutsStatics, Filter { } if (serveStatic && resourcePath.startsWith("/struts")) { - findStaticResource(resourcePath, request, response); + findStaticResource(resourcePath, findAndCheckResources(resourcePath), request, response); } else { // this is a normal request, let it pass through chain.doFilter(request, response); @@ -430,41 +432,56 @@ public class FilterDispatcher implements StrutsStatics, Filter { /** * Locate a static resource and copy directly to the response, - * setting the appropriate caching headers. + * setting the appropriate caching headers. * * @param path The resource path + * @param resourceUrls List of matching resource URLs * @param request The request * @param response The response * @throws IOException If anything goes wrong */ - public void findStaticResource(String path, HttpServletRequest request, HttpServletResponse response) + public void findStaticResource(String path, List resourceUrls, HttpServletRequest request, HttpServletResponse response) throws IOException { - String name = cleanupPath(path); - for (String pathPrefix : pathPrefixes) { - URL resourceUrl = findResource(buildPath(name, pathPrefix)); - if (resourceUrl != null) { - InputStream is = null; - try { - //check that the resource path is under the pathPrefix path - String pathEnding = buildPath(name, pathPrefix); - if (resourceUrl.getFile().endsWith(pathEnding)) - is = resourceUrl.openStream(); - } catch (Exception ex) { - // just ignore it - continue; - } + for (URL resourceUrl : resourceUrls) { + InputStream is; + try { + is = resourceUrl.openStream(); + } catch (Exception ex) { + // just ignore it + continue; + } - //not inside the try block, as this could throw IOExceptions also - if (is != null) { - process(is, path, request, response); - return; - } + //not inside the try block, as this could throw IOExceptions also + if (is != null) { + process(is, path, request, response); + return; } } response.sendError(HttpServletResponse.SC_NOT_FOUND); } + /** + * Locate a static classpath resource and check for safety constraints. + * + * @param path The resource path to check for available resources + * @return verified classpath resource URLs + * @throws IOException If anything goes wrong + */ + protected List findAndCheckResources(String path) throws IOException { + String name = cleanupPath(path); + List resourceUrls = new ArrayList(pathPrefixes.length); + for (String pathPrefix : pathPrefixes) { + URL resourceUrl = findResource(buildPath(name, pathPrefix)); + String pathEnding = buildPath(name, pathPrefix); + //check that the resource path is under the pathPrefix path + if (resourceUrl != null && resourceUrl.getFile().endsWith(pathEnding)) { + resourceUrls.add(resourceUrl); + } + } + return resourceUrls; + } + /** * Look for a static resource in the classpath. * diff --git a/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java b/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java index 1861b9707..1ccbb996e 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java @@ -21,8 +21,11 @@ package org.apache.struts2.dispatcher; import java.io.IOException; +import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import java.util.List; +import java.net.URL; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; @@ -177,6 +180,37 @@ public class FilterDispatcherTest extends StrutsTestCase { assertTrue(_dispatcher.serviceRequest); } + public void testFindAndCheckResourcesWithDojoJs() throws Exception { + FilterDispatcher filterDispatcher = new FilterDispatcher(); + filterDispatcher.pathPrefixes = filterDispatcher.parse(FilterDispatcher.DEFAULT_STATIC_PACKAGES); + List result = filterDispatcher.findAndCheckResources("/struts/dojo/dojo.js"); + assertTrue(result.size()>=1); + for (URL url : result) { + try { + InputStream is = url.openStream(); + is.close(); + } catch (IOException e) { + fail("Resource could not be opened"); + } + + } + } + + public void testFindAndCheckResourcesWithValidationClientJs() throws Exception { + FilterDispatcher filterDispatcher = new FilterDispatcher(); + filterDispatcher.pathPrefixes = filterDispatcher.parse(FilterDispatcher.DEFAULT_STATIC_PACKAGES); + List result = filterDispatcher.findAndCheckResources("/struts/validationClient.js"); + assertTrue(result.size()>=1); + for (URL url : result) { + try { + InputStream is = url.openStream(); + is.close(); + } catch (IOException e) { + fail("Resource could not be opened"); + } + + } + } // === inner class ======== public static class InnerObjectFactory extends ObjectFactory {