src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java
changeset 52554 5f1ca46703f9
parent 52106 76d526565453
child 53256 bd8df96decba
--- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java	Wed Nov 14 17:16:44 2018 +0530
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java	Wed Nov 14 14:23:21 2018 +0000
@@ -45,6 +45,7 @@
 import java.net.InetSocketAddress;
 import java.net.URI;
 import java.net.URLPermission;
+import java.net.http.HttpClient;
 import java.net.http.HttpHeaders;
 import java.net.http.HttpTimeoutException;
 import java.nio.ByteBuffer;
@@ -75,6 +76,7 @@
 import static java.lang.String.format;
 import static java.util.Objects.requireNonNull;
 import static java.util.stream.Collectors.joining;
+import jdk.internal.net.http.HttpRequestImpl;
 
 /**
  * Miscellaneous utilities
@@ -127,14 +129,23 @@
 
     public static final BiPredicate<String,String> ACCEPT_ALL = (x,y) -> true;
 
-    private static final Set<String> DISALLOWED_HEADERS_SET;
+    private static final Set<String> DISALLOWED_HEADERS_SET = getDisallowedHeaders();
+
+    private static Set<String> getDisallowedHeaders() {
+        Set<String> headers = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        headers.addAll(Set.of("connection", "content-length", "expect", "host", "upgrade"));
 
-    static {
-        // A case insensitive TreeSet of strings.
-        TreeSet<String> treeSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
-        treeSet.addAll(Set.of("connection", "content-length",
-                "date", "expect", "from", "host", "upgrade", "via", "warning"));
-        DISALLOWED_HEADERS_SET = Collections.unmodifiableSet(treeSet);
+        String v = getNetProperty("jdk.httpclient.allowRestrictedHeaders");
+        if (v != null) {
+            // any headers found are removed from set.
+            String[] tokens = v.trim().split(",");
+            for (String token : tokens) {
+                headers.remove(token);
+            }
+            return Collections.unmodifiableSet(headers);
+        } else {
+            return Collections.unmodifiableSet(headers);
+        }
     }
 
     public static final BiPredicate<String, String>
@@ -156,6 +167,19 @@
                 return true;
             };
 
+    // Headers that are not generally restricted, and can therefore be set by users,
+    // but can in some contexts be overridden by the implementation.
+    // Currently, only contains "Authorization" which will
+    // be overridden, when an Authenticator is set on the HttpClient.
+    // Needs to be BiPred<String,String> to fit with general form of predicates
+    // used by caller.
+
+    public static final BiPredicate<String, String> CONTEXT_RESTRICTED(HttpClient client) {
+        return (k, v) -> client.authenticator() == null ||
+                ! (k.equalsIgnoreCase("Authorization")
+                        && k.equalsIgnoreCase("Proxy-Authorization"));
+    }
+
     private static final Predicate<String> IS_PROXY_HEADER = (k) ->
             k != null && k.length() > 6 && "proxy-".equalsIgnoreCase(k.substring(0,6));
     private static final Predicate<String> NO_PROXY_HEADER =
@@ -323,8 +347,8 @@
                                                     Stream<String> headers) {
         String urlString = new StringBuilder()
                 .append(uri.getScheme()).append("://")
-                .append(uri.getAuthority())
-                .append(uri.getPath()).toString();
+                .append(uri.getRawAuthority())
+                .append(uri.getRawPath()).toString();
 
         StringBuilder actionStringBuilder = new StringBuilder(method);
         String collected = headers.collect(joining(","));
@@ -795,6 +819,33 @@
     }
 
     /**
+     * Return the host string from a HttpRequestImpl
+     *
+     * @param request
+     * @return
+     */
+    public static String hostString(HttpRequestImpl request) {
+        URI uri = request.uri();
+        int port = uri.getPort();
+        String host = uri.getHost();
+
+        boolean defaultPort;
+        if (port == -1) {
+            defaultPort = true;
+        } else if (uri.getScheme().equalsIgnoreCase("https")) {
+            defaultPort = port == 443;
+        } else {
+            defaultPort = port == 80;
+        }
+
+        if (defaultPort) {
+            return host;
+        } else {
+            return host + ":" + Integer.toString(port);
+        }
+    }
+
+    /**
      * Get a logger for debug HPACK traces.The logger should only be used
      * with levels whose severity is {@code <= DEBUG}.
      *