You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2013/09/26 17:54:57 UTC

svn commit: r1526586 - in /cxf/trunk: rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java

Author: sergeyb
Date: Thu Sep 26 15:54:57 2013
New Revision: 1526586

URL: http://svn.apache.org/r1526586
Log:
[CXF-5122] Using URI.resolve to resolve relative redirects, and optionally restricting a number of redirects

Modified:
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java

Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java?rev=1526586&r1=1526585&r2=1526586&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java (original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java Thu Sep 26 15:54:57 2013
@@ -166,6 +166,7 @@ public abstract class HTTPConduit 
     
     private static final String AUTO_REDIRECT_SAME_HOST_ONLY = "http.redirect.same.host.only";
     private static final String AUTO_REDIRECT_ALLOW_REL_URI = "http.redirect.relative.uri";
+    private static final String MAX_AUTO_REDIRECT_COUNT = "max.http.redirect.count";
     
     
     private static final String HTTP_POST_METHOD = "POST";
@@ -1411,8 +1412,8 @@ public abstract class HTTPConduit 
             String urlString = url.toString();
             
             try {
-                detectRedirectLoop(conduitName, urlString, newURL, outMessage);
                 newURL = convertToAbsoluteUrlIfNeeded(conduitName, urlString, newURL, outMessage);
+                detectRedirectLoop(conduitName, urlString, newURL, outMessage);
                 checkSameBaseUriRedirect(conduitName, urlString, newURL, outMessage);
             } catch (IOException ex) {
                 // Consider introducing ClientRedirectException instead - it will require
@@ -1756,22 +1757,7 @@ public abstract class HTTPConduit 
         if (newURL != null && !newURL.startsWith("http")) {
             
             if (MessageUtils.isTrue(message.getContextualProperty(AUTO_REDIRECT_ALLOW_REL_URI))) {
-                
-                int queryInd = lastURL.lastIndexOf('?');
-                String query = queryInd == -1 ? null : lastURL.substring(queryInd); 
-                String newAbsURL = queryInd == -1 ? lastURL : lastURL.substring(0, queryInd);
-                if (newAbsURL.endsWith("/")) {
-                    newAbsURL = newAbsURL.substring(0, newAbsURL.length() - 1);
-                }
-                newAbsURL = newAbsURL + newURL;
-                if (query != null) {
-                    if (newAbsURL.lastIndexOf("?") != -1) {
-                        newAbsURL += "&";
-                        query = query.substring(1);
-                    }
-                    newAbsURL += query;
-                }    
-                return newAbsURL;
+                return URI.create(lastURL).resolve(newURL).toString(); 
             } else {
                 String msg = "Relative Redirect detected on Conduit '" 
                     + conduitName + "' on '" + newURL + "'";
@@ -1793,22 +1779,27 @@ public abstract class HTTPConduit 
         if (visitedURLs == null) {
             visitedURLs = new HashSet<String>();
             message.put(KEY_VISITED_URLS, visitedURLs);
+        } else {
+            Object maxCountProp = message.getContextualProperty(MAX_AUTO_REDIRECT_COUNT);
+            if (maxCountProp != null) {
+                Integer maxCount = maxCountProp instanceof Integer 
+                    ? (Integer)maxCountProp : Integer.valueOf((String)maxCountProp);
+                if (visitedURLs.size() == maxCount) {    
+                    String msg = "Too many redirects detected on Conduit '" + conduitName + "'";
+                    LOG.log(Level.INFO, msg);
+                    throw new IOException(msg);
+                }
+            }
         }
         visitedURLs.add(lastURL);
-        if (newURL != null) {
-            if (visitedURLs.contains(newURL)) {
-                // See if we are being redirected in a loop as best we can,
-                // using string equality on URL.
-                // We are in a redirect loop; -- bail
-                String msg = "Redirect loop detected on Conduit '" 
-                    + conduitName + "' on '" + newURL + "'";
-                LOG.log(Level.INFO, msg);
-                throw new IOException(msg);
-            }
-            // Important to prevent looping on relative URIs
-            if (!newURL.startsWith("http")) {
-                visitedURLs.add(newURL);
-            }
+        if (newURL != null && visitedURLs.contains(newURL)) {
+            // See if we are being redirected in a loop as best we can,
+            // using string equality on URL.
+            // We are in a redirect loop; -- bail
+            String msg = "Redirect loop detected on Conduit '" 
+                + conduitName + "' on '" + newURL + "'";
+            LOG.log(Level.INFO, msg);
+            throw new IOException(msg);
         }
     }   
     private static void detectAuthorizationLoop(String conduitName, Message message, 

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=1526586&r1=1526585&r2=1526586&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Thu Sep 26 15:54:57 2013
@@ -167,9 +167,9 @@ public class BookStore {
                                        @QueryParam("loop") boolean loop) {
         if (done == null) {
             if (loop) {
-                return Response.status(303).header("Location", "/?a").build();                
+                return Response.status(303).header("Location", "relative?loop=true").build();                
             } else {
-                return Response.status(303).header("Location", "/?redirect=true").build();    
+                return Response.status(303).header("Location", "relative?redirect=true").build();    
             }
         } else {
             return Response.ok(new Book("CXF", 124L), "application/xml").build();