Closed Bug 1217501 Opened 9 years ago Closed 9 years ago

theguardian.com offline serviceworker does not work

Categories

(Core :: DOM: Service Workers, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla44
Tracking Status
firefox44 --- fixed

People

(Reporter: bkelly, Assigned: bkelly)

References

Details

Attachments

(5 files)

The Guardian recently added a service worker that shows a cross-world puzzle when offline: https://twitter.com/OliverJAsh/status/657200027983585280 It does not work in our current firefox nightly, even with opaque interception enabled. I don't see any obvious errors in the console, browser console, or debug stderr.
Their service worker is doing the following: var doesRequestAcceptHtml = function (request) { return request.headers.get('Accept') .split(',') .some(function (type) { return type === 'text/html'; }); }; this.addEventListener('fetch', function (event) { if (doesRequestAcceptHtml(event.request)) { isCacheUpdated().then(function (isUpdated) { if (!isUpdated) { updateCache().then(deleteOldCaches); } }); } event.respondWith( fetch(event.request) .catch(function () { // If a request is cached, respond with that. Otherwise respond // with the shell, whose subresources will be in the cache. return caches.match(event.request).then(function (response) { if (response) { return response; } else { if (doesRequestAcceptHtml(event.request)) { return caches.match('/offline-page'); } } }) }) ); }); doesRequestAcceptHtml() returns false here, so they end up resolving the promise to undefined, and we get the following warning: "FetchEvent::RespondWith was passed a promise resolved to a non-Object value".
The spec is a bit unclear to me here. I'll write a spec issue and note the problem with the author of the site.
Hi, I am the author of this piece of work. I would like to help getting it to work in Firefox. Do you know why `doesRequestAcceptHtml` returns false? I only want to serve the offline page if the request accepts HTML.
Actually, I think the spec is clear that respondWith(undefined) should be an error. I wrote a spec issue anyway, though: https://github.com/slightlyoff/ServiceWorker/issues/766 Although, now that I look at comment 1, I'm not sure what else could be done there. The code has already attempted a fetch(event.request).
Oh, I think the service-worker.js may be using a chrome-specific promise extension. Its doing Promise.all().concat().
Gah. I can't read. The .concat() is inside the Promise.all(). I'll go drink more coffee before trying to "help" more here.
(In reply to oliverjash from comment #3) > Hi, I am the author of this piece of work. I would like to help getting it > to work in Firefox. > > Do you know why `doesRequestAcceptHtml` returns false? I only want to serve > the offline page if the request accepts HTML. Oliver, thanks for your help. I think we're (or at least I am) still confused about whats failing, though. I think its reasonable for your code to do what its doing in comment 1. We'll keep looking.
Its possible we are killing the service worker before it can update the cache. The update is done outside of the respondWith().
(In reply to Ben Kelly [:bkelly] from comment #8) > Its possible we are killing the service worker before it can update the > cache. The update is done outside of the respondWith(). This isn't our main problem. I checked in my profile and the cache has all the resources stored.
Ehsan debugged more and discovered we are throwing in the FetchEvent handler. This is because of this code: var doesRequestAcceptHtml = function (request) { return request.headers.get('Accept') .split(',') .some(function (type) { return type === 'text/html'; }); }; It appears we are setting the 'Accept' header further down in the network code after interception. Per step 3 of Fetching, however, we should set both Accept and Accept-Language before interception: https://fetch.spec.whatwg.org/#fetching
Apparently we never did this correctly in e10s mode, but we regressed it in non-e10s in bug 1200337. We need to set some standard headers after interception and some before interception.
Blocks: 1200337
Assignee: nobody → ehsan
Assignee: ehsan → bkelly
Status: NEW → ASSIGNED
We had a lengthy discussion over how to fix this on IRC. We agreed on exposing whatever the Accept header is set to by Necko (or the consumer). Also it seems that fetch() isn't supposed to send an Accept header at all. I filed https://github.com/whatwg/fetch/issues/142 to fix that.
It turns out we hid too many headers from the SW in bug 1200337. We still need to expose the Accept and Accept-Language headers.
Attachment #8678268 - Flags: review?(mcmanus)
Attachment #8678268 - Flags: review?(mcmanus) → review+
Comment on attachment 8678270 [details] [diff] [review] P2 Send */* for fetch() default Accept header. r=ehsan Review of attachment 8678270 [details] [diff] [review]: ----------------------------------------------------------------- r=me pending resolution to https://github.com/whatwg/fetch/issues/142. ::: dom/fetch/FetchDriver.cpp @@ +306,2 @@ > for (uint32_t i = 0; i < headers.Length(); ++i) { > + if (headers[i].mName == NS_LITERAL_CSTRING("accept")) { Nit: please prepend |!hasAccept &&| to avoid string comparisons once we have found one header.
Attachment #8678270 - Flags: review?(ehsan) → review+
Comment on attachment 8678271 [details] [diff] [review] P3 Check Accept header visibility in service worker fetch event. r=ehsan Review of attachment 8678271 [details] [diff] [review]: ----------------------------------------------------------------- ::: testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-header-visibility-iframe.html @@ +40,5 @@ > + // Check for custom accept header > + fetch(uri, { headers: headers }).then(function(response) { > + return response.text(); > + }).then(function(text) { > + dump('### ### custom accept ' + text + '\n'); Nit: debugging left-over @@ +55,5 @@ > + // Check for default accept header > + fetch(uri).then(function(response) { > + return response.text(); > + }).then(function(text) { > + dump('### ### default accept ' + text + '\n'); Here too.
Attachment #8678271 - Flags: review?(ehsan) → review+
(In reply to Ehsan Akhgari (don't ask for review please) from comment #16) > Comment on attachment 8678270 [details] [diff] [review] > P2 Send */* for fetch() default Accept header. r=ehsan > > r=me pending resolution to https://github.com/whatwg/fetch/issues/142. I don't think we should wait for the spec issue. Our current value is wrong no matter what. I have a separate bug filed to possibly remove the header.
Flags: needinfo?(ehsan)
Flags: needinfo?(ehsan)
(In reply to Ehsan Akhgari (don't ask for review please) from comment #16) > > for (uint32_t i = 0; i < headers.Length(); ++i) { > > + if (headers[i].mName == NS_LITERAL_CSTRING("accept")) { > > Nit: please prepend |!hasAccept &&| to avoid string comparisons once we have > found one header. I'm also going to use .EqualsLiteral() here. Thanks.
I filed bug 1218496 for detecting leaks of ErrorResult::Message in normal debug builds.
The error in comment 23 seems more related to the RequestCache change. I don't see how changing the Accept header would trigger this. Ehsan, do you have any ideas?
Flags: needinfo?(bkelly) → needinfo?(ehsan)
Err, never mind.
Flags: needinfo?(ehsan)
We need to fill the headers before setting the header guard in Cache API.
Comment on attachment 8679190 [details] [diff] [review] P4 Fill headers before setting guard when reading response from Cache. r=ehsan Review of attachment 8679190 [details] [diff] [review]: ----------------------------------------------------------------- Whoa! Do you know how this ever worked?
Attachment #8679190 - Flags: review?(ehsan) → review+
(In reply to Ehsan Akhgari (don't ask for review please) from comment #30) > Whoa! Do you know how this ever worked? No iterable headers makes it hard to test that a header isn't lost.
(In reply to Ben Kelly [:bkelly] from comment #31) > (In reply to Ehsan Akhgari (don't ask for review please) from comment #30) > > Whoa! Do you know how this ever worked? > > No iterable headers makes it hard to test that a header isn't lost. Fair enough. Now that bug 1108181 is fixed, do we have tests that would have caught this? If not, we should add them in a follow-up.
(In reply to Ehsan Akhgari (don't ask for review please) from comment #32) > Fair enough. Now that bug 1108181 is fixed, do we have tests that would > have caught this? If not, we should add them in a follow-up. The wpt tests do a little header asserting, but I guess they didn't catch this. We have a chrome-only way to set the header guard, so we should be able to write a mochitest, though.
See Also: → 1218632
Try shows that we ran into some restrictive checks in InternalHeaders with P4. We should loosen them as they are not required by the spec. https://treeherder.mozilla.org/#/jobs?repo=try&revision=22c74aa09df6
Attachment #8679207 - Flags: review?(ehsan)
Attachment #8679207 - Flags: review?(ehsan) → review+
Depends on: 1319846
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: