8196902: Better HTTP Redirection
authormichaelm
Tue, 10 Jul 2018 08:20:13 +0100
changeset 52169 ca48ad1b6e21
parent 52168 0c50240bf61d
child 52170 2990f1e1c325
8196902: Better HTTP Redirection Reviewed-by: dfuchs Contributed-by: chris.hegarty@oracle.com
src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Fri Jun 29 10:28:05 2018 +0530
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Jul 10 08:20:13 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2725,6 +2725,8 @@
             // doesn't know about proxy.
             useProxyResponseCode = true;
         } else {
+            final URL prevURL = url;
+
             // maintain previous headers, just change the name
             // of the file we're getting
             url = locUrl;
@@ -2753,6 +2755,14 @@
                 poster = null;
                 if (!checkReuseConnection())
                     connect();
+
+                if (!sameDestination(prevURL, url)) {
+                    // Ensures pre-redirect user-set cookie will not be reset.
+                    // CookieHandler, if any, will be queried to determine
+                    // cookies for redirected URL, if any.
+                    userCookies = null;
+                    userCookies2 = null;
+                }
             } else {
                 if (!checkReuseConnection())
                     connect();
@@ -2775,11 +2785,52 @@
                     }
                     requests.set("Host", host);
                 }
+
+                if (!sameDestination(prevURL, url)) {
+                    // Redirecting to a different destination will drop any
+                    // security-sensitive headers, regardless of whether
+                    // they are user-set or not. CookieHandler, if any, will be
+                    // queried to determine cookies for redirected URL, if any.
+                    userCookies = null;
+                    userCookies2 = null;
+                    requests.remove("Cookie");
+                    requests.remove("Cookie2");
+                    requests.remove("Authorization");
+
+                    // check for preemptive authorization
+                    AuthenticationInfo sauth =
+                            AuthenticationInfo.getServerAuth(url, getAuthenticatorKey());
+                    if (sauth != null && sauth.supportsPreemptiveAuthorization() ) {
+                        // Sets "Authorization"
+                        requests.setIfNotSet(sauth.getHeaderName(), sauth.getHeaderValue(url,method));
+                        currentServerCredentials = sauth;
+                    }
+                }
             }
         }
         return true;
     }
 
+    /* Returns true iff the given URLs have the same host and effective port. */
+    private static boolean sameDestination(URL firstURL, URL secondURL) {
+        assert firstURL.getProtocol().equalsIgnoreCase(secondURL.getProtocol()):
+               "protocols not equal: " + firstURL +  " - " + secondURL;
+
+        if (!firstURL.getHost().equalsIgnoreCase(secondURL.getHost()))
+            return false;
+
+        int firstPort = firstURL.getPort();
+        if (firstPort == -1)
+            firstPort = firstURL.getDefaultPort();
+        int secondPort = secondURL.getPort();
+        if (secondPort == -1)
+            secondPort = secondURL.getDefaultPort();
+        if (firstPort != secondPort)
+            return false;
+
+        return true;
+    }
+
     /* dummy byte buffer for reading off socket prior to closing */
     byte[] cdata = new byte [128];