-
Bug
-
Resolution: Unresolved
-
P4
-
11, 12, 13
-
generic
-
generic
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
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