5

Given a WebSocket endpoint as follows.

@ServerEndpoint(value = "/Push/CartPush/{token}")
public final class CartPush {
    // ...
}

The endpoint is able to accept a path parameter {token}. The path parameter is however, optional which is determined dynamically at run-time in Java Script. Skipping this parameter in JavaScript like the following results in 404.

var ws = new WebSocket("wss://localhost:8443/ContextPath/Push/CartPush");

WebSocket connection to 'wss://localhost:8443/ContextPath/Push/CartPush' failed: Error during WebSocket handshake: Unexpected response code: 404

It makes the token value compulsory as follows.

var token = "token value";
var ws = new WebSocket("wss://localhost:8443/ContextPath/Push/CartPush" + "/" + token);

In order to exclude all unneeded HTTP methods except GET and POST, I use the following restrictions or constraints along with Servlet security constraints using appropriate URL patterns and role mappings in web.xml.

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Disable unneeded HTTP methods by 403</web-resource-name>

        <url-pattern>/Public/*</url-pattern>
        <url-pattern>/Push/*</url-pattern>
        <url-pattern>/javax.faces.resource/*</url-pattern>

        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
</security-constraint>

<deny-uncovered-http-methods/> <!-- Requires Servlet 3.1 -->

How to make the given path parameter optional?

The server in use is WildFly 10.0.0 final / Java EE 7.

Tiny
  • 27,221
  • 105
  • 339
  • 599
  • I wonder what the security constraint has got to do with the concrete question. Question would still stand good when you leave out it. – BalusC Mar 03 '16 at 21:20
  • I added that section as additional information because GlassFish (4.1) would work with URIs like `/Push/CartPush` even though `/Push/*` were excluded or removed from `web.xml`. WildFly on the other hand, would report `403` with `/Push/CartPush`, when that `` was excluded from `web.xml`. I am unaware of the reason. – Tiny Mar 03 '16 at 22:01

1 Answers1

11

Unfortunately, WS URI template is documented to follow [RFC 6570 Level 1] 2 templates. So a Level 3 template like /Push/CartPush{/token} won't work out.

Your best bet is always suffixing it with / and let the token be an empty string.

var token = "";
var ws = new WebSocket("wss://localhost:8443/ContextPath/Push/CartPush/" + token);

It might be worth an enhancement request at WS spec guys.

Given that the parameter is fully defined in the client, an alternative is to supply it as a request parameter. Naturally, request parameters represent client-defined parameters.

var ws = new WebSocket("wss://localhost:8443/ContextPath/Push/CartPush?token=" + token);
String token = session.getRequestParameterMap().get("token").get(0);
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555