Spark: GET route prioritized over WebSocket route

Created on 29 Mar 2016  路  4Comments  路  Source: perwendel/spark

Using Spark 2.3, I am seeing a GET route prioritized over a webSocket route, even though I define the webSocket route first (as I should, per documentation). The following code:

public static void main(String[] args) {

    webSocket("/echo", EchoWebSocket.class);
    get("/hello", (req, res) -> {
        return "<html><body><h1>Hello World!</h1></body></html>";
    });

    // webSocket /echo route works if I comment this route out
    get("/*", (req, res) -> {
        res.status(404);
        return "<html><body><h1>Custom 404 Message</h1></body></html>";
    });
}

produces a 404 when I try to connect via webSocket to /echo.

I suppose I can work around this specific scenario if there is an alternate way to do custom 404 pages.

Bug

Most helpful comment

I also found that when I had the catch all route defined for 404s that the webSocket path was no longer being recognized. I haven't had time to dive deep and find the correct fix for this, but (and this is probably a hack) I found if you simply exclude the websocket address and return null, the websocket is fine. For example:

    get("*", (request, response) -> {

        String pathInfo = request.raw().getPathInfo();

        if (!pathInfo.equals("/websocket/path")) {

            logger.debug("Caught 404 for " + pathInfo);

            Map<String, Object> attributes = new HashMap<>();

            response.status(404);
            return render(attributes, "404.mst");
        } else {
            return null;
        }

    });

As far as I can tell there aren't any side effects as of yet. Hopefully this small hack will suffice until the root issue is addressed.

All 4 comments

This works fine:

 webSocket("/chat", ChatWebSocketHandler.class);
 get("/chat", (Request request, Response response) -> "ouch?");

But I also had a problem using get("*", ...).

This works fine:

Could that be because you are connecting to /chat/ in the javascript code and so get("/chat", ...) doesn't match with that? I tried get("/chat/", ...) and the problem occurs, whereas if I didn't have get("/chat/", ...), it works fine.

Looks like this occurs due to the fact that in EmbeddedJettyServer, handling web socket routes is done last.

I also had the same problem.
I use get("*", ... to process all the mismatched routers

I also found that when I had the catch all route defined for 404s that the webSocket path was no longer being recognized. I haven't had time to dive deep and find the correct fix for this, but (and this is probably a hack) I found if you simply exclude the websocket address and return null, the websocket is fine. For example:

    get("*", (request, response) -> {

        String pathInfo = request.raw().getPathInfo();

        if (!pathInfo.equals("/websocket/path")) {

            logger.debug("Caught 404 for " + pathInfo);

            Map<String, Object> attributes = new HashMap<>();

            response.status(404);
            return render(attributes, "404.mst");
        } else {
            return null;
        }

    });

As far as I can tell there aren't any side effects as of yet. Hopefully this small hack will suffice until the root issue is addressed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wowselim picture wowselim  路  5Comments

mhulse picture mhulse  路  7Comments

rbordon-meli picture rbordon-meli  路  5Comments

anxiaoyi picture anxiaoyi  路  3Comments

kiriti999 picture kiriti999  路  4Comments