FULL PRODUCT VERSION :
jdk 9.0.01
ADDITIONAL OS VERSION INFORMATION :
Linux jackonWD1T 4.10.0-38-generic #42-Ubuntu SMP Tue Oct 10 13:24:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
the websocket provided in jdk.incubator.httpclient throws the following exception when I connect to a websocket server (wss).
java.util.concurrent.CompletionException: jdk.incubator.http.WebSocketHandshakeException
at java.base/java.util.concurrent.CompletableFuture.encodeRelay(CompletableFuture.java:367)
at java.base/java.util.concurrent.CompletableFuture.completeRelay(CompletableFuture.java:376)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1074)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
at jdk.incubator.httpclient/jdk.incubator.http.ResponseProcessors$NullProcessor.onComplete(ResponseProcessors.java:336)
at jdk.incubator.httpclient/jdk.incubator.http.BlockingPushPublisher.acceptData(BlockingPushPublisher.java:65)
at jdk.incubator.httpclient/jdk.incubator.http.AbstractPushPublisher.consume(AbstractPushPublisher.java:51)
at jdk.incubator.httpclient/jdk.incubator.http.ResponseContent.pushBodyFixed(ResponseContent.java:277)
at jdk.incubator.httpclient/jdk.incubator.http.ResponseContent.pushBody(ResponseContent.java:112)
at jdk.incubator.httpclient/jdk.incubator.http.Http1Response.lambda$readBody$2(Http1Response.java:161)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: jdk.incubator.http.WebSocketHandshakeException
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.resultFrom(OpeningHandshake.java:213)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1072)
... 11 more
Caused by: jdk.incubator.http.internal.websocket.CheckFailedException: Response field 'Sec-WebSocket-Version' present: [13]
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.checkFailed(OpeningHandshake.java:312)
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.requireAbsent(OpeningHandshake.java:281)
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.handleResponse(OpeningHandshake.java:243)
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.resultFrom(OpeningHandshake.java:209)
... 12 more
Given the exception, I use the following code to print information.
WebSocketHandshakeException e = (WebSocketHandshakeException) t;
HttpResponse<?> res = e.getResponse();
if (res != null) {
out.println(res.statusCode()+" "+res.version().toString());
HttpHeaders hs = res.headers();
if (hs != null) {
Util.dumpHeaders(hs.map(), "websocket response");
} else {
out.println("response headers is null");
}
HttpRequest req=res.request();
hs=req.headers();
if (hs != null) {
Util.dumpHeaders(hs.map(), "websocket request");
} else {
out.println("request headers is null");
}
} else {
out.println("response is null");
}
And the following is the information printed:
101 HTTP_1_1
start headers for websocket response
cf-ray: 3bd14275db0e787a-LAX
connection: upgrade
date: Mon, 13 Nov 2017 11:06:05 GMT
sec-websocket-accept: S9VUj2iAxVwQjWz7uzDqi/Z2QKA=
sec-websocket-protocol: websocket
sec-websocket-version: 13
server: cloudflare-nginx
set-cookie: __cfduid=d9f8e36dffb020ed4b39635b3a9ebf8d41510571165; expires=Tue, 13-Nov-18 11:06:05 GMT; path=/; domain=.bitfinex.com; HttpOnly
upgrade: websocket
websocket-server: uWebSockets
end headers for websocket response
start headers for websocket request
Sec-WebSocket-Key: hm2oYUkReBXF6rV1CIdDhA==
Sec-WebSocket-Protocol: websocket
Sec-WebSocket-Version: 13
end headers for websocket request
By the way, the server is good, if at the client side, I use https://github.com/TooTallNate/Java-WebSocket, then there is no problem in handshake, and connects OK. The handshake headers as follows:
request:
GET /ws HTTP/1.1
Connection: Upgrade
Host: api.bitfinex.com:443
Sec-WebSocket-Key: rLc7RM2rrTWxWstuRk1OlA==
Sec-WebSocket-Version: 13
Upgrade: websocket
response:
HTTP/1.1 101 Switching Protocols
Date: Mon, 13 Nov 2017 11:01:33 GMT
Connection: upgrade
Set-Cookie: __cfduid=db9360a709a6bccbe4d2faeb5f184b17d1510570893; expires=Tue, 13-Nov-18 11:01:33 GMT; path=/; domain=.bitfinex.com; HttpOnly
Upgrade: websocket
Sec-WebSocket-Accept: ijGieuFWjnBMGSLimegf5UGlIuQ=
Sec-WebSocket-Version: 13
WebSocket-Server: uWebSockets
Server: cloudflare-nginx
CF-RAY: 3bd13bd36faa51ac-SJC
Clearly, the jdk9 websocket the requirement, that the header "Sec-WebSocket-Version" should be absent in the response, caused the exception.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class WebSocketTest2 implements WebSocket.Listener {
static String url
=//"wss://real.okcoin.cn:10440/websocket/okcoinapi"; //"{'event':'addChannel','channel':'ok_btccny_ticker'}"
"wss://api.bitfinex.com/ws";
WebSocket wsocket;
static HttpClient client;
static PrintWriter out;
static boolean debug;
public static void setDebug(PrintWriter pw) {
out = pw;
debug = out != null;
}
static WebSocketTest2 one;
public static void main(String[] args) {
try {
Util.setDebug(out);
one = new WebSocketTest2();
one.test();
// wait 5 seconds for messages from websocket
//Thread.sleep(5000);
} catch (Throwable ex) {
if (debug) {
ex.printStackTrace(out);
out.flush();
}
}
if (debug) {
out.flush();
}
}
void test() throws URISyntaxException {
//System.out.println("debug:"+debug+" out:"+out);
if (debug) {
out.println("will try to create a websocket");
out.flush();
}
client = HttpClient.newHttpClient​();
WebSocket.Builder builder = client.newWebSocketBuilder(new URI(url), this);
builder.subprotocols("websocket");
builder.buildAsync().handle((WebSocket ws, Throwable t) -> {
if (t != null) {
if (debug) {
out.println("websocket creation exception");
}
t.printStackTrace(out);
if(t instanceof CompletionException){
t=t.getCause();
}
if (t instanceof WebSocketHandshakeException) {
WebSocketHandshakeException e = (WebSocketHandshakeException) t;
HttpResponse<?> res = e.getResponse();
if (res != null) {
out.println(res.statusCode()+" "+res.version().toString());
HttpHeaders hs = res.headers();
if (hs != null) {
Util.dumpHeaders(hs.map(), "websocket response");
} else {
out.println("response headers is null");
}
HttpRequest req=res.request();
hs=req.headers();
if (hs != null) {
Util.dumpHeaders(hs.map(), "websocket request");
} else {
out.println("request headers is null");
}
} else {
out.println("response is null");
}
}
out.flush();
return null;
}
if (debug) {
out.println("websocket is created");
out.flush();
}
return ws;
}).thenAccept(ws -> {
wsocket = ws;
ws.sendText(url, false);
});
}
@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence message, WebSocket.MessagePart part) {
try {
if (debug) {
out.println(message);
}
JsonReader jr = Json.createReader(new StringReader(message.toString()));
JsonStructure js = jr.read();
JsonValue.ValueType vt = js.getValueType();
if (vt == vt.ARRAY) {
} else {
//jr.readObject()
}
} catch (Throwable t) {
}
webSocket.request(1);
return null;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
use alternative websocket package.
SUPPORT :
YES
jdk 9.0.01
ADDITIONAL OS VERSION INFORMATION :
Linux jackonWD1T 4.10.0-38-generic #42-Ubuntu SMP Tue Oct 10 13:24:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
the websocket provided in jdk.incubator.httpclient throws the following exception when I connect to a websocket server (wss).
java.util.concurrent.CompletionException: jdk.incubator.http.WebSocketHandshakeException
at java.base/java.util.concurrent.CompletableFuture.encodeRelay(CompletableFuture.java:367)
at java.base/java.util.concurrent.CompletableFuture.completeRelay(CompletableFuture.java:376)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1074)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
at jdk.incubator.httpclient/jdk.incubator.http.ResponseProcessors$NullProcessor.onComplete(ResponseProcessors.java:336)
at jdk.incubator.httpclient/jdk.incubator.http.BlockingPushPublisher.acceptData(BlockingPushPublisher.java:65)
at jdk.incubator.httpclient/jdk.incubator.http.AbstractPushPublisher.consume(AbstractPushPublisher.java:51)
at jdk.incubator.httpclient/jdk.incubator.http.ResponseContent.pushBodyFixed(ResponseContent.java:277)
at jdk.incubator.httpclient/jdk.incubator.http.ResponseContent.pushBody(ResponseContent.java:112)
at jdk.incubator.httpclient/jdk.incubator.http.Http1Response.lambda$readBody$2(Http1Response.java:161)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: jdk.incubator.http.WebSocketHandshakeException
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.resultFrom(OpeningHandshake.java:213)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1072)
... 11 more
Caused by: jdk.incubator.http.internal.websocket.CheckFailedException: Response field 'Sec-WebSocket-Version' present: [13]
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.checkFailed(OpeningHandshake.java:312)
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.requireAbsent(OpeningHandshake.java:281)
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.handleResponse(OpeningHandshake.java:243)
at jdk.incubator.httpclient/jdk.incubator.http.internal.websocket.OpeningHandshake.resultFrom(OpeningHandshake.java:209)
... 12 more
Given the exception, I use the following code to print information.
WebSocketHandshakeException e = (WebSocketHandshakeException) t;
HttpResponse<?> res = e.getResponse();
if (res != null) {
out.println(res.statusCode()+" "+res.version().toString());
HttpHeaders hs = res.headers();
if (hs != null) {
Util.dumpHeaders(hs.map(), "websocket response");
} else {
out.println("response headers is null");
}
HttpRequest req=res.request();
hs=req.headers();
if (hs != null) {
Util.dumpHeaders(hs.map(), "websocket request");
} else {
out.println("request headers is null");
}
} else {
out.println("response is null");
}
And the following is the information printed:
101 HTTP_1_1
start headers for websocket response
cf-ray: 3bd14275db0e787a-LAX
connection: upgrade
date: Mon, 13 Nov 2017 11:06:05 GMT
sec-websocket-accept: S9VUj2iAxVwQjWz7uzDqi/Z2QKA=
sec-websocket-protocol: websocket
sec-websocket-version: 13
server: cloudflare-nginx
set-cookie: __cfduid=d9f8e36dffb020ed4b39635b3a9ebf8d41510571165; expires=Tue, 13-Nov-18 11:06:05 GMT; path=/; domain=.bitfinex.com; HttpOnly
upgrade: websocket
websocket-server: uWebSockets
end headers for websocket response
start headers for websocket request
Sec-WebSocket-Key: hm2oYUkReBXF6rV1CIdDhA==
Sec-WebSocket-Protocol: websocket
Sec-WebSocket-Version: 13
end headers for websocket request
By the way, the server is good, if at the client side, I use https://github.com/TooTallNate/Java-WebSocket, then there is no problem in handshake, and connects OK. The handshake headers as follows:
request:
GET /ws HTTP/1.1
Connection: Upgrade
Host: api.bitfinex.com:443
Sec-WebSocket-Key: rLc7RM2rrTWxWstuRk1OlA==
Sec-WebSocket-Version: 13
Upgrade: websocket
response:
HTTP/1.1 101 Switching Protocols
Date: Mon, 13 Nov 2017 11:01:33 GMT
Connection: upgrade
Set-Cookie: __cfduid=db9360a709a6bccbe4d2faeb5f184b17d1510570893; expires=Tue, 13-Nov-18 11:01:33 GMT; path=/; domain=.bitfinex.com; HttpOnly
Upgrade: websocket
Sec-WebSocket-Accept: ijGieuFWjnBMGSLimegf5UGlIuQ=
Sec-WebSocket-Version: 13
WebSocket-Server: uWebSockets
Server: cloudflare-nginx
CF-RAY: 3bd13bd36faa51ac-SJC
Clearly, the jdk9 websocket the requirement, that the header "Sec-WebSocket-Version" should be absent in the response, caused the exception.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class WebSocketTest2 implements WebSocket.Listener {
static String url
=//"wss://real.okcoin.cn:10440/websocket/okcoinapi"; //"{'event':'addChannel','channel':'ok_btccny_ticker'}"
"wss://api.bitfinex.com/ws";
WebSocket wsocket;
static HttpClient client;
static PrintWriter out;
static boolean debug;
public static void setDebug(PrintWriter pw) {
out = pw;
debug = out != null;
}
static WebSocketTest2 one;
public static void main(String[] args) {
try {
Util.setDebug(out);
one = new WebSocketTest2();
one.test();
// wait 5 seconds for messages from websocket
//Thread.sleep(5000);
} catch (Throwable ex) {
if (debug) {
ex.printStackTrace(out);
out.flush();
}
}
if (debug) {
out.flush();
}
}
void test() throws URISyntaxException {
//System.out.println("debug:"+debug+" out:"+out);
if (debug) {
out.println("will try to create a websocket");
out.flush();
}
client = HttpClient.newHttpClient​();
WebSocket.Builder builder = client.newWebSocketBuilder(new URI(url), this);
builder.subprotocols("websocket");
builder.buildAsync().handle((WebSocket ws, Throwable t) -> {
if (t != null) {
if (debug) {
out.println("websocket creation exception");
}
t.printStackTrace(out);
if(t instanceof CompletionException){
t=t.getCause();
}
if (t instanceof WebSocketHandshakeException) {
WebSocketHandshakeException e = (WebSocketHandshakeException) t;
HttpResponse<?> res = e.getResponse();
if (res != null) {
out.println(res.statusCode()+" "+res.version().toString());
HttpHeaders hs = res.headers();
if (hs != null) {
Util.dumpHeaders(hs.map(), "websocket response");
} else {
out.println("response headers is null");
}
HttpRequest req=res.request();
hs=req.headers();
if (hs != null) {
Util.dumpHeaders(hs.map(), "websocket request");
} else {
out.println("request headers is null");
}
} else {
out.println("response is null");
}
}
out.flush();
return null;
}
if (debug) {
out.println("websocket is created");
out.flush();
}
return ws;
}).thenAccept(ws -> {
wsocket = ws;
ws.sendText(url, false);
});
}
@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence message, WebSocket.MessagePart part) {
try {
if (debug) {
out.println(message);
}
JsonReader jr = Json.createReader(new StringReader(message.toString()));
JsonStructure js = jr.read();
JsonValue.ValueType vt = js.getValueType();
if (vt == vt.ARRAY) {
} else {
//jr.readObject()
}
} catch (Throwable t) {
}
webSocket.request(1);
return null;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
use alternative websocket package.
SUPPORT :
YES
- duplicates
-
JDK-8191494 Refresh incubating HTTP Client
-
- Closed
-