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

HttpClient fails to send successive POST requests under HTTP/2

XMLWordPrintable

    • Verified

      The following test will fail:

      import static java.net.http.HttpClient.Version.HTTP_2;

      import java.net.URI;
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpRequest.BodyPublishers;
      import java.net.http.HttpResponse;
      import java.net.http.HttpResponse.BodyHandlers;

      import org.testng.annotations.Test;

      /*
       * @test
       * @compile HttpTestUtils.java
       * @run testng/othervm POSTTest
       */
      public class POSTTest {
          @Test
          public void test() throws Exception {
              HttpTestServer server = HttpTestServer.APACHE;
              HttpClient client = HttpTestUtils.clientBuilder(server)
                                               .version(HTTP_2)
                                               .build();

              HttpRequest request = HttpRequest
                      .newBuilder(new URI(server.getCgiRoot(
                              HttpTestUtils.Protocol.HTTPS, "maxframesize")))
                      .POST(BodyPublishers.ofString("test=123")).build();

              HttpResponse<String> resp = client.sendAsync(request, BodyHandlers.ofString()).get();
              System.out.println(resp.version());
              
              request = HttpRequest
                      .newBuilder(new URI(server.getCgiRoot(
                              HttpTestUtils.Protocol.HTTPS, "maxframesize")))
                      .POST(BodyPublishers.ofString("test=123")).build();

              resp = client.sendAsync(request, BodyHandlers.ofString()).get();
              System.out.println(resp.version());
              
              request = HttpRequest
                      .newBuilder(new URI(server.getCgiRoot(
                              HttpTestUtils.Protocol.HTTPS, "headerresp")))
                      .POST(BodyPublishers.ofString("r=02")).build();

              resp = client.sendAsync(request, BodyHandlers.ofString()).get();
              System.out.println(resp.version());
          }
      }

      with message:
      STDOUT:
      [TestNG] Running:
        infra/java/net/http/httpclient/POSTTest.java

      HTTP_2
      test POSTTest.test(): failure
      java.util.concurrent.ExecutionException: java.io.IOException: /10.0.2.15:37724: GOAWAY received
      at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
      at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1999)
      at POSTTest.test(POSTTest.java:38)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.base/java.lang.reflect.Method.invoke(Method.java:564)
      at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
      at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
      at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:821)
      at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1131)
      at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:124)
      at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
      at org.testng.TestRunner.privateRun(TestRunner.java:773)
      at org.testng.TestRunner.run(TestRunner.java:623)
      at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
      at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
      at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
      at org.testng.SuiteRunner.run(SuiteRunner.java:259)
      at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
      at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
      at org.testng.TestNG.runSuitesSequentially(TestNG.java:1185)
      at org.testng.TestNG.runSuitesLocally(TestNG.java:1110)
      at org.testng.TestNG.run(TestNG.java:1018)
      at com.sun.javatest.regtest.agent.TestNGRunner.main(TestNGRunner.java:94)
      at com.sun.javatest.regtest.agent.TestNGRunner.main(TestNGRunner.java:54)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.base/java.lang.reflect.Method.invoke(Method.java:564)
      at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:115)
      at java.base/java.lang.Thread.run(Thread.java:844)
      Caused by: java.io.IOException: /10.0.2.15:37724: GOAWAY received
      at java.net.http/jdk.internal.net.http.Http2Connection.handleGoAway(Http2Connection.java:817)
      at java.net.http/jdk.internal.net.http.Http2Connection.handleConnectionFrame(Http2Connection.java:716)
      at java.net.http/jdk.internal.net.http.Http2Connection.processFrame(Http2Connection.java:614)
      at java.net.http/jdk.internal.net.http.frame.FramesDecoder.decode(FramesDecoder.java:155)
      at java.net.http/jdk.internal.net.http.Http2Connection$FramesController.processReceivedData(Http2Connection.java:200)
      at java.net.http/jdk.internal.net.http.Http2Connection.asyncReceive(Http2Connection.java:549)
      at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.processQueue(Http2Connection.java:1090)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
      at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
      at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1131)
      at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:631)
      ... 1 more


      After the first response is received, HttpClient sends the second, but it only sends the HEADERS frame, not send the DATA frame, so the server reset stream with timeout.

            dfuchs Daniel Fuchs
            fyuan Frank Yuan (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: