vertx-web
vertx-web copied to clipboard
Lose charset in application/x-www-form-urlencoded?
I use sendForm to request, I set a header Content-Type: application/x-www-form-urlencoded; charset=UTF-8, but I found actual request Content-Type is application/x-www-form-urlencoded , it's not should be.
Vertx override my header in here of HttpContext#handleCreateRequest:
multipartForm.headers().forEach(header -> { requestOptions.putHeader(header.getKey(), header.getValue()); });
Version
vertx-core:4.3.5 vertx-web-client:4.3.5 JVM:1.8
Steps to reproduce
- set
Content-Type: application/x-www-form-urlencoded; charset=UTF-8to header. - call
sendForm - look message in tcpdump.
I don't think it's a bug, but just an implicit behaviour:
HttpRequestImpl::sendForm method would set the MultipartForm parts' charset to UTF-8 already. See: src/main/java/io/vertx/ext/web/client/impl/HttpRequestImpl.java.
If you call the sendForm method with the second argument of any other charsets different to UTF-8, the charset specification from "content-type" header would be ignored.
I tried it out by adding this test case to WebClientTest:
@Test
public void testWwwFormUrlEncodedWithCharset() throws Exception {
this.server.requestHandler(req -> {
req.body()
.onComplete(onSuccess(body -> {
MultiMap headers = req.headers();
System.out.println("body = " + body);
try {
if (!headers.contains("content-type")) {
throw new AssertionError("'content-type' header missing.");
}
String contentTypeHeaderValue = headers.get("content-type");
if (!contentTypeHeaderValue.equals("application/x-www-form-urlencoded; charset=UTF-8")) {
throw new AssertionError(String.format("Unexpected 'content-type' header value: '%s'.", contentTypeHeaderValue));
}
} finally {
req.response().end();
}
}));
});
startServer();
MultiMap form = MultiMap.caseInsensitiveMultiMap();
form.add("param1", "param1_value");
HttpRequest<Buffer> builder = webClient.post("/somepath");
builder.putHeader("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
builder.sendForm(form, StandardCharsets.UTF_16.toString()).onComplete(onSuccess(resp -> complete()));
await();
}
Test result:
May 09, 2023 3:35:52 AM io.vertx.test.core.AsyncTestBase
INFO: Starting test: WebClientTest#testWwwFormUrlEncodedWithCharset
body = �� p a r a m 1�� =�� p a r a m 1 _ v a l u e
May 09, 2023 3:35:53 AM io.vertx.core.impl.ContextBase
SEVERE: Unhandled exception
java.lang.AssertionError: Unexpected 'content-type' header value: 'application/x-www-form-urlencoded'.
at io.vertx.ext.web.client.WebClientTest.lambda$testWwwFormUrlEncodedWithCharset$122(WebClientTest.java:1341)
at io.vertx.test.core.AsyncTestBase.lambda$onSuccess$3(AsyncTestBase.java:684)
at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
<...trimmed...>
And also, the test result for builder.sendForm(form) without the second argument for charset:
May 09, 2023 3:44:26 AM io.vertx.test.core.AsyncTestBase
INFO: Starting test: WebClientTest#testWwwFormUrlEncodedWithCharset
body = param1=param1_value
May 09, 2023 3:44:26 AM io.vertx.core.impl.ContextBase
SEVERE: Unhandled exception
java.lang.AssertionError: Unexpected 'content-type' header value: 'application/x-www-form-urlencoded'.
at io.vertx.ext.web.client.WebClientTest.lambda$testWwwFormUrlEncodedWithCharset$122(WebClientTest.java:1341)
at io.vertx.test.core.AsyncTestBase.lambda$onSuccess$3(AsyncTestBase.java:684)
at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
<...trimmed...>