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

Http cache #496

Merged
merged 7 commits into from
Mar 23, 2017
Merged

Http cache #496

merged 7 commits into from
Mar 23, 2017

Conversation

mnot
Copy link
Member

@mnot mnot commented Mar 1, 2017

For #373.

Also should help #336 (since HTTP clearly says this, and there's a direct reference now).

I think it addresses #307 (although Anne may want a different approach).

Touches #144.


Preview | Diff

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

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

This looks great. Mostly minor nits. Do we have tests for this already somewhere?

fetch.bs Outdated
@@ -3342,86 +3345,149 @@ steps:

<li><p>Let <var>response</var> be null.

<li><p>Let the <var>revalidating</var> and <var>partial</var> flags be unset.
Copy link
Member

Choose a reason for hiding this comment

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

I think we should either make these booleans or pull flag into their name.

fetch.bs Outdated

<p class=note>As mandated by HTTP, this still takes the `<code>Vary</code>`
<a>header</a> into account.
<p class=note>The cache key used to locate a stored response must include the value of the
Copy link
Member

Choose a reason for hiding this comment

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

We cannot use must in notes. I think the right solution here is probably to not make this a note, apart from maybe the bit that is explaining the requirement.

fetch.bs Outdated

<li>
<!-- If response is still null, we require a forward request. -->
Copy link
Member

Choose a reason for hiding this comment

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

Minor nit: "forwarded request" seems to be the term of art?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. Should I factor that out, explain it, or?

Copy link
Member

Choose a reason for hiding this comment

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

I meant to change from "forward" to "forwarded".

fetch.bs Outdated
<a for=response>status</a> begins with <code>2</code> or <code>3</code>, invalidate appropriate
stored responses in the HTTP cache, as per the
"<a href=https://tools.ietf.org/html/rfc7234#section-4.4>Invalidation</a>" chapter of
<cite>HTTP Caching</cite> [[!HTTP-CACHING]], and set <var>storedResponse</var> to null.
Copy link
Member

Choose a reason for hiding this comment

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

This step looks a little scary. 1 "unsafe" can change over time. Are we expecting implementations to change their result over time? If so we should probably reference "unsafe". I guess we also want tests for this.

Also, I think I'm mostly treating status as an integer, so a range check would make more sense, e.g., in the range 200 to 399, inclusive.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm. I can reference the part of HTTP that defines the registry:
http://httpwg.org/specs/rfc7231.html#method.registry
... or I can reference the registry directly:
http://www.iana.org/assignments/http-methods/http-methods.xhtml

Preference?

Copy link
Member

Choose a reason for hiding this comment

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

I think http://httpwg.org/specs/rfc7231.html#safe.methods would be the most logical. I mostly meant that the term was not referenced. That it's variable is also somewhat problematic, but maybe okay.

fetch.bs Outdated
"<code>force-cache</code>" or "<code>only-if-cached</code>", then set
<var>response</var> to the <a for=/>response</a> in the HTTP cache for
<var>httpRequest</var>.
<p>Let <var>storedResponse</var> be the result of selecting a response from the HTTP cache,
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be good to declare storedResponse upfront just like partial/revalidating since you end up using it outside these substeps.

Copy link
Member

Choose a reason for hiding this comment

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

And then here you just say "Set storedResponse" to the result of selecting a ..., if any." (meaning it keeps its initial value otherwise).

Copy link
Member Author

Choose a reason for hiding this comment

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

Where is "if any"? Phrase ends with "or null if no stored response is selected."

Copy link
Member

Choose a reason for hiding this comment

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

I meant that if you declare storedResponse upfront outside these substeps as "Let storedResponse be null" (to make it clearer what its scope is) you can rephrase this too.

fetch.bs Outdated
chapter of <cite>HTTP Caching</cite>. [[!HTTP-CACHING]]
<li><p>Set <var>response</var> to <var>storedResponse</var>.

<p class="note">This updates the stored response in cache as well.
Copy link
Member

Choose a reason for hiding this comment

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

It seems this note is more fitting for the paragraph above? Also, the formatting is a little off. If you have multiple <p> descendants, they need to be on their own line and indented by one.

fetch.bs Outdated

<li><p>Set <var>response</var> to <var>storedResponse</var>.

<p class="note">This updates the stored response in cache as well.
Copy link
Member

Choose a reason for hiding this comment

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

Same here. It seems this note should be for one step earlier.

fetch.bs Outdated
</ol>
<!-- TODO: account for partial request failure -->

<li><p>If <var>response</var> is null, run these substeps:
Copy link
Member

Choose a reason for hiding this comment

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

<p> needs to be on a new line due to the sibling <ol>.

fetch.bs Outdated

<p class=note>The cache key used to store the response must include the value of the
<var>credentials</var> flag, to ensure that a stored response to a request with credentials is
not used to satisfy a request without credentials.
Copy link
Member

Choose a reason for hiding this comment

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

Same comment as earlier, no requirements in notes. Also a formatting glitch here due to multiple <p> inside the <li>.

@mnot
Copy link
Member Author

mnot commented Mar 2, 2017

I think all feedback is addressed. Tests are next; planning to start with the direct requirements added here, then work on those incorporated by reference from the RFCs.

@annevk
Copy link
Member

annevk commented Mar 3, 2017

That is great, while you work on tests, would you mind clicking the checkbox that enables me to push to your branch (should be in the sidebar)? I was mainly thinking of collapsing your commits into one and maybe adding one or more follow up cleanup commits for you to review.

@annevk annevk added the needs tests Moving the issue forward requires someone to write tests label Mar 3, 2017
@mnot
Copy link
Member Author

mnot commented Mar 6, 2017

Box ticked.

mnot and others added 2 commits March 6, 2017 10:54
In particular:

* Be more specific about terminology
* Detail more clearly how requests are to be modified
* Make sure credentials flag is taken into account

Fixes #373, fixes #336, and fixes #307. Helps with #144.
@annevk
Copy link
Member

annevk commented Mar 6, 2017

For some reason the box got unticked after I force pushed your collapsed changes with a revised commit message. Can you tick it again as I have a bunch of changes I wanted to push in a new commit? I'm guessing you created this branch well before GitHub introduced this feature, leading to this somewhat weird situation.

@mnot
Copy link
Member Author

mnot commented Mar 6, 2017

Weird. Done.

@annevk
Copy link
Member

annevk commented Mar 7, 2017

Thanks, fixup pushed.

@annevk
Copy link
Member

annevk commented Mar 7, 2017

Curiously enough it seems again unchecked. I'll contact GitHub support about it now.

@annevk
Copy link
Member

annevk commented Mar 7, 2017

(Sigh, if you want to troubleshoot the push access revocation issue, you need to contact GitHub yourself. I gave them a rather detailed explanation of what went down over several emails, but that didn't cut it...)

@mnot
Copy link
Member Author

mnot commented Mar 8, 2017

Any preference on where to put the tests -- e.g., http/cache, fetch/cache, or? Assuming I'll be testing with fetch, not XHR.

@mnot
Copy link
Member Author

mnot commented Mar 8, 2017

I think I've got a rough work list for tests:

  • Do credentials form part of the cache key?
  • Are If-None-Match and If-Modified-Since sent correctly?
  • Are cached responses invalidated?
  • Are response headers updated on a 304?
  • Are stale responses used when there's a network error?
  • Is partial content handled correctly, and If-Range, etc. generated?
  • Are non-200 status codes cached?
  • Is Vary handled correctly?
  • Are Cache-Control request directives respected?
  • Is the precedence of Expires and max-age handled correctly?
  • Is heuristic caching done?
    • Is the 'public' response directive honoured?
  • Is CC: no-store handled correctly?
  • is no-cache handled correctly in requests and responses?

The rest seems to be pretty well covered by fetc/api/request-cache.js (which I found after the comment above).

I've already written and stashed a few tests. Some notes:

Invalidation

Chrome partially implements; it invalidates the cache upon a successful PUT or unrecognised method (e.g., FOO). Firefox and Safari TP do not.

Credentials in the Cache Key

Firefox implements; Chrome and Safari TP appear not to. This could be because it's spec'd and tested based upon the credentials flag; they may be looking for the actual credentials. Will play with it a bit more.

Using Stale Responses on a Network Error

This isn't implemented, AFAICT, although the responses generated by the framework are extremely stale, and that may be playing into it. It might be best to take this out of the spec for now; it's allowed but not mandated by HTTP.

As per testing, doesn't seem to be implemented, and this
is optional in HTTP anyway.
@mnot
Copy link
Member Author

mnot commented Mar 8, 2017

Fixed my tests for invalidation; support is much better than I thought.

Firefox and Safari TP invalidate everything correctly, but they over-invalidate (i.e., they do so even when the response is unsuccessful - 500 in this case).

Safari also shows a bit of variance when hitting 'reload', but I see that in other tests too.

Chrome only invalidates on POST and DELETE, regardless of whether the response is successful.

See:
https://github.com/mnot/web-platform-tests/tree/http-cache

@annevk
Copy link
Member

annevk commented Mar 8, 2017

fetch/cache or fetch/http-cache seems okay to me. I'd prefer fetch/ over http/ since some of the requirements are outlined here and we're testing the integration.

@mnot
Copy link
Member Author

mnot commented Mar 14, 2017

I think my tests are done. Before I do a pull, one question: I have an additional page of tests for partial content (i.e., range requests), but as far as I can tell, they're not supported by any browser, except Safari TP -- and its support is extremely basic.

My inclination is to pull the specification of partial content support in the Fetch HTTP cache; it's an optional feature of HTTP caching, and I don't think we're going to convince other browsers to implement (unless someone suddenly gets VERY interested).

Thoughts? See also #144 (which I'll update in a moment).

@annevk
Copy link
Member

annevk commented Mar 14, 2017

It seems reasonable to omit processing requirements, but we should at least have a note indicating we are aware of the feature and that it's simply not sufficiently supported or some such.

Having the tests somewhere seems good though in case browsers get interested at some point. Especially given the surprise you got from mcmanus.

@mnot
Copy link
Member Author

mnot commented Mar 16, 2017

I think tests are ready (sorry for the last minute additions). I'm thinking we should remove the incorporation of credentials into the cache key from this pull, at least until #307 progresses. Make sense?

@annevk
Copy link
Member

annevk commented Mar 16, 2017

I guess that's fair.

@mnot
Copy link
Member Author

mnot commented Mar 16, 2017

Done.

@annevk
Copy link
Member

annevk commented Mar 20, 2017

Can you click the checkbox again so I can push to your branch?

I think this is all good now. Are the tests ready to land as well?

@annevk annevk removed the needs tests Moving the issue forward requires someone to write tests label Mar 20, 2017
<li>
<p>If <var>response</var> is null, run these substeps:
<li>
<p>If the <var>revalidatingFlag</var> is set, then:
Copy link
Collaborator

Choose a reason for hiding this comment

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

If I'm reading this correctly, nothing assigns storedResponse to response if revalidation is not needed, and the cache-mode is not force-cache or only-if-cached.
Am I reading this correctly? If so, is this intentional? I'd expect such assignment to happen if no revalidation is needed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, thanks - that got acccidentally removed in 2ae9df0. Will fix.

@mnot
Copy link
Member Author

mnot commented Mar 23, 2017

Checkbox clicked. Yes, I think this is ready, and so are tests; doubtless there will be more of each, but it's good for now.

annevk pushed a commit to web-platform-tests/wpt that referenced this pull request Mar 23, 2017
@annevk annevk merged commit cbca2c2 into whatwg:master Mar 23, 2017
@annevk
Copy link
Member

annevk commented Mar 23, 2017

🍸

@youennf
Copy link
Collaborator

youennf commented Mar 23, 2017

That is a lot of test :)
Is WebKit all fine?

@mnot
Copy link
Member Author

mnot commented Mar 24, 2017

AIUI Webkit doesn't do the HTTP caching layer -- or has this changed? I tested Safari TP, see here:
https://www.mnot.net/blog/2017/03/16/browser-caching
In a nutshell, pretty well, a few places to look. Can file bugs if you point me to the right place to do it.

@youennf
Copy link
Collaborator

youennf commented Mar 24, 2017

WebKit has a bunch of HTTP caches, most notably https://trac.webkit.org/raw-attachment/wiki/March%202015%20Meeting/Disk%20cache.pdf and memory cache.

This is interesting even if it is related to the underlying HTTP library.
https://bugs.webkit.org is the usual place for feedback.

@annevk
Copy link
Member

annevk commented Mar 24, 2017

@mnot https://bugs.webkit.org/enter_bug.cgi?product=WebKit in particular (random component, prefix subject with "HTTP cache: ").

@mnot
Copy link
Member Author

mnot commented Apr 11, 2017

Safari TP bugs:

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

Successfully merging this pull request may close these issues.

4 participants