Author: cziegeler
Date: Thu Sep 27 15:21:15 2012
New Revision: 1391055
URL: http://svn.apache.org/viewvc?rev=1391055&view=rev
Log:
SLING-2543 : SlingPostServlet is not encoding redirect URLs. Apply patch from
James Philipotts
Modified:
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/SlingPostServletTest.java
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/PostRedirectTest.java
Modified:
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java?rev=1391055&r1=1391054&r2=1391055&view=diff
==============================================================================
---
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
(original)
+++
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
Thu Sep 27 15:21:15 2012
@@ -22,11 +22,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.scr.annotations.Component;
@@ -214,8 +214,8 @@ public class SlingPostServlet extends Sl
// check for redirect URL if processing succeeded
if (htmlResponse.isSuccessful()) {
- if (redirectIfNeeded(getRedirectUrl(request, htmlResponse),
response)) {
- return;
+ if (redirectIfNeeded(request, htmlResponse, response)) {
+ return;
}
}
@@ -223,22 +223,37 @@ public class SlingPostServlet extends Sl
htmlResponse.send(response, isSetStatus(request));
}
- /**
- * Redirects the HttpServletResponse, if redirectURL is not empty
- * @param redirectURL The computed redirect URL
- * @param response The HttpServletResponse to use for redirection
- * @return Whether a redirect was requested
- * @throws IOException
- */
- boolean redirectIfNeeded(String redirectURL,
- SlingHttpServletResponse response)
- throws IOException {
- if (redirectURL != null) {
-
response.sendRedirect(response.encodeRedirectURL(redirectURL));
- return true;
- }
- return false;
- }
+ /**
+ * Redirects the HttpServletResponse, if redirectURL is not empty
+ * @param htmlResponse
+ * @param request
+ * @param redirectURL The computed redirect URL
+ * @param response The HttpServletResponse to use for redirection
+ * @return Whether a redirect was requested
+ * @throws IOException
+ */
+ boolean redirectIfNeeded(SlingHttpServletRequest request, PostResponse
htmlResponse, SlingHttpServletResponse response)
+ throws IOException {
+ String redirectURL = getRedirectUrl(request, htmlResponse);
+ if (redirectURL != null) {
+ Matcher m = REDIRECT_WITH_SCHEME_PATTERN.matcher(redirectURL);
+ boolean hasScheme = m.matches();
+ String encodedURL;
+ if (hasScheme && m.group(2).length() > 0) {
+ encodedURL = m.group(1) +
response.encodeRedirectURL(m.group(2));
+ } else if (hasScheme) {
+ encodedURL = redirectURL;
+ } else {
+ log.debug("Request path is [{}]", request.getPathInfo());
+ encodedURL = response.encodeRedirectURL(redirectURL);
+ }
+ log.debug("redirecting to URL [{}] - encoded as [{}]",
redirectURL, encodedURL);
+ response.sendRedirect(encodedURL);
+ return true;
+ }
+ return false;
+ }
+ private static final Pattern REDIRECT_WITH_SCHEME_PATTERN =
Pattern.compile("^(https?://[^/]+)(.*)$");
/**
* Creates an instance of a PostResponse.
@@ -287,10 +302,11 @@ public class SlingPostServlet extends Sl
* @param ctx the post processor
* @return the redirect location or <code>null</code>
*/
- protected String getRedirectUrl(HttpServletRequest request, PostResponse
ctx) {
+ protected String getRedirectUrl(SlingHttpServletRequest request,
PostResponse ctx) {
// redirect param has priority (but see below, magic star)
String result =
request.getParameter(SlingPostConstants.RP_REDIRECT_TO);
if (result != null && ctx.getPath() != null) {
+ log.debug("redirect requested as [{}] for path [{}]", result,
ctx.getPath());
// redirect to created/modified Resource
int star = result.indexOf('*');
@@ -310,18 +326,23 @@ public class SlingPostServlet extends Sl
buf.append(result.substring(star + 1));
}
+ // Prepend request path if it ends with create suffix and
result isn't absolute
+ String requestPath = request.getPathInfo();
+ if
(requestPath.endsWith(SlingPostConstants.DEFAULT_CREATE_SUFFIX) &&
buf.charAt(0) != '/' &&
+ !REDIRECT_WITH_SCHEME_PATTERN.matcher(buf).matches()) {
+ buf.insert(0, requestPath);
+ }
+
// use the created path as the redirect result
result = buf.toString();
-
+
} else if
(result.endsWith(SlingPostConstants.DEFAULT_CREATE_SUFFIX)) {
// if the redirect has a trailing slash, append modified node
// name
result = result.concat(ResourceUtil.getName(ctx.getPath()));
}
- if (log.isDebugEnabled()) {
- log.debug("Will redirect to " + result);
- }
+ log.debug("Will redirect to {}", result);
}
return result;
}
Modified:
sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/SlingPostServletTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/SlingPostServletTest.java?rev=1391055&r1=1391054&r2=1391055&view=diff
==============================================================================
---
sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/SlingPostServletTest.java
(original)
+++
sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/SlingPostServletTest.java
Thu Sep 27 15:21:15 2012
@@ -21,21 +21,31 @@ package org.apache.sling.servlets.post.i
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
+import java.util.StringTokenizer;
import junit.framework.TestCase;
+import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;
import org.apache.sling.commons.testing.sling.MockSlingHttpServletResponse;
+import org.apache.sling.servlets.post.HtmlResponse;
import org.apache.sling.servlets.post.JSONResponse;
import org.apache.sling.servlets.post.PostResponse;
import org.apache.sling.servlets.post.SlingPostConstants;
import org.apache.sling.servlets.post.impl.helper.MediaRangeList;
public class SlingPostServletTest extends TestCase {
+
+ private SlingPostServlet servlet;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ servlet = new SlingPostServlet();
+ }
public void testIsSetStatus() {
StatusParamSlingHttpServletRequest req = new
StatusParamSlingHttpServletRequest();
- SlingPostServlet servlet = new SlingPostServlet();
// 1. null parameter, expect true
req.setStatusParam(null);
@@ -72,42 +82,82 @@ public class SlingPostServletTest extend
return null;
}
};
- SlingPostServlet servlet = new SlingPostServlet();
PostResponse result = servlet.createPostResponse(req);
assertTrue(result instanceof JSONResponse);
}
public void testRedirection() throws Exception {
- final String[] redirectLocation = new String[1];
- MockSlingHttpServletResponse resp = new MockSlingHttpServletResponse() {
- @Override
- public String encodeRedirectURL(String s) {
- try {
- return URLEncoder.encode(s, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- fail("Should have UTF-8?? " + e);
- return null;
- }
- }
-
- @Override
- public void sendRedirect(String s) throws IOException {
- redirectLocation[0] = s;
- }
- };
-
- SlingPostServlet servlet = new SlingPostServlet();
-
-
assertTrue(servlet.redirectIfNeeded("\u0414\u0440\u0443\u0433\u0430.html",
resp));
- assertEquals("Should encode UTF-8",
"%D0%94%D1%80%D1%83%D0%B3%D0%B0.html", redirectLocation[0]);
-
- redirectLocation[0] = null;
- assertTrue(servlet.redirectIfNeeded("fred.html", resp));
- assertEquals("Plain old ASCII passes through", "fred.html",
redirectLocation[0]);
-
- redirectLocation[0] = null;
- assertFalse(servlet.redirectIfNeeded(null, resp));
- assertNull("Shouldn't have encoded anything", redirectLocation[0]);
+ String utf8Path = "\u0414\u0440\u0443\u0433\u0430";
+ String encodedUtf8 = "%D0%94%D1%80%D1%83%D0%B3%D0%B0";
+ testRedirection("/", "/fred", "*.html", "/fred.html");
+ testRedirection("/xyz/", "/xyz/"+utf8Path, "*", "/xyz/"+encodedUtf8);
+ testRedirection("/", "/fred/abc", "http://forced", "http://forced");
+ testRedirection("/", "/fred/"+utf8Path, "http://forced/xyz/*",
"http://forced/xyz/"+encodedUtf8);
+ testRedirection("/", "/fred/"+utf8Path, null, null);
+ }
+
+ private void testRedirection(String requestPath, String resourcePath,
String redirect, String expected)
+ throws Exception {
+ RedirectServletResponse resp = new RedirectServletResponse();
+ SlingHttpServletRequest request = new RedirectServletRequest(redirect,
requestPath);
+ PostResponse htmlResponse = new HtmlResponse();
+ htmlResponse.setPath(resourcePath);
+ assertEquals(expected != null, servlet.redirectIfNeeded(request,
htmlResponse, resp));
+ assertEquals(expected, resp.redirectLocation);
+ }
+
+ /**
+ *
+ */
+ private final class RedirectServletRequest extends
MockSlingHttpServletRequest {
+
+ private String requestPath;
+ private String redirect;
+
+ private RedirectServletRequest(String redirect, String requestPath) {
+ super(null, null, null, null, null);
+ this.requestPath = requestPath;
+ this.redirect = redirect;
+ }
+
+ public String getPathInfo() {
+ return requestPath;
+ }
+
+ @Override
+ public String getParameter(String name) {
+ return SlingPostConstants.RP_REDIRECT_TO.equals(name) ? redirect :
null;
+ }
+ }
+
+ private final class RedirectServletResponse extends
MockSlingHttpServletResponse {
+
+ private String redirectLocation;
+
+ @Override
+ public String encodeRedirectURL(String s) {
+ StringTokenizer st = new StringTokenizer(s, "/", true);
+ StringBuilder sb = new StringBuilder();
+ try {
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if ("/".equals(token)) {
+ sb.append(token);
+ } else {
+ sb.append(URLEncoder.encode(token, "UTF-8"));
+ }
+ }
+ } catch (UnsupportedEncodingException e) {
+ fail("Should have UTF-8?? " + e);
+ return null;
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public void sendRedirect(String s) throws IOException {
+ redirectLocation = s;
+ }
}
private static class StatusParamSlingHttpServletRequest extends
Modified:
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/PostRedirectTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/PostRedirectTest.java?rev=1391055&r1=1391054&r2=1391055&view=diff
==============================================================================
---
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/PostRedirectTest.java
(original)
+++
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/PostRedirectTest.java
Thu Sep 27 15:21:15 2012
@@ -31,6 +31,19 @@ public class PostRedirectTest extends Ht
private String postUrl = HTTP_BASE_URL + "/" + postPath
+ SlingPostConstants.DEFAULT_CREATE_SUFFIX;
+ public void testEncodedRedirect() throws IOException {
+ final Map<String, String> params = new HashMap<String, String>();
+ params.put(":redirect", "*");
+ params.put(":name", "\u0414\u0440\u0443\u0433\u0430");
+ final Map<String, String> headers = new HashMap<String, String>();
+ headers.put("Referer", "http://referer/");
+
+ final String location = testClient.createNode(postUrl, params, headers,
+ false);
+ assertTrue("With UTF-8 in path, redirect must be encoded :"+location,
+ location.contains(postPath + "/%D0%94%D1%80%D1%83%D0%B3%D0%B0"));
+ }
+
public void testForcedRedirect() throws IOException {
final Map<String, String> params = new HashMap<String, String>();
params.put(":redirect", "http://forced");