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

Fixes a bug with cacheFirst handler + maxAgeSeconds + CORS request #694

Merged
merged 4 commits into from
Jul 26, 2017

Conversation

jeffposnick
Copy link
Contributor

R: @addyosmani @gauntface
CC: @pbakaus

Fixes #691

This fixes a bug that would prevent a response used in a cache-first handler from properly triggering maxAgeSeconds-based expiration iff that response lacked a Date: header. A CORS-response without the Date: header specifically whitelisted via Access-Control-Expose-Headers could trigger this scenario, as @pbakaus encountered.

This also changes the method signature of the cacheWillMatch lifecycle callback to be async (i.e. return a Promise), since we now want to wait for it to complete before returning a cached response to the client (to ensure that any expiration that's necessary gets performed). That should (arguably) be considered a breaking change, since cacheWillMatch is part of the public interface.

@jeffposnick
Copy link
Contributor Author

Actually, as an alternative to changing cacheWillMatch to be async, I could keep things as-is without affecting the real-world behavior for most scenarios. The downside is that it could introduce some flakiness into the new test and require longer timeouts to reduce the risk of that flakiness. That might be an acceptable trade-off, though.

@@ -165,6 +166,8 @@ class CacheExpiration {
// Only return false if all the conditions are met.
return false;
}
} else {
this.expireEntries({cacheName, now});

Choose a reason for hiding this comment

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

If there is no maxAgeSeconds, can we really regard the entry as fresh?

I'm just slightly confused at what this is solving.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a little hard to line up the braces, but this else is associated with if (dateHeader). I'll clarify in a comment what's going on.

Choose a reason for hiding this comment

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

Shouldn't this return false?

// Only return false if all the conditions are met.
return false;
}
// will return NaN, and the comparison will always be false. We want

Choose a reason for hiding this comment

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

Why not just check for NaN and treat as a special case? This negation is likely to cause confusion.

Copy link
Member

Choose a reason for hiding this comment

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

I found opting for the negation strategy here a little hard to parse. I'm similarly having trouble reasoning why we're not just special casing NaN per Matt's comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will switch.

Copy link

@gauntface gauntface left a comment

Choose a reason for hiding this comment

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

Nit with the NaN check, otherwise looks good - thanks for adding the comments.


it(`should work properly when a cache-first strategy + maxAgeSeconds is used, and responses lack a Date header`, async function() {
// See the comment later about a source of potential flakiness.
this.retries(2);

Choose a reason for hiding this comment

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

you should probably set the timeout of this test case to 5 or 6 with this.timeout(6 * 1000);

Copy link
Member

@addyosmani addyosmani left a comment

Choose a reason for hiding this comment

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

LGTM minus one nit

@jeffposnick
Copy link
Contributor Author

PTAL.

return true;
}

// If we have a valid headerTime, then our response is fresh iff the
Copy link
Member

Choose a reason for hiding this comment

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

iff -> if

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@addyosmani
Copy link
Member

Smallest nit in the world. LGTM otherwise.

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.

Issue with cacheFirst + maxAgeSeconds for CORS resource
3 participants