Author: bpontarelli
Date: Sun Jan 27 15:43:31 2008
New Revision: 615679
URL: http://svn.apache.org/viewvc?rev=615679&view=rev
Log:
Added better handling for extensionless URLs that contain dots in directory
names
Modified:
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java
Modified:
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
URL:
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java?rev=615679&r1=615678&r2=615679&view=diff
==============================================================================
---
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
(original)
+++
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
Sun Jan 27 15:43:31 2008
@@ -169,11 +169,11 @@
protected boolean allowDynamicMethodCalls = true;
protected boolean allowSlashesInActionNames = false;
-
+
protected boolean alwaysSelectFullNamespace = false;
protected PrefixTrie prefixTrie = null;
-
+
protected List<String> extensions = new ArrayList<String>() {{
add("action"); add("");}};
protected Container container;
@@ -242,17 +242,17 @@
protected void addParameterAction(String prefix, ParameterAction
parameterAction) {
prefixTrie.put(prefix, parameterAction);
}
-
+
@Inject(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION)
public void setAllowDynamicMethodCalls(String allow) {
allowDynamicMethodCalls = "true".equals(allow);
}
-
+
@Inject(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES)
public void setSlashesInActionNames(String allow) {
allowSlashesInActionNames = "true".equals(allow);
}
-
+
@Inject(StrutsConstants.STRUTS_ALWAYS_SELECT_FULL_NAMESPACE)
public void setAlwaysSelectFullNamespace(String val) {
this.alwaysSelectFullNamespace = "true".equals(val);
@@ -262,7 +262,7 @@
public void setContainer(Container container) {
this.container = container;
}
-
+
@Inject(StrutsConstants.STRUTS_ACTION_EXTENSION)
public void setExtensions(String extensions) {
if (extensions != null && !"".equals(extensions)) {
@@ -285,7 +285,7 @@
mapping.setName(actionName);
return parseActionName(mapping);
}
-
+
/*
* (non-Javadoc)
*
@@ -295,10 +295,10 @@
ConfigurationManager configManager) {
ActionMapping mapping = new ActionMapping();
String uri = getUri(request);
-
+
int indexOfSemicolon = uri.indexOf(";");
uri = (indexOfSemicolon > -1) ? uri.substring(0, indexOfSemicolon) :
uri;
-
+
uri = dropExtension(uri, mapping);
if (uri == null) {
return null;
@@ -350,12 +350,12 @@
for (Iterator iterator = parameterMap.keySet().iterator(); iterator
.hasNext();) {
String key = (String) iterator.next();
-
+
// Strip off the image button location info, if found
if (key.endsWith(".x") || key.endsWith(".y")) {
key = key.substring(0, key.length() - 2);
}
-
+
// Ensure a parameter doesn't get processed twice
if (!uniqueParameters.contains(key)) {
ParameterAction parameterAction = (ParameterAction) prefixTrie
@@ -435,13 +435,13 @@
protected String dropExtension(String name) {
return dropExtension(name, new ActionMapping());
}
-
+
/**
* Drops the extension from the action name, storing it in the mapping for
later use
*
* @param name
* The action name
- * @param mapping The action mapping to store the extension in
+ * @param mapping The action mapping to store the extension in
* @return The action name without its extension
*/
protected String dropExtension(String name, ActionMapping mapping) {
@@ -450,7 +450,11 @@
}
for (String ext : extensions) {
if ("".equals(ext)) {
- if (name.indexOf('.') == -1) {
+ // This should also handle cases such as
/foo/bar-1.0/description. It is tricky to
+ // distinquish /foo/bar-1.0 but perhaps adding a numeric check
in the future could
+ // work
+ int index = name.indexOf('.');
+ if (index == -1 || name.indexOf('/', index) >= 0) {
return name;
}
} else {
@@ -460,7 +464,7 @@
mapping.setExtension(ext);
return name;
}
- }
+ }
}
return null;
}
@@ -538,9 +542,9 @@
}
}
}
-
+
if (extension != null) {
-
+
if (extension.length() == 0 || (extension.length() > 0 &&
uri.indexOf('.' + extension) == -1)) {
if (extension.length() > 0) {
uri.append(".").append(extension);
@@ -553,10 +557,10 @@
return uri.toString();
}
-
+
public boolean isSlashesInActionNames() {
return allowSlashesInActionNames;
}
-
+
}
Modified:
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java
URL:
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java?rev=615679&r1=615678&r2=615679&view=diff
==============================================================================
---
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java
(original)
+++
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java
Sun Jan 27 15:43:31 2008
@@ -20,31 +20,27 @@
*/
package org.apache.struts2.dispatcher.mapper;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
-import java.util.Arrays;
-import org.apache.struts2.StrutsConstants;
-import org.apache.struts2.StrutsTestCase;
import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.StrutsTestCase;
import org.apache.struts2.dispatcher.ServletRedirectResult;
import org.apache.struts2.dispatcher.StrutsResultSupport;
import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest;
import org.apache.struts2.views.jsp.StrutsMockHttpServletResponse;
-import com.mockobjects.servlet.MockHttpServletRequest;
import com.mockobjects.dynamic.Mock;
-import com.opensymphony.xwork2.Result;
-import com.opensymphony.xwork2.DefaultActionInvocation;
-import com.opensymphony.xwork2.ActionInvocation;
+import com.mockobjects.servlet.MockHttpServletRequest;
import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.config.entities.PackageConfig;
import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
-import javax.servlet.http.HttpServletResponse;
-
/**
* DefaultActionMapper test case.
*
@@ -116,9 +112,9 @@
assertEquals("/my", mapping.getNamespace());
assertEquals("foo/actionName", mapping.getName());
- assertNull(mapping.getMethod());
+ assertNull(mapping.getMethod());
}
-
+
public void testGetMappingWithNamespaceSlash() throws Exception {
req.setupGetRequestURI("/my.hh/abc.action");
@@ -131,7 +127,7 @@
assertEquals("", mapping.getNamespace());
assertEquals("abc", mapping.getName());
-
+
req.setupGetAttribute(null);
req.addExpectedGetAttributeName("javax.servlet.include.servlet_path");
mapper = new DefaultActionMapper();
@@ -155,7 +151,7 @@
assertEquals("actionName", mapping.getName());
assertNull(mapping.getMethod());
}
-
+
public void testGetMappingWithUnknownNamespaceButFullNamespaceSelect()
throws Exception {
req.setupGetRequestURI("/bo/foo/actionName.action");
req.setupGetServletPath("/bo/foo/actionName.action");
@@ -211,7 +207,7 @@
ActionMapping mapping = mapper.getMapping(req, configManager);
assertEquals("/my/namespace/actionName.action",
mapper.getUriFromActionMapping(mapping));
}
-
+
public void testGetUriWithSemicolonPresent() throws Exception {
req.setupGetParameterMap(new HashMap());
req.setupGetRequestURI("/my/namespace/actionName.action;abc=123rty56");
@@ -236,14 +232,14 @@
assertEquals("/my/namespace/actionName!add.action",
mapper.getUriFromActionMapping(mapping));
}
-
+
public void testGetUriWithOriginalExtension() throws Exception {
ActionMapping mapping = new ActionMapping("actionName", "/ns", null,
new HashMap());
-
+
ActionMapping orig = new ActionMapping();
orig.setExtension("foo");
ActionContext.getContext().put(ServletActionContext.ACTION_MAPPING,
orig);
-
+
DefaultActionMapper mapper = new DefaultActionMapper();
assertEquals("/ns/actionName.foo",
mapper.getUriFromActionMapping(mapping));
}
@@ -263,7 +259,7 @@
assertEquals("actionName", mapping.getName());
assertNull(mapping.getMethod());
}
-
+
public void testGetMappingWithNoExtensionButUriHasExtension() throws
Exception {
req.setupGetParameterMap(new HashMap());
req.setupGetRequestURI("/my/namespace/actionName.html");
@@ -370,7 +366,7 @@
assertEquals(actionMapping.getName(), "myAction");
}
-
+
public void testActionPrefix_fromIEImageButton() throws Exception {
Map parameterMap = new HashMap();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.x", "");
@@ -426,17 +422,17 @@
DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
defaultActionMapper.setContainer(container);
ActionMapping actionMapping = defaultActionMapper.getMapping(request,
configManager);
-
+
StrutsResultSupport result = (StrutsResultSupport)
actionMapping.getResult();
assertNotNull(result);
assertTrue(result instanceof ServletRedirectResult);
-
+
assertEquals("myAction.action", result.getLocation());
// TODO: need to test location but there's noaccess to the
property/method, unless we use reflection
}
-
+
public void testRedirectActionPrefixWithEmptyExtension() throws Exception {
Map parameterMap = new HashMap();
parameterMap.put(DefaultActionMapper.REDIRECT_ACTION_PREFIX +
"myAction", "");
@@ -449,12 +445,12 @@
defaultActionMapper.setContainer(container);
defaultActionMapper.setExtensions(",,");
ActionMapping actionMapping = defaultActionMapper.getMapping(request,
configManager);
-
+
StrutsResultSupport result = (StrutsResultSupport)
actionMapping.getResult();
assertNotNull(result);
assertTrue(result instanceof ServletRedirectResult);
-
+
assertEquals("myAction", result.getLocation());
// TODO: need to test location but there's noaccess to the
property/method, unless we use reflection
@@ -488,7 +484,7 @@
assertTrue("Name not right: "+name, "foo.action".equals(name));
}
-
+
public void testDropExtensionWhenBlank() throws Exception {
DefaultActionMapper mapper = new DefaultActionMapper();
mapper.setExtensions("action,,");
@@ -500,6 +496,17 @@
assertNull(mapper.dropExtension("foo."));
}
+ public void testDropExtensionEmbeddedDot() throws Exception {
+ DefaultActionMapper mapper = new DefaultActionMapper();
+ mapper.setExtensions("action,,");
+
+ String name = mapper.dropExtension("/foo/bar-1.0/baz.action");
+ assertTrue("Name not right: "+name, "/foo/bar-1.0/baz".equals(name));
+
+ name = mapper.dropExtension("/foo/bar-1.0/baz");
+ assertTrue("Name not right: "+name, "/foo/bar-1.0/baz".equals(name));
+ }
+
public void testGetUriFromActionMapper1() throws Exception {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
@@ -639,7 +646,7 @@
assertEquals("myActionName!myMethod", uri);
}
-
+
public void testGetUriFromActionMapperWhenBlankExtension() throws
Exception {
DefaultActionMapper mapper = new DefaultActionMapper();
mapper.setExtensions(",,");