问题
Here's my code:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://127.0.0.1:8081/"))
.header("Host", "test.example.com")
.build();
client.send(request, HttpResponse.BodyHandlers.ofString());
As a result I see that the above code sends:
GET / HTTP/1.1
Connection: Upgrade, HTTP2-Settings
Content-Length: 0
Host: 127.0.0.1:8081
HTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA
Upgrade: h2c
User-Agent: Java-http-client/10
Host: test.example.com
As you can see it sends two Host
headers (the one from URI and the one I specified), but I would like it to send the Host
header that I specified, not the one from the URI.
Is it possible with this client?
EDIT: In Java 11, it gets even worse (you need to change the client.send line to: client.send(request, HttpResponse.BodyHandlers.ofString());
):
java.lang.IllegalArgumentException: restricted header name: "Host"
How can I customize that header (needed for testing of virtual hosts)?
I also tried the setHeader
and get exactly the same problem (either double Host
headers, or the exception).
EDIT: I reported a JDK bug.
回答1:
As of Java 12 (EA build 22) it has been solved by additional property jdk.httpclient.allowRestrictedHeaders
(see https://bugs.openjdk.java.net/browse/JDK-8213696).
So now one can override Host
(or any other restricted header) by executing the code with:
java -Djdk.httpclient.allowRestrictedHeaders=host ...
回答2:
The behavior from the Java11 client code seems correct. The Host section elaborates on the details. By the way, from the documentation of HttpRequest
builder header(String name, String value)
:
* @throws IllegalArgumentException if the header name or value is not
* valid, see <a href="https://tools.ietf.org/html/rfc7230#section-3.2">
* RFC 7230 section-3.2</a>, or the header name or value is restricted
* by the implementation.
Update: See this, for answer pertaining to JDK/12.
来源:https://stackoverflow.com/questions/52315472/how-to-customise-host-header-in-java-http-client