OpenJDK (JDK 11) behavior discussion for HttpClient
Daniel Fuchs
daniel.fuchs at oracle.com
Fri Sep 15 16:37:45 UTC 2023
Hi Rajesh,
On 15/09/2023 17:19, Rajesh Gudikoti wrote:
> Thanks both for quick response.
> Daniel, how did you get connection upgrade. Are you setting any header
> for upgrade? Our sample code almost resembles your code. The difference
> is, you have used httpClient.sendAsync vs httpClient.send.
The upgrade header is set automatically by the HttpClient.
You should not try to set it.
If you send a clear (http vs https) request to a server, and either
the request version or the client preferred version is HTTP_2, the
client will attempt a connection upgrade (the first time).
send() is internally implemented as sendAsync().get() + some
exception wrapping/unwrapping logic, so there should be no difference.
best regards,
-- daniel
>
>
> POST /WarmupHandler HTTP/1.1
> *Connection: Upgrade, HTTP2-Settings*
>
> **
>
>
> *var*httpClient= HttpClient./newBuilder/()
>
> .version(HttpClient.Version.*/HTTP_2/*)
>
> .build();
>
> *var*httpRequest=
> HttpRequest./newBuilder/(URI./create/(http://localhost:xxxx/pmxxx/pmdxxx
> <http://localhost:xxxx/pmdinhxxx/pmdinhInputxxx>))
>
> .version(HttpClient.Version.*/HTTP_2/*)
>
>
> .POST(HttpRequest.BodyPublishers./ofString/("_FIRST_POST_PMDINH_"))
>
> .build();
>
> *var*httpResponse= httpClient.send(httpRequest,
> HttpResponse.BodyHandlers./ofString/());
>
> *Regards*
>
> Rajesh
>
> *From: *Daniel Jeliński <djelinski1 at gmail.com>
> *Date: *Friday, 15 September 2023 at 7:47 PM
> *To: *Asha Sunagar <Asha.Sunagar at ibm.com>
> *Cc: *net-dev at openjdk.org <net-dev at openjdk.org>, Syed Moinudeen1
> <smoinud1 at in.ibm.com>, Rajesh Gudikoti <ragudiko at in.ibm.com>, Suman
> Mitra <summitra at in.ibm.com>, Shruthi Shruthi1 <Shruthi.Shruthi1 at ibm.com>
> *Subject: *[EXTERNAL] Re: OpenJDK (JDK 11) behavior discussion for
> HttpClient
>
> I verified the httpclient behavior using a slightly modified
> TrailingHeadersTest
> (https://github.com/openjdk/jdk/blob/master/test/jdk/java/net/httpclient/http2/TrailingHeadersTest.java );
> modified the performWarmupRequest method to perform a POST instead of
> a GET like this:
>
> private void performWarmupRequest(HttpClient httpClient) {
> HttpRequest warmupReq =
> HttpRequest.newBuilder(warmupURI).version(HTTP_2)
> .POST(HttpRequest.BodyPublishers.ofString("Bwah!"))
> .build();
> httpClient.sendAsync(warmupReq, BodyHandlers.discarding()).join();
> }
>
> Then captured the generated traffic using Wireshark. The client sent
> the following sequence:
>
> POST /WarmupHandler HTTP/1.1
> Connection: Upgrade, HTTP2-Settings
> Content-Length: 5
> Host: 127.0.0.1:60259
> HTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA
> Upgrade: h2c
> User-Agent: Java-http-client/22-internal
>
> Bwah!PRI * HTTP/2.0
>
> SM
>
> <followed by binary content>
>
> This appears to be the correct behavior, according to the RFC:
> https://datatracker.ietf.org/doc/html/rfc7540#section-3.2
> <https://datatracker.ietf.org/doc/html/rfc7540#section-3.2>
>
>> Requests that contain a payload body MUST be sent in their entirety before the client can send HTTP/2 frames. This means that a large request can block the use of the connection until it is completely sent.
>
> Based on the above I'd say that the client behavior is correct here.
> Does the above match your observations?
> Regards,
> Daniel
>
> pt., 15 wrz 2023 o 14:44 Daniel Jeliński <djelinski1 at gmail.com> napisał(a):
>>
>> Hi Asha,
>> It sounds like you are not using ALPN, but instead start with a HTTP1
>> connection and upgrade to HTTP2.
>>
>> The incorrect preface string translates to:
>> _FIRST_POST_PMDINH_PRI *
>>
>> Is it correct to assume that "_FIRST_POST_PMDINH_" is the final bytes
>> of the first POST request? If that's correct, then either the client
>> or the server handles the content-length header incorrectly.
>>
>> Can you provide a minimal reproducer?
>> Regards,
>> Daniel
>>
>> pt., 15 wrz 2023 o 14:07 Asha Sunagar <Asha.Sunagar at ibm.com> napisał(a):
>> >
>> > Hello Team,
>> >
>> >
>> > We are facing invalid preface issue when we send POST request using HttpClient. We overcame this issue using workaround mentioned in openjdk issue. The workaround was to use a blank request before making post request.
>> >
>> >
>> >
>> > Based on our below observations, the Preface String is different in Failure & Success case,
>> >
>> >
>> > The Preface String for
>> > 1.1) Post Request without blank request --> we get GOAWAY Exception (Failure case)
>> >
>> > Preface String: [80, 82, 73, 32, 42, 32, 72, 84, 84, 80, 47, 50, 46, 48, 13, 10, 13, 10, 83, 77, 13, 10, 13, 10]
>> >
>> > Preface String: [95, 70, 73, 82, 83, 84, 95, 80, 79, 83, 84, 95, 80, 77, 68, 73, 78, 72, 95, 80, 82, 73, 32, 42]
>> >
>> > Preface String: [95, 70, 73, 82, 83, 84, 95, 80, 79, 83, 84, 95, 80, 77, 68, 73, 78, 72, 95, 80, 82, 73, 32, 42]
>> >
>> >
>> >
>> > 1.2) Workaround case with a blank request (Success Case)
>> >
>> > Preface String: [80, 82, 73, 32, 42, 32, 72, 84, 84, 80, 47, 50, 46, 48, 13, 10, 13, 10, 83, 77, 13, 10, 13, 10]
>> >
>> > Preface String: [80, 82, 73, 32, 42, 32, 72, 84, 84, 80, 47, 50, 46, 48, 13, 10, 13, 10, 83, 77, 13, 10, 13, 10]
>> >
>> > Preface String: [80, 82, 73, 32, 42, 32, 72, 84, 84, 80, 47, 50, 46, 48, 13, 10, 13, 10, 83, 77, 13, 10, 13, 10]
>> >
>> >
>> >
>> > 2) LOGS
>> > 2.1) Post Request without blank request :We get the error "an error occurred processing a frame": Failed to complete the connection preface from Liberty server and GOAWAY Exception.
>> >
>> > [9/7/23, 15:41:10:595 IST] 00000058 id=00000000 com.ibm.ws.http.channel.h2internal.FrameReadProcessor 3 checkConnectionPreface: processNextFrame-: stream: 0 frame type: Magic Preface direction: READ_IN H2InboundLink hc: 101118290
>> >
>> > [9/7/23, 15:41:10:595 IST] 00000058 id=00000000 com.ibm.ws.http.channel.h2internal.FrameReadProcessor 3 checkConnectionPreface: Preface String: [95, 70, 73, 82, 83, 84, 95, 80, 79, 83, 84, 95, 80, 77, 68, 73, 78, 72, 95, 80, 82, 73, 32, 42]
>> >
>> > [9/7/23, 15:41:10:595 IST] 00000058 id=00000000 SystemOut O PMDINH, FrameReadProcessor CHECKPOINT 2, throw new ProtocolException --- Connection preface/magic was invalid
>> >
>> > [9/7/23, 15:41:10:595 IST] 00000058 id=00000000 SystemOut O PMDINH, FrameReadProcessor CHECKPOINT 3, throw new ProtocolException --- Cconnection preface
>> >
>> > [9/7/23, 15:41:10:595 IST] 00000058 id=00000000 com.ibm.ws.http.channel.h2internal.H2InboundLink 3 processRead: an error occurred processing a frame: Failed to complete the connection preface
>> >
>> > [9/7/23, 15:41:10:595 IST] 00000058 id=00000000 com.ibm.ws.http.channel.h2internal.H2InboundLink 3 close(vc,e): :linkstatus: is: INIT :close: H2InboundLink hc: 101118290exception: com.ibm.ws.http.channel.h2internal.exceptions.ProtocolException: Failed to complete the connection preface
>> >
>> >
>> >
>> > 2.2) Workaround case with a blank request
>> >
>> > [9/7/23, 15:54:21:528 IST] 0000005a id=00000000 com.ibm.ws.http.channel.h2internal.FrameReadProcessor 3 checkConnectionPreface: processNextFrame-: stream: 0 frame type: Magic Preface direction: READ_IN H2InboundLink hc: 551136004
>> >
>> > [9/7/23, 15:54:21:528 IST] 0000005a id=00000000 com.ibm.ws.http.channel.h2internal.FrameReadProcessor 3 checkConnectionPreface: Preface String: [80, 82, 73, 32, 42, 32, 72, 84, 84, 80, 47, 50, 46, 48, 13, 10, 13, 10, 83, 77, 13, 10, 13, 10]
>> >
>> > [9/7/23, 15:54:21:528 IST] 0000005a id=00000000 com.ibm.ws.http.channel.h2internal.H2InboundLink 3 createNewInboundLink entry: stream-id: 0
>> >
>> > [9/7/23, 15:54:21:528 IST] 0000005a id=00000000 com.ibm.ws.http.channel.internal.inbound.HttpInboundLink
>> >
>> >
>> >
>> > Please let us to know whether it is an expected behavior or an issue? Or is there a way to handle such scenarios?
>> >
>> >
>> >
>> > Thanks & Regards,
>> >
>> > Asha H Sunagar
>> >
>> > IGA - JTC | Global Business Services – IBM
>> >
>> > Phone: +91 8884256034
>> >
>> > Email : asha.sunagar at ibm.com
>> >
>> >
>
More information about the net-dev
mailing list