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

Strong ETag validators #24387

Merged
merged 1 commit into from Apr 2, 2016
Merged

Strong ETag validators #24387

merged 1 commit into from Apr 2, 2016

Conversation

jeremy
Copy link
Member

@jeremy jeremy commented Apr 1, 2016

  • Introduce Response#strong_etag= and #weak_etag= and analogous options
    for fresh_when and stale?. Response#etag= sets a weak ETag.

    Strong ETags are desirable when you're serving byte-for-byte identical
    responses that support Range requests, like PDFs or videos (typically
    done by reproxying the response from a backend storage service).
    Also desirable when fronted by some CDNs that support strong ETags
    only, like Akamai.

  • No longer strips quotes (") from ETag values before comparing them.
    Quotes are significant, part of the ETag. A quoted ETag and an unquoted
    one are not the same entity.

  • Support If-None-Match: *. Rarely useful for GET requests; meant
    to provide some optimistic concurrency control for PUT requests.

* Introduce `Response#strong_etag=` and `#weak_etag=` and analogous options
  for `fresh_when` and `stale?`. `Response#etag=` sets a weak ETag.

  Strong ETags are desirable when you're serving byte-for-byte identical
  responses that support Range requests, like PDFs or videos (typically
  done by reproxying the response from a backend storage service).
  Also desirable when fronted by some CDNs that support strong ETags
  only, like Akamai.

* No longer strips quotes (`"`) from ETag values before comparing them.
  Quotes are significant, part of the ETag. A quoted ETag and an unquoted
  one are not the same entity.

* Support `If-None-Match: *`. Rarely useful for GET requests; meant
  to provide some optimistic concurrency control for PUT requests.
@jeremy jeremy merged commit 863d385 into rails:master Apr 2, 2016
@jeremy jeremy deleted the strong-etag branch April 2, 2016 01:09
y-yagi added a commit to y-yagi/rails that referenced this pull request Oct 24, 2016
The document is written with "only generate weak", but it can also be used to
strong etag.
Also, add missing entory for rails#24387
maclover7 pushed a commit to maclover7/rails that referenced this pull request Nov 16, 2016
The document is written with "only generate weak", but it can also be used to
strong etag.
Also, add missing entory for rails#24387
@@ -86,12 +101,16 @@ def etag(&etagger)
#
# before_action { fresh_when @article, template: 'widgets/show' }
#
def fresh_when(object = nil, etag: object, last_modified: nil, public: false, template: nil)
def fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, template: nil)
weak_etag ||= etag || object unless strong_etag
Copy link
Member

Choose a reason for hiding this comment

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

Hello @jeremy ! I have a question about this change (if you remember… it's almost one year old).

Before this PR, I was able to use fresh_when to cache a page based solely on last_modified, and completely ignoring the body.

For instance, I could have an action like this:

def index
  @sections = Section.all
  fresh_when @sections, etag: nil
end

which would render the page if any Section had been updated, or respond with 304 otherwise.

After this PR, I cannot find a way to not set an etag.
Even if I pass etag: nil or etag: false, this line:

weak_etag ||= etag || object unless strong_etag

ends up using object as the value of etag.

I understand the good intention of this PR: in principle, if your response has changed (and therefore Etag), you want to expire the cache. However, in my case, using last_modified is enough. If last_modified didn't change, then I want to serve the cached version without checking the Etag as well.

Am I correct in saying that this approach cannot be taken anymore after this PR?

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

Successfully merging this pull request may close these issues.

None yet

3 participants