From 41fbefa44f4b8759bddc1ef487f39b3badc8d48f Mon Sep 17 00:00:00 2001 From: Musachy Barroso Date: Sat, 18 Apr 2009 17:09:01 +0000 Subject: [PATCH] WW-3000 force StrutsPrepareAndExecuteFilter to always lookup action mapping, to prevent infinite recursion when the filter is applied to FORWARD git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@766357 13f79535-47bb-0310-9956-ffa450edef68 --- .../dispatcher/ng/PrepareOperations.java | 15 ++++++-- .../filter/StrutsPrepareAndExecuteFilter.java | 2 +- ...repareAndExecuteFilterIntegrationTest.java | 34 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java b/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java index 24388c1ae..e4856e089 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/ng/PrepareOperations.java @@ -134,13 +134,24 @@ public class PrepareOperations { } /** - * Finds and optionally creates an {@link ActionMapping}. It first looks in the current request to see if one + * Finds and optionally creates an {@link ActionMapping}. It first looks in the current request to see if one * has already been found, otherwise, it creates it and stores it in the request. No mapping will be created in the * case of static resource requests or unidentifiable requests for other servlets, for example. */ public ActionMapping findActionMapping(HttpServletRequest request, HttpServletResponse response) { + return findActionMapping(request, response, false); + } + + /** + * Finds and optionally creates an {@link ActionMapping}. if forceLookup is false, it first looks in the current request to see if one + * has already been found, otherwise, it creates it and stores it in the request. No mapping will be created in the + * case of static resource requests or unidentifiable requests for other servlets, for example. + * @param forceLookup if true, the action mapping will be looked up from the ActionMapper instance, ignoring if there is one + * in the request or not + */ + public ActionMapping findActionMapping(HttpServletRequest request, HttpServletResponse response, boolean forceLookup) { ActionMapping mapping = (ActionMapping) request.getAttribute(STRUTS_ACTION_MAPPING_KEY); - if (mapping == null) { + if (mapping == null || forceLookup) { try { mapping = dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(request, dispatcher.getConfigurationManager()); if (mapping != null) { diff --git a/core/src/main/java/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.java b/core/src/main/java/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.java index e73884b84..ad0471637 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/ng/filter/StrutsPrepareAndExecuteFilter.java @@ -66,7 +66,7 @@ public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter { prepare.assignDispatcherToThread(); prepare.setEncodingAndLocale(request, response); request = prepare.wrapRequest(request); - ActionMapping mapping = prepare.findActionMapping(request, response); + ActionMapping mapping = prepare.findActionMapping(request, response, true); if (mapping == null) { boolean handled = execute.executeStaticResourceRequest(request, response); if (!handled) { diff --git a/core/src/test/java/org/apache/struts2/dispatcher/ng/StrutsPrepareAndExecuteFilterIntegrationTest.java b/core/src/test/java/org/apache/struts2/dispatcher/ng/StrutsPrepareAndExecuteFilterIntegrationTest.java index 116fa625b..7ea502317 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/ng/StrutsPrepareAndExecuteFilterIntegrationTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/ng/StrutsPrepareAndExecuteFilterIntegrationTest.java @@ -79,6 +79,40 @@ public class StrutsPrepareAndExecuteFilterIntegrationTest extends TestCase { assertNull(Dispatcher.getInstance()); } + public void testActionMappingLookup() throws ServletException, IOException { + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + MockFilterConfig filterConfig = new MockFilterConfig(); + MockFilterChain filterChain = new MockFilterChain() { + @Override + public void doFilter(ServletRequest req, ServletResponse res) { + fail("Shouldn't get here"); + } + }; + + request.setRequestURI("/hello.action"); + StrutsPrepareAndExecuteFilter filter = new StrutsPrepareAndExecuteFilter(); + filter.init(filterConfig); + filter.doFilter(request, response, filterChain); + assertEquals(200, response.getStatus()); + assertNull(ActionContext.getContext()); + assertNull(Dispatcher.getInstance()); + + //simulate a FORWARD + MockFilterChain filterChain2 = new MockFilterChain() { + @Override + public void doFilter(ServletRequest req, ServletResponse res) { + req.setAttribute("__invoked", true); + } + }; + request.setRequestURI("hello.jsp"); + filter.doFilter(request, response, filterChain2); + assertEquals(200, response.getStatus()); + assertNull(ActionContext.getContext()); + assertNull(Dispatcher.getInstance()); + assertTrue((Boolean) request.getAttribute("__invoked")); + } + public void testStaticFallthrough() throws ServletException, IOException { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse();