incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r1391055 - in /sling/trunk: bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/ bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/ launchpad/integration-tests/src/main/java/org/apache/sling/launchp...
Date Thu, 27 Sep 2012 15:21:16 GMT
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");



Mime
View raw message