Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for Last-Modified and If-Modified-Since headers #1376

Closed
wants to merge 1 commit into from

Conversation

matiaskotlik
Copy link

#989, #95

Adds support for Last-Modified and If-Modified-Since headers.

  • If a NamedFile is requested with the If-Modified-Since header set and the file was last modified before the date in the header, the server instead responds with 304 Not Modified
  • If that header is not present, the file is sent over with the Last-Modified header (on supported platforms/OS)

I'm pretty new to rocket so let me know if I'm doing anything wrong and if the style is ok! (no rustfmt... shame 😛 )

Copy link
Collaborator

@jebrosen jebrosen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally speaking, I'm in favor of having this or at least something similar. I have not audited the date comparison code, but that will really need to be correct. I do have two wider concerns:

  • Reliability of timestamps from the filesystem is not necessarily great; there are many pitfalls here. StaticFiles/NamedFile seems like an okay place to do this with a few safeguards, such as ignoring filesystem dates that are from the future.
  • Interactions with other preconditions. This PR seems to ignore most of https://tools.ietf.org/html/rfc7232#section-6. That might be okay! For example, maybe NamedFile specifically does not ever have to worry about whether If-None-Match is present, since NamedFile never generates an ETag header. But like the date comparisons, this is an easy thing to get subtly wrong and needs some scrutiny.
  • And one very minor downside / bikeshed: with this implementation, we would effectively remove "File with extension-based MIME detection" and replace it with "File with extension-based MIME detection and filesystem-based time checking"; maybe this should be a builder or a separate type so that the two features aren't tied together.

impl<'r> Responder<'r, 'static> for NamedFile {
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
// using the file handle `self.1` is too much trouble here, tokio's `File::metadata` method
// is async, so is into_std, and try_into_std gives you a `io::Result<std::fs::File>`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't safely use std::fs::metadata even in this function, since it's blocking. The problem of respond_to being async or non-async came up a bit, and we had resolved it as "async work should happen in an async constructor" (in this case NamedFile::open).

This does mean that we would need to query the modification time even if there is no If-Modified-Since header to compare to; I'm not sure how big of a problem that is in terms of performance.

.map(|duration| OffsetDateTime::from_unix_timestamp(duration.as_secs() as i64));

// if file_mod_time is < this date, we don't need to re-send the file.
let cutoff = req.headers().get_one("If-Modified-Since")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should ensure the method was GET or HEAD, and maybe should check other preconditions.

@SergioBenitez
Copy link
Member

Checking in: what's the status here? We also have #1219; should one be closed in favor of another?

@jebrosen
Copy link
Collaborator

I hadn't realized there were two PRs for this. I'm closing this one in favor of #1219, which is opt-in (resolving most of my concerns about reliability and composability) and more complete (including examples and tests).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants