You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@slider.apache.org by el...@apache.org on 2015/01/29 18:23:41 UTC

[18/28] incubator-slider git commit: SLIDER-782 Failed attempt to integrate with the AmWebClient logic for handling redirects across http/https boundary. That code only works for GET operations.

SLIDER-782 Failed attempt to integrate with the AmWebClient logic for handling redirects across http/https boundary. That code only works for GET operations.


Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/6c038b41
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/6c038b41
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/6c038b41

Branch: refs/heads/develop
Commit: 6c038b4132fe8bfdca493d3ef9158bfd838db9db
Parents: 73e1639
Author: Steve Loughran <st...@apache.org>
Authored: Fri Jan 23 12:46:34 2015 +0000
Committer: Steve Loughran <st...@apache.org>
Committed: Fri Jan 23 12:48:16 2015 +0000

----------------------------------------------------------------------
 .../core/restclient/UgiJerseyBinding.java       | 12 +++-
 .../restclient/UrlConnectionOperations.java     | 69 ++++++++++++++++++--
 2 files changed, 73 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/6c038b41/slider-core/src/main/java/org/apache/slider/core/restclient/UgiJerseyBinding.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/core/restclient/UgiJerseyBinding.java b/slider-core/src/main/java/org/apache/slider/core/restclient/UgiJerseyBinding.java
index 76407c6..10ce1ce 100644
--- a/slider-core/src/main/java/org/apache/slider/core/restclient/UgiJerseyBinding.java
+++ b/slider-core/src/main/java/org/apache/slider/core/restclient/UgiJerseyBinding.java
@@ -33,6 +33,7 @@ import org.apache.hadoop.yarn.webapp.NotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -74,7 +75,7 @@ public class UgiJerseyBinding implements
 
   /**
    * Get a URL connection. 
-   * @param url
+   * @param url URL to connect to
    * @return the connection
    * @throws IOException any problem. {@link AuthenticationException} 
    * errors are wrapped
@@ -82,6 +83,10 @@ public class UgiJerseyBinding implements
   @Override
   public HttpURLConnection getHttpURLConnection(URL url) throws IOException {
     try {
+      // open a connection handling status codes and so redirections
+      // but as it opens a connection, it's less useful than you think.
+//      return operations.openConnectionRedirecting(url);
+      
       return operations.openConnection(url);
     } catch (AuthenticationException e) {
       throw new IOException(e);
@@ -124,10 +129,11 @@ public class UgiJerseyBinding implements
     ClientResponse response = ex.getResponse();
     int resultCode = response.getStatus();
     String msg = verb.toString() + " " + url;
-    if (resultCode == 404) {
+    if (resultCode == HttpServletResponse.SC_NOT_FOUND) {
       return (IOException) new PathNotFoundException(url).initCause(ex);
     }
-    if (resultCode == 401) {
+    if (resultCode == HttpServletResponse.SC_UNAUTHORIZED
+        || resultCode == HttpServletResponse.SC_FORBIDDEN) {
       return (IOException) new PathAccessDeniedException(url).initCause(ex);
     }
     // all other error codes

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/6c038b41/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java b/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
index 328684e..e6b08c1 100644
--- a/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
+++ b/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
@@ -31,10 +31,13 @@ import org.apache.hadoop.yarn.webapp.NotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.HttpHeaders;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.HttpURLConnection;
+import java.net.URI;
 import java.net.URL;
 
 /**
@@ -74,7 +77,8 @@ public class UrlConnectionOperations extends Configured  {
   }
 
   /**
-   * Opens a url with read and connect timeouts
+   * Opens a url with cache disabled, redirect handled in 
+   * (JDK) implementation.
    *
    * @param url to open
    * @return URLConnection
@@ -84,14 +88,70 @@ public class UrlConnectionOperations extends Configured  {
   public HttpURLConnection openConnection(URL url) throws
       IOException,
       AuthenticationException {
-    Preconditions.checkArgument(url.getPort() != 0, "no port");
-    HttpURLConnection conn =
-        (HttpURLConnection) connectionFactory.openConnection(url, useSpnego);
+
+    HttpURLConnection conn = innerOpenConnection(url);
     conn.setUseCaches(false);
     conn.setInstanceFollowRedirects(true);
     return conn;
   }
 
+
+  /**
+   * Opens a url.
+   * <p>
+   *   This implementation
+   *   <ol>
+   *     <li>Handles protocol switching during redirects</li>
+   *     <li>Handles 307 responses "redirect with same verb"</li>
+   *   </ol>
+   *
+   * @param url to open
+   * @return URLConnection
+   * @throws IOException
+   * @throws AuthenticationException authentication failure
+   */
+  public HttpURLConnection openConnectionRedirecting(URL url) throws
+      IOException,
+      AuthenticationException {
+    HttpURLConnection connection = innerOpenConnection(url);
+    connection.setUseCaches(false);
+    int responseCode = connection.getResponseCode();
+    if (responseCode == HttpServletResponse.SC_MOVED_TEMPORARILY 
+        || responseCode == HttpServletResponse.SC_TEMPORARY_REDIRECT) {
+      log.debug("Redirected with response {}", responseCode);
+      // is a redirect - are we changing schemes?
+      String redirectLocation = connection.getHeaderField(HttpHeaders.LOCATION);
+      String originalScheme = url.getProtocol();
+      String redirectScheme = URI.create(redirectLocation).getScheme();
+      boolean buildNewUrl = false;
+      if (!originalScheme.equals(redirectScheme)) {
+        // need to fake it out by doing redirect ourselves
+        log.debug("Protocol change during redirect");
+        buildNewUrl = true;
+      } else if (responseCode == HttpServletResponse.SC_TEMPORARY_REDIRECT) {
+        // 307 response
+        buildNewUrl = true;
+      }
+
+      if (buildNewUrl) {
+        // perform redirect ourselves
+        log.debug("Redirecting {} to URL {}",
+            url, redirectLocation);
+        URL redirectURL = new URL(redirectLocation);
+        connection = innerOpenConnection(url);
+      }
+    }
+
+    return connection;
+  }
+
+  protected HttpURLConnection innerOpenConnection(URL url) throws
+      IOException,
+      AuthenticationException {
+    Preconditions.checkArgument(url.getPort() != 0, "no port");
+    return (HttpURLConnection) connectionFactory.openConnection(url, useSpnego);
+  }
+
   public HttpOperationResponse execGet(URL url) throws
       IOException,
       AuthenticationException {
@@ -121,7 +181,6 @@ public class UrlConnectionOperations extends Configured  {
       if (doOutput) {
         conn.setRequestProperty("Content-Type", contentType);
       }
-      
 
       // now do the connection
       conn.connect();