Rocket: StaticFiles should redirect directory requests without a trailing slash

Created on 11 Jan 2020  路  8Comments  路  Source: SergioBenitez/Rocket

I'm using rocket 0.4.2, and rocket_contrib::serve, on Ubuntu Linux 18.04.3 LTS and rust 1.42.0-nightly.

I'm using StaticFiles to serve a directory static/ containing two files: index.html and app.js, with

.mount("/static", StaticFiles::from("static"))

The file index.html includes the line

 <script src="app.js" type="text/javascript"></script>

If I visit http://localhost:8000/static/ in my browser, it loads my index page and the application script as expected:

GET /static/ text/html:
    => Matched: GET /static [10]
    => Outcome: Success
    => Response succeeded.
GET /static/app.js:
    => Matched: GET /static/<path..> [10]
    => Outcome: Success
    => Response succeeded.

However, if I visit http://localhost:8000/static instead, it loads my index page but fails to load the application script. The Rocket logs show this:

GET /static text/html:
    => Matched: GET /static [10]
    => Outcome: Success
    => Response succeeded.
GET /app.js:
    => Error: No matching routes for GET /app.js.
    => Warning: Responding with 404 Not Found catcher.
    => Response succeeded.

I expected the page to load correctly, whether it was requested with static/ or static. Actually, it only loads corectly if static/ is used; if static is used all relative URLs are interpreted relative to the parent directory rather than the static directory.

I would prefer Rocket to respond to a request for static with a 301 redirect to static/. In general, if the request does not have a trailing slash but the matching file is a directory, issue a redirect to the request URI with a trailing slash appended.

Thanks.

accepted enhancement request

Most helpful comment

I'd prefer Options::SomeName. Perhaps Options::RedirectRoot?

All 8 comments

Such a redirect should be doable in StaticFiles itself, possibly configurable, and it does seem like the right thing to do.

Some implementation guidance for this feature: routes can't be directly defined with a trailing slash, but navigating to a URI with a trailing slash will activate the corresponding route without a trailing slash. Whether the trailing slash was used or not can be detected by inspecting the URI (the &Origin request guard, or request.uri()).

Thanks - I'd be happy to have this as a configurable option if that was preferred for back-compatibility.

@kw217 I'd be in favor of such a configuration option, likely disabled by default.

For configuration, would you prefer StaticFiles::from("static").slash_dirs(true) or StaticFiles::new("static", Options::SlashDirs)? Also suggestions for a better name welcome :-)

I'd prefer Options::SomeName. Perhaps Options::RedirectRoot?

Would we redirect only the root / base path, or any subdirectory in that StaticFiles instance?

Any subdirectory, not just root. The same issue arises at all levels.

Options::NakedDirs, or perhaps, Options::UnterminatedDirs?

Or even, Options::RedirectDirWithNoTrailingSlashToTrailingSlashDir.

Ok, the first two are actual suggestions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GoRustafari picture GoRustafari  路  3Comments

denysvitali picture denysvitali  路  3Comments

Perseus101 picture Perseus101  路  4Comments

klnusbaum picture klnusbaum  路  4Comments

kitsuneninetails picture kitsuneninetails  路  4Comments