Warp: mount everything in a directory on the root path

I am trying to set up a SPA using Warp that consists of some static files and a websocket as follows:

/* set up routes */
let socket_route = warp::path("socket")
    .and(warp::ws())
    .map(|ws: warp::ws::Ws | {
        ws.on_upgrade(move |socket| ws_handler(socket))
    });
let static_route = warp::path::end()
    .and(warp::fs::dir("/var/www"));

/* run the server */
warp::serve(socket_route.or(static_route)).run(([127, 0, 0, 1], 3030)).await;

What I would like is for everything inside of /var/www to be available at /, but I have been unable to make this happen. Using the above set up, what currently happens is requesting / gives back /var/www/index.html, but requesting /index.html or /favicon.png results in the files not being found:

[2020-12-04T16:53:55Z TRACE warp::filters::path] "socket"?: "index.html"
[2020-12-04T16:53:55Z DEBUG warp::filter::service] rejected: Rejection(NotFound)
[2020-12-04T16:53:55Z TRACE warp::filters::path] "socket"?: "favicon.ico"
[2020-12-04T16:53:55Z DEBUG warp::filter::service] rejected: Rejection(NotFound)

I tried to swap warp::path::end() for warp::path("/") but this is not allowed:

exact path segments should not contain a slash: "/"

I found the solution, it is pretty obvious once you have it working but up until that point it is difficult to see. I needed to change my static route to:

let static_route = warp::get()
    .and(warp::fs::dir("/var/www"));

Which makes perfect sense. You start with a GET and then apply no further (path) filters to it.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.