browser(firefox): expose Response.fromServiceWorker (#14606)

This property is "true" when network response was fulfilled
by the service worker.
This commit is contained in:
Dmitry Gozman 2022-06-02 17:16:19 -07:00 committed by GitHub
parent 789f319eda
commit 94a0d669b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 5 deletions

View File

@ -1,2 +1,2 @@
1328
Changed: yurys@chromium.org Wed 01 Jun 2022 08:28:56 PM PDT
1329
Changed: dgozman@gmail.com Thu Jun 2 16:19:39 PDT 2022

View File

@ -533,6 +533,9 @@ class NetworkRequest {
// remoteAddress is not defined for cached requests.
}
const fromServiceWorker = this._networkObserver._channelIdsFulfilledByServiceWorker.has(this.requestId);
this._networkObserver._channelIdsFulfilledByServiceWorker.delete(this.requestId);
pageNetwork.emit(PageNetwork.Events.Response, {
requestId: this.requestId,
securityDetails: getSecurityDetails(this.httpChannel),
@ -543,6 +546,7 @@ class NetworkRequest {
status,
statusText,
timing,
fromServiceWorker,
}, this._frameId);
}
@ -591,6 +595,7 @@ class NetworkObserver {
this._channelToRequest = new Map(); // http channel -> network request
this._expectedRedirect = new Map(); // expected redirect channel id (string) -> network request
this._channelIdsFulfilledByServiceWorker = new Set(); // http channel ids that were fulfilled by service worker
const protocolProxyService = Cc['@mozilla.org/network/protocol-proxy-service;1'].getService();
this._channelProxyFilter = {
@ -636,6 +641,7 @@ class NetworkObserver {
helper.addObserver(this._onResponse.bind(this, false /* fromCache */), 'http-on-examine-response'),
helper.addObserver(this._onResponse.bind(this, true /* fromCache */), 'http-on-examine-cached-response'),
helper.addObserver(this._onResponse.bind(this, true /* fromCache */), 'http-on-examine-merged-response'),
helper.addObserver(this._onServiceWorkerResponse.bind(this), 'service-worker-synthesized-response'),
];
}
@ -700,6 +706,14 @@ class NetworkObserver {
request._sendOnResponse(fromCache);
}
_onServiceWorkerResponse(channel, topic) {
if (!(channel instanceof Ci.nsIHttpChannel))
return;
const httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
const channelId = httpChannel.channelId + '';
this._channelIdsFulfilledByServiceWorker.add(channelId);
}
dispose() {
this._activityDistributor.removeObserver(this);
const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);

View File

@ -501,6 +501,7 @@ const Network = {
statusText: t.String,
headers: t.Array(networkTypes.HTTPHeader),
timing: networkTypes.ResourceTiming,
fromServiceWorker: t.Boolean,
},
'requestFinished': {
requestId: t.String,

View File

@ -1,2 +1,2 @@
1326
Changed: yurys@chromium.org Wed 01 Jun 2022 08:27:21 PM PDT
1327
Changed: dgozman@gmail.com Thu Jun 2 16:19:39 PDT 2022

View File

@ -533,6 +533,9 @@ class NetworkRequest {
// remoteAddress is not defined for cached requests.
}
const fromServiceWorker = this._networkObserver._channelIdsFulfilledByServiceWorker.has(this.requestId);
this._networkObserver._channelIdsFulfilledByServiceWorker.delete(this.requestId);
pageNetwork.emit(PageNetwork.Events.Response, {
requestId: this.requestId,
securityDetails: getSecurityDetails(this.httpChannel),
@ -543,6 +546,7 @@ class NetworkRequest {
status,
statusText,
timing,
fromServiceWorker,
}, this._frameId);
}
@ -591,6 +595,7 @@ class NetworkObserver {
this._channelToRequest = new Map(); // http channel -> network request
this._expectedRedirect = new Map(); // expected redirect channel id (string) -> network request
this._channelIdsFulfilledByServiceWorker = new Set(); // http channel ids that were fulfilled by service worker
const protocolProxyService = Cc['@mozilla.org/network/protocol-proxy-service;1'].getService();
this._channelProxyFilter = {
@ -636,6 +641,7 @@ class NetworkObserver {
helper.addObserver(this._onResponse.bind(this, false /* fromCache */), 'http-on-examine-response'),
helper.addObserver(this._onResponse.bind(this, true /* fromCache */), 'http-on-examine-cached-response'),
helper.addObserver(this._onResponse.bind(this, true /* fromCache */), 'http-on-examine-merged-response'),
helper.addObserver(this._onServiceWorkerResponse.bind(this), 'service-worker-synthesized-response'),
];
}
@ -700,6 +706,14 @@ class NetworkObserver {
request._sendOnResponse(fromCache);
}
_onServiceWorkerResponse(channel, topic) {
if (!(channel instanceof Ci.nsIHttpChannel))
return;
const httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
const channelId = httpChannel.channelId + '';
this._channelIdsFulfilledByServiceWorker.add(channelId);
}
dispose() {
this._activityDistributor.removeObserver(this);
const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);

View File

@ -501,6 +501,7 @@ const Network = {
statusText: t.String,
headers: t.Array(networkTypes.HTTPHeader),
timing: networkTypes.ResourceTiming,
fromServiceWorker: t.Boolean,
},
'requestFinished': {
requestId: t.String,

View File

@ -33,7 +33,7 @@ it('should work with navigation @smoke', async ({ page, server }) => {
expect(requests.get('style.css').isNavigationRequest()).toBe(false);
});
it('should intercept after a service worker', async ({ page, server, isAndroid, isElectron }) => {
it('should intercept after a service worker', async ({ page, server, browserName, isAndroid, isElectron }) => {
it.skip(isAndroid);
it.skip(isElectron);
@ -61,6 +61,14 @@ it('should intercept after a service worker', async ({ page, server, isAndroid,
// Page route is not applied to service worker initiated fetch.
const nonInterceptedResponse = await page.evaluate(() => window['fetchDummy']('passthrough'));
expect(nonInterceptedResponse).toBe('FAILURE: Not Found');
// Firefox does not want to fetch the redirect for some reason.
if (browserName !== 'firefox') {
// Page route is not applied to service worker initiated fetch with redirect.
server.setRedirect('/serviceworkers/fetchdummy/passthrough', '/simple.json');
const redirectedResponse = await page.evaluate(() => window['fetchDummy']('passthrough'));
expect(redirectedResponse).toBe('{"foo": "bar"}\n');
}
});
it('should work with glob', async () => {