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

HttpClient sends the same request twice in some cases

    Details

    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      ADDITIONAL SYSTEM INFORMATION :
      openjdk version "11.0.1" 2018-10-16
      OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.1+13)
      OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.1+13, mixed mode)

      MacOS 10.14.3

      A DESCRIPTION OF THE PROBLEM :
      Imagine the following situation:
      1) HttpClient connects to HTTP-server and sends http-request
      2) Server receives request and closes tcp-connection

      After these steps HttpClient tries to re-establish TCP connection to server and sends the same request again.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1) Run nc (netcat) program on localhost:
      nc -4lk localhost 8000; nc -4lk localhost 8000
      (yes, twice in turn)
      2) Start Wireshark to capture traffic on localhost port 8000
      3) Run the provided program
      4) You will see the following output in netcat window:
      GET /test HTTP/1.1
      Content-Length: 0
      Host: localhost:8000
      User-Agent: Java-http-client/11.0.1

      5) Press "Ctrl+C" in netcat window
      6) Depending on luck you will either see the following exception from Java program:
      Exception in thread "main" java.net.ConnectException: Connection refused
      at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:561)
      at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:119)
      at ru.mitya.test.App.main(App.java:14)
      Caused by: java.net.ConnectException: Connection refused
      at java.base/sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
      at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:779)
      at java.net.http/jdk.internal.net.http.PlainHttpConnection$ConnectEvent.handle(PlainHttpConnection.java:128)
      at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.handleEvent(HttpClientImpl.java:957)
      at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.lambda$run$3(HttpClientImpl.java:912)
      at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
      at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.run(HttpClientImpl.java:912)

      which means that second copy on netcat started slowly and program tried to establish second tcp-connection faster and failed with Connection refused (wrong message)

      or (if netcat starts faster) you will see the same HTTP-request in netcat window second time.

      7) Analyse Wireshark capture to prove that is works that way

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      After server closes connection, I expect the program to fail with IOException and do not try to re-connect to server.

      ---------- BEGIN SOURCE ----------
      import java.net.URI;
      import java.net.http.HttpClient;
      import java.net.http.HttpRequest;
      import java.net.http.HttpResponse;

      public class App {
          public static void main(String[] args) throws Exception {
              HttpClient client = HttpClient.newBuilder().build();
              HttpRequest req = HttpRequest.newBuilder(URI.create("http://localhost:8000/test"))
                      .version(HttpClient.Version.HTTP_1_1)
                      .build();
              HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
          }
      }
      ---------- END SOURCE ----------

      FREQUENCY : always


        Attachments

          Activity

            People

            • Assignee:
              dfuchs Daniel Fuchs
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated: