Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8326420

http2 upgrade "IOException: HTTP/1.1 header parser received no bytes"

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 21
    • core-libs
    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Reproduced on a range of platform:

      Mac OS (latest) and JDK 21 latest
      RedHat Linux (REHL) 9 and JDK 17.0.8+7-LTS

      A DESCRIPTION OF THE PROBLEM :

      Additional comments on the following existing issue:
      https://bugs.openjdk.org/browse/JDK-8239117

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      This code always fails when the targetted server isn't able to handle the "Upgrade: h2c" header automatically sent by this request. Indeed, the server I've found crashes, and breaks the TCP connection right away (confirmed by testing with curl).

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Ideally, a retry with http 1.1 instead.
      Else, raise a IOException or InterruptedException
      ACTUAL -
      Exception in thread "main" java.io.IOException: HTTP/1.1 header parser received no bytes
      at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:964)
      at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:133)
      at Test.main(test.java:21)
      Caused by: java.io.IOException: HTTP/1.1 header parser received no bytes
      at java.net.http/jdk.internal.net.http.common.Utils.wrapWithExtraDetail(Utils.java:388)
      at java.net.http/jdk.internal.net.http.Http1Response$HeadersReader.onReadError(Http1Response.java:590)
      at java.net.http/jdk.internal.net.http.Http1AsyncReceiver.checkForErrors(Http1AsyncReceiver.java:302)
      at java.net.http/jdk.internal.net.http.Http1AsyncReceiver.flush(Http1AsyncReceiver.java:268)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
      at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
      at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
      at java.base/java.lang.Thread.run(Thread.java:1583)
      Caused by: java.io.EOFException: EOF reached while reading
      at java.net.http/jdk.internal.net.http.Http1AsyncReceiver$Http1TubeSubscriber.onComplete(Http1AsyncReceiver.java:601)
      at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$ReadSubscription.signalCompletion(SocketTube.java:648)
      at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.read(SocketTube.java:853)
      at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowTask.run(SocketTube.java:181)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233)
      at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.signalReadable(SocketTube.java:782)
      at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$ReadEvent.signalEvent(SocketTube.java:965)
      at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowEvent.handle(SocketTube.java:253)
      at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.handleEvent(HttpClientImpl.java:1467)
      at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.lambda$run$3(HttpClientImpl.java:1412)
      at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
      at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:1412)

      ---------- BEGIN SOURCE ----------
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpResponse;
      import java.net.URI;
      import java.net.URISyntaxException;
      import java.time.Duration;
      import java.io.IOException;

      public class Test {
        public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
          final var request = HttpRequest.newBuilder()
              .uri(new URI("http://url_to_weird_server"))
              .GET()
              .timeout(Duration.ofSeconds(10))
              .build();

          var httpClient = HttpClient.newBuilder().build();

          var r = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      The workaround is to set `.version(HttpClient.Version.HTTP_1_1)` after line 12 in this particular case.

      (setting the version to HttpClient.Version.HTTP_2, always leads to the issue, as expected snce this is the default behaviour)

      FREQUENCY : always


            jpai Jaikiran Pai
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: