Bug 54709 - Official schemes for WebSocket are "ws"/"wss"; WsWebSocketContainer only allows "http"/"https"
Summary: Official schemes for WebSocket are "ws"/"wss"; WsWebSocketContainer only allo...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.0.x-trunk
Hardware: All All
: P2 critical (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-03-17 08:54 UTC by Nick Williams
Modified: 2020-09-16 22:55 UTC (History)
1 user (show)



Attachments
Patch to address issue (1.76 KB, patch)
2013-03-17 08:54 UTC, Nick Williams
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Williams 2013-03-17 08:54:31 UTC
Created attachment 30056 [details]
Patch to address issue

According to the WebSocket specification RFC6455 [1], the official URI schemes for the WebSocket protocol are "ws" and "wss." However, o.a.t.websocket.WsWebSocketContainer#connectToServer(...) throws an exception if anything other than "http" or "https" are specified. I agree with allowing "http" and "https" for reasons of friendliness (although the correctness of this could be debated; I did not address that in my patch), but "ws" and "wss" should ALWAYS be allowed here.

Also, one should be allowed to specify a port for EITHER ws/http OR wss/https. However, the way it was written, you could only specify a port for ws/http, and wss/https always tried to use 443 (I understand that SSL wasn't fully implemented here yet). Imagine the scenario where Tomcat is running on 8080/8443. You would need to specify 8443 as the wss/https port.

I have attached a patch that addresses these issues.

[1] http://tools.ietf.org/html/rfc6455#page-54
Comment 1 Mark Thomas 2013-03-17 18:52:08 UTC
Thanks for the report.

I fixed this with a slightly different patch. http/https are now not permitted for WebSocket URIs.
Comment 2 Nick Williams 2013-03-17 19:02:18 UTC
Note one potential problem:

        if (port == -1) {
            if ("ws".equalsIgnoreCase(scheme)) {
                sa = new InetSocketAddress(host, 80);
            } else {
                // TODO HTTPS support
                // sa = new InetSocketAddress(host, 443);
                throw new DeploymentException("TODO: HTTPS");
            }
        } else {
            sa = new InetSocketAddress(host, port);
        }

Now, I understand that SSL support is not complete yet, but as-written this won't allow customization of the port when connecting via SSL (wss). It is imperative that this be allowed (consider port 8443 as an example). Suggestion:

        if ("ws".equalsIgnoreCase(scheme)) {
            if (port == -1) {
                port = 80;
            }
            sa = new InetSocketAddress(host, port);
        } else {
            if (port == -1) {
                port = 443;
            }
            // TODO HTTPS support
            // sa = new InetSocketAddress(host, port);
            throw new DeploymentException("TODO: HTTPS");
        }

Of course, you may be planning on doing that anyway when you complete SSL support.
Comment 3 Mark Thomas 2013-03-17 19:08:08 UTC
(In reply to comment #2)
> Note one potential problem:

I must be being blind. What is the problem here?
Comment 4 Nick Williams 2013-03-17 19:33:27 UTC
If SSL support is completed by commenting out:

sa = new InetSocketAddress(host, 443);

Then if someone specifies a URL:

wss://localhost:8443/webSocketEndpoint

The code will attempt to connect to this instead:

wss://localhost:443/webSocketEndpoint
Comment 5 Nick Williams 2013-03-17 19:35:11 UTC
Scratch that previous comment. I was the one that was blind. Your code will work fine.