--- 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}.
*