http4s/http4s-jdk-http-client

Bug in multipart POST

gekomad opened this issue · 10 comments

In version 0.3.7, multipart POST does not seem to work. Using the standard http4s client everything is fine.

    val multipart = Multipart[IO](Vector(Part.formData("form", """foo""")))
    
    val request: Request[IO] = Request[IO](POST, url).withEntity(multipart).withHeaders(multipart.headers)
    // http4s standard client works fine

    BlazeClientBuilder[IO](global).resource.use { client0 =>
        client0.expect[String](request)
    }
    // http4s-jdk-http-client client 0.3.7  doesen't work

    val baseClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2)
    val client0: Client[IO] = JdkHttpClient(baseClient.build())
    client0.expect[String](request)

I can't reproduce this against https://httpbin.org/post. Can you reproduce this with a publicly available site? What error do you get? Can you ensure that this also happens when using java.net.http.HttpClient directly?

Unfortunately I'm calling a IIS private server and I can't debug it, the error is 400 Bad Request. sttp client works too.
Do you know a public debug service for IIS?

Sorry, I am not aware of such a site. Can you ensure that this also happens when using java.net.http.HttpClient directly? http4s-jdk-http-client is a light wrapper around that, so this would be helpful to debug the issue.

Using java.net.http.HttpClient works. I used this code https://urvanov.ru/2020/08/18/java-11-httpclient-multipart-form-data/

Did you also force HTTP 2 like you did in your initial example?

I found out the IIS server is behind a Amazon awl Elastic Load Balancing (awselb)

so

standard http4s client works fine:

Response(status=200, headers=Headers(Date: Sat, 19 Feb 2022 16:33:18 GMT, Content-Length: 0, Connection: keep-alive, Cache-Control: no-cache, Pragma: no-cache, Expires: -1, Server: Microsoft-IIS/10.0, Access-Control-Allow-Origin: *, X-AspNet-Version: 4.0.30319, X-Powered-By: ASP.NET))

With http4s-jdk-http-client I get an error from awselb:

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
</body>
</html>
Response(status=400, headers=Headers(connection: close, content-length: 122, content-type: text/html, date: Sat, 19 Feb 2022 16:32:47 GMT, server: awselb/2.0)))

with java version "11.0.7" doesn't work
but with java version "12.0.2" works!

Ah, then it is an instance of #200, see also this note in the docs:

TLS 1.3 on Java 11. On Java 11, TLS 1.3 is disabled by default (when using JdkHttpClient.simple). This is a workaround for a spurious bug, see #200.

In particular, when you create the client via JdkHttpClient.simple, it should also work on Java 11.

I'll use jdk 17. Thanks @amesgen

epabst commented

If you need to use Java 11, I fixed a similar issue by specifying HTTP 1.1 rather than HTTP 2.

HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1)...