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.
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.
Most helpful comment
I'd prefer
Options::SomeName. PerhapsOptions::RedirectRoot?