A DESCRIPTION OF THE PROBLEM :
Currently one cannot use HttpClient / WebSocket introduced in Java 11 to perform Websocket connections that require Http Upgrade (see https://en.wikipedia.org/wiki/WebSocket > Opening handshake).
Given a WebSocket.Builder is created from an HttpClient this seems a unneeded limitation of the current implementation while large part of the work is already done because:
1. HttpClient support Http 1.1 requests
2. It supports building a Websocke capable implementation
3. It already supports upgrades to the Http/2 protocol
Assume the following code:
URI endpointUri = URI.create("http://server/wsendpoint-requiring-http-upgrade");
HttpClient client = HttpClient.newHttpClient();
WebSocket.Builder webSocketBuilder = client.newWebSocketBuilder();
WebSocket webSocket = webSocketBuilder.buildAsync(endpointUri, new WebSocket.Listener() {
@Override
public void onOpen(WebSocket webSocket) {
System.out.println("Web Socket was opened!");
}
}).join();
currently results in an Exception
Caused by: java.lang.IllegalArgumentException: invalid URI scheme: http
at java.net.http/jdk.internal.net.http.websocket.OpeningHandshake.illegal(OpeningHandshake.java:358)
at java.net.http/jdk.internal.net.http.websocket.OpeningHandshake.checkURI(OpeningHandshake.java:349)
at java.net.http/jdk.internal.net.http.websocket.OpeningHandshake.<init>(OpeningHandshake.java:115)
at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl.newInstanceAsync(WebSocketImpl.java:139)
at java.net.http/jdk.internal.net.http.websocket.BuilderImpl.buildAsync(BuilderImpl.java:120)
Also trying to build up an upgrade request directly (even though then one can not connect the streams to the WebSocket.Builder as it only accepts URIs) results in
java.lang.IllegalArgumentException: restricted header name: "Upgrade"
at java.net.http/jdk.internal.net.http.common.Utils.newIAE(Utils.java:286)
at java.net.http/jdk.internal.net.http.HttpRequestBuilderImpl.checkNameAndValue(HttpRequestBuilderImpl.java:110)
at java.net.http/jdk.internal.net.http.HttpRequestBuilderImpl.header(HttpRequestBuilderImpl.java:126)
at java.net.http/jdk.internal.net.http.HttpRequestBuilderImpl.header(HttpRequestBuilderImpl.java:43)
So the user is locked in here and must use other libraries whenever an http-only endpoint for the websocket is possible (e.g. proxy or firewalls).
As the protocol for upgrading a connection is quite simple, it would be good if it could be enhanced for this usage to make the new HttpClient/WebSocket even more general purpose and useful with minimal extra efforts!
Any additional information needed beforehands (e.g Sec-WebSocket-Protocol or Sec-WebSocket-Extensions) might be passed using the WebSocket.Builder like with java.net.http.WebSocket.Builder.subprotocols(String, String...) method.
Currently one cannot use HttpClient / WebSocket introduced in Java 11 to perform Websocket connections that require Http Upgrade (see https://en.wikipedia.org/wiki/WebSocket > Opening handshake).
Given a WebSocket.Builder is created from an HttpClient this seems a unneeded limitation of the current implementation while large part of the work is already done because:
1. HttpClient support Http 1.1 requests
2. It supports building a Websocke capable implementation
3. It already supports upgrades to the Http/2 protocol
Assume the following code:
URI endpointUri = URI.create("http://server/wsendpoint-requiring-http-upgrade");
HttpClient client = HttpClient.newHttpClient();
WebSocket.Builder webSocketBuilder = client.newWebSocketBuilder();
WebSocket webSocket = webSocketBuilder.buildAsync(endpointUri, new WebSocket.Listener() {
@Override
public void onOpen(WebSocket webSocket) {
System.out.println("Web Socket was opened!");
}
}).join();
currently results in an Exception
Caused by: java.lang.IllegalArgumentException: invalid URI scheme: http
at java.net.http/jdk.internal.net.http.websocket.OpeningHandshake.illegal(OpeningHandshake.java:358)
at java.net.http/jdk.internal.net.http.websocket.OpeningHandshake.checkURI(OpeningHandshake.java:349)
at java.net.http/jdk.internal.net.http.websocket.OpeningHandshake.<init>(OpeningHandshake.java:115)
at java.net.http/jdk.internal.net.http.websocket.WebSocketImpl.newInstanceAsync(WebSocketImpl.java:139)
at java.net.http/jdk.internal.net.http.websocket.BuilderImpl.buildAsync(BuilderImpl.java:120)
Also trying to build up an upgrade request directly (even though then one can not connect the streams to the WebSocket.Builder as it only accepts URIs) results in
java.lang.IllegalArgumentException: restricted header name: "Upgrade"
at java.net.http/jdk.internal.net.http.common.Utils.newIAE(Utils.java:286)
at java.net.http/jdk.internal.net.http.HttpRequestBuilderImpl.checkNameAndValue(HttpRequestBuilderImpl.java:110)
at java.net.http/jdk.internal.net.http.HttpRequestBuilderImpl.header(HttpRequestBuilderImpl.java:126)
at java.net.http/jdk.internal.net.http.HttpRequestBuilderImpl.header(HttpRequestBuilderImpl.java:43)
So the user is locked in here and must use other libraries whenever an http-only endpoint for the websocket is possible (e.g. proxy or firewalls).
As the protocol for upgrading a connection is quite simple, it would be good if it could be enhanced for this usage to make the new HttpClient/WebSocket even more general purpose and useful with minimal extra efforts!
Any additional information needed beforehands (e.g Sec-WebSocket-Protocol or Sec-WebSocket-Extensions) might be passed using the WebSocket.Builder like with java.net.http.WebSocket.Builder.subprotocols(String, String...) method.