8203850: java.net.http HTTP client should allow specifying Origin and Referer headers
Reviewed-by: chegar, dfuchs
This commit is contained in:
parent
55692eb0ca
commit
96b43418b5
@ -133,9 +133,7 @@ public final class Utils {
|
|||||||
// A case insensitive TreeSet of strings.
|
// A case insensitive TreeSet of strings.
|
||||||
TreeSet<String> treeSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
|
TreeSet<String> treeSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
treeSet.addAll(Set.of("connection", "content-length",
|
treeSet.addAll(Set.of("connection", "content-length",
|
||||||
"date", "expect", "from", "host", "origin",
|
"date", "expect", "from", "host", "upgrade", "via", "warning"));
|
||||||
"referer", "upgrade",
|
|
||||||
"via", "warning"));
|
|
||||||
DISALLOWED_HEADERS_SET = Collections.unmodifiableSet(treeSet);
|
DISALLOWED_HEADERS_SET = Collections.unmodifiableSet(treeSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,15 +337,31 @@ public class RequestBuilderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// headers that are allowed now, but weren't before
|
||||||
|
private static final Set<String> FORMERLY_RESTRICTED = Set.of("referer", "origin",
|
||||||
|
"OriGin", "Referer");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFormerlyRestricted() throws URISyntaxException {
|
||||||
|
URI uri = new URI("http://localhost:80/test/");
|
||||||
|
URI otherURI = new URI("http://www.foo.com/test/");
|
||||||
|
for (String header : FORMERLY_RESTRICTED) {
|
||||||
|
HttpRequest req = HttpRequest.newBuilder(uri)
|
||||||
|
.header(header, otherURI.toString())
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final Set<String> RESTRICTED = Set.of("connection", "content-length",
|
private static final Set<String> RESTRICTED = Set.of("connection", "content-length",
|
||||||
"date", "expect", "from", "host", "origin",
|
"date", "expect", "from", "host",
|
||||||
"referer", "upgrade", "via", "warning",
|
"upgrade", "via", "warning",
|
||||||
"Connection", "Content-Length",
|
"Connection", "Content-Length",
|
||||||
"DATE", "eXpect", "frOm", "hosT", "origIN",
|
"DATE", "eXpect", "frOm", "hosT",
|
||||||
"ReFerer", "upgradE", "vIa", "Warning",
|
"upgradE", "vIa", "Warning",
|
||||||
"CONNection", "CONTENT-LENGTH",
|
"CONNection", "CONTENT-LENGTH",
|
||||||
"Date", "EXPECT", "From", "Host", "Origin",
|
"Date", "EXPECT", "From", "Host",
|
||||||
"Referer", "Upgrade", "Via", "WARNING");
|
"Upgrade", "Via", "WARNING");
|
||||||
|
|
||||||
interface WithHeader {
|
interface WithHeader {
|
||||||
HttpRequest.Builder withHeader(HttpRequest.Builder builder, String name, String value);
|
HttpRequest.Builder withHeader(HttpRequest.Builder builder, String name, String value);
|
||||||
|
@ -57,21 +57,25 @@ import java.net.InetAddress;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpHeaders;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import java.net.http.HttpResponse.BodyHandlers;
|
import java.net.http.HttpResponse.BodyHandlers;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static java.lang.System.err;
|
import static java.lang.System.err;
|
||||||
import static java.lang.System.out;
|
import static java.lang.System.out;
|
||||||
import static java.net.http.HttpClient.Builder.NO_PROXY;
|
import static java.net.http.HttpClient.Builder.NO_PROXY;
|
||||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||||
|
import org.testng.Assert;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
public class SpecialHeadersTest implements HttpServerAdapters {
|
public class SpecialHeadersTest implements HttpServerAdapters {
|
||||||
@ -91,6 +95,13 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
|||||||
{"User-Agent: camel-cased"},
|
{"User-Agent: camel-cased"},
|
||||||
{"user-agent: all-lower-case"},
|
{"user-agent: all-lower-case"},
|
||||||
{"user-Agent: mixed"},
|
{"user-Agent: mixed"},
|
||||||
|
// headers which were restricted before and are now allowable
|
||||||
|
{"referer: lower"},
|
||||||
|
{"Referer: normal"},
|
||||||
|
{"REFERER: upper"},
|
||||||
|
{"origin: lower"},
|
||||||
|
{"Origin: normal"},
|
||||||
|
{"ORIGIN: upper"},
|
||||||
};
|
};
|
||||||
|
|
||||||
@DataProvider(name = "variants")
|
@DataProvider(name = "variants")
|
||||||
@ -168,6 +179,50 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "variants")
|
||||||
|
void testHomeMadeIllegalHeader(String uriString, String headerNameAndValue, boolean sameClient) throws Exception {
|
||||||
|
out.println("\n--- Starting ");
|
||||||
|
final URI uri = URI.create(uriString);
|
||||||
|
|
||||||
|
HttpClient client = HttpClient.newBuilder()
|
||||||
|
.proxy(NO_PROXY)
|
||||||
|
.sslContext(sslContext)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Test a request which contains an illegal header created
|
||||||
|
HttpRequest req = new HttpRequest() {
|
||||||
|
@Override public Optional<BodyPublisher> bodyPublisher() {
|
||||||
|
return Optional.of(BodyPublishers.noBody());
|
||||||
|
}
|
||||||
|
@Override public String method() {
|
||||||
|
return "GET";
|
||||||
|
}
|
||||||
|
@Override public Optional<Duration> timeout() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
@Override public boolean expectContinue() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override public URI uri() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
@Override public Optional<HttpClient.Version> version() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
@Override public HttpHeaders headers() {
|
||||||
|
Map<String, List<String>> map = Map.of("via", List.of("http://foo.com"));
|
||||||
|
return HttpHeaders.of(map, (x, y) -> true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
HttpResponse<String> response = client.send(req, BodyHandlers.ofString());
|
||||||
|
Assert.fail("Unexpected reply: " + response);
|
||||||
|
} catch (IllegalArgumentException ee) {
|
||||||
|
out.println("Got IAE as expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test(dataProvider = "variants")
|
@Test(dataProvider = "variants")
|
||||||
void testAsync(String uriString, String headerNameAndValue, boolean sameClient) {
|
void testAsync(String uriString, String headerNameAndValue, boolean sameClient) {
|
||||||
out.println("\n--- Starting ");
|
out.println("\n--- Starting ");
|
||||||
@ -259,7 +314,10 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
|||||||
https2TestServer.stop();
|
https2TestServer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A handler that returns, as its body, the exact received request URI. */
|
/** A handler that returns, as its body, the exact received request URI.
|
||||||
|
* The header whose name is in the URI query and is set in the request is
|
||||||
|
* returned in the response with its name prefixed by X-
|
||||||
|
*/
|
||||||
static class HttpUriStringHandler implements HttpTestHandler {
|
static class HttpUriStringHandler implements HttpTestHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handle(HttpTestExchange t) throws IOException {
|
public void handle(HttpTestExchange t) throws IOException {
|
||||||
|
Loading…
Reference in New Issue
Block a user