diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java index 4d53a85ab78..81c693ea192 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java @@ -39,6 +39,7 @@ import java.util.Optional; import java.net.http.HttpClient; import java.net.http.HttpHeaders; import java.net.http.HttpRequest; +import java.util.function.BiPredicate; import jdk.internal.net.http.common.Alpns; import jdk.internal.net.http.common.HttpHeadersBuilder; @@ -148,7 +149,11 @@ public class HttpRequestImpl extends HttpRequest implements WebSocketRequest { String method, HttpRequestImpl other, boolean mayHaveBody) { - return new HttpRequestImpl(uri, method, other, mayHaveBody); + if (uri.getScheme().equalsIgnoreCase(other.uri.getScheme()) && + uri.getRawAuthority().equals(other.uri.getRawAuthority())) { + return new HttpRequestImpl(uri, method, other, mayHaveBody, Optional.empty()); + } + return new HttpRequestImpl(uri, method, other, mayHaveBody, Optional.of(Utils.ALLOWED_REDIRECT_HEADERS)); } /** Returns a new instance suitable for authentication. */ @@ -168,9 +173,19 @@ public class HttpRequestImpl extends HttpRequest implements WebSocketRequest { String method, HttpRequestImpl other, boolean mayHaveBody) { + this(uri, method, other, mayHaveBody, Optional.empty()); + } + + private HttpRequestImpl(URI uri, + String method, + HttpRequestImpl other, + boolean mayHaveBody, + Optional> redirectHeadersFilter) { assert method == null || Utils.isValidName(method); - this.method = method == null? "GET" : method; - this.userHeaders = other.userHeaders; + this.method = method == null ? "GET" : method; + HttpHeaders userHeaders = redirectHeadersFilter.isPresent() ? + HttpHeaders.of(other.userHeaders.map(), redirectHeadersFilter.get()) : other.userHeaders; + this.userHeaders = userHeaders; this.isWebSocket = other.isWebSocket; this.systemHeadersBuilder = new HttpHeadersBuilder(); if (userHeaders.firstValue("User-Agent").isEmpty()) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java index eecabfd96f9..4fb1896c51e 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java @@ -188,6 +188,18 @@ public final class Utils { public static final BiPredicate ALLOWED_HEADERS = (header, unused) -> !DISALLOWED_HEADERS_SET.contains(header); + private static final Set DISALLOWED_REDIRECT_HEADERS_SET = getDisallowedRedirectHeaders(); + + private static Set getDisallowedRedirectHeaders() { + Set headers = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + headers.addAll(Set.of("Authorization", "Cookie", "Origin", "Referer", "Host")); + + return Collections.unmodifiableSet(headers); + } + + public static final BiPredicate + ALLOWED_REDIRECT_HEADERS = (header, _) -> !DISALLOWED_REDIRECT_HEADERS_SET.contains(header); + public static final BiPredicate VALIDATE_USER_HEADER = (name, value) -> { assert name != null : "null header name"; diff --git a/test/jdk/java/net/httpclient/DigestEchoClient.java b/test/jdk/java/net/httpclient/DigestEchoClient.java index 7b4f7fd3462..0aa70a26586 100644 --- a/test/jdk/java/net/httpclient/DigestEchoClient.java +++ b/test/jdk/java/net/httpclient/DigestEchoClient.java @@ -261,8 +261,9 @@ public class DigestEchoClient { } try { for (DigestEchoServer.HttpAuthType authType : types) { - // The test server does not support PROXY305 properly - if (authType == DigestEchoServer.HttpAuthType.PROXY305) continue; + // The test server does not support PROXY305 or SERVER307 properly + if (authType == DigestEchoServer.HttpAuthType.PROXY305 || + authType == DigestEchoServer.HttpAuthType.SERVER307) continue; EnumSet basics = EnumSet.of(DigestEchoServer.HttpAuthSchemeType.BASICSERVER, DigestEchoServer.HttpAuthSchemeType.BASIC);