fix(service-worker): correctly serve `ngsw/state` with a non-root SW scope (#37922)
The Angular ServiceWorker can serve requests to a special virtual path, `ngsw/state`, showing [information about its internal state][1], which can be useful for debugging. Previously, this would only work if the ServiceWorker's [scope][2] was the root directory (`/`). Otherwise, (e.g. when building the app with `--baseHref=/some/path/`), the ServiceWorker would fail to detect a request to `/some/path/ngsw/state` as matching `ngsw/state` and would not serve it with the debugging information. This commit fixes it by ensuring that the ServiceWorker's scope is taken into account when detecting a request to `ngsw/state`. [1]: https://angular.io/guide/service-worker-devops#locating-and-analyzing-debugging-information [2]: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/scope Fixes #30505 PR Close #37922
This commit is contained in:
parent
b98314e306
commit
2156beed0c
|
@ -99,6 +99,8 @@ export class Driver implements Debuggable, UpdateSource {
|
|||
*/
|
||||
private loggedInvalidOnlyIfCachedRequest: boolean = false;
|
||||
|
||||
private ngswStatePath = this.adapter.parseUrl('ngsw/state', this.scope.registration.scope).path;
|
||||
|
||||
/**
|
||||
* A scheduler which manages a queue of tasks that need to be executed when the SW is
|
||||
* not doing any other work (not processing any other requests).
|
||||
|
@ -184,7 +186,7 @@ export class Driver implements Debuggable, UpdateSource {
|
|||
}
|
||||
|
||||
// The only thing that is served unconditionally is the debug page.
|
||||
if (requestUrlObj.path === '/ngsw/state') {
|
||||
if (requestUrlObj.path === this.ngswStatePath) {
|
||||
// Allow the debugger to handle the request, but don't affect SW state in any other way.
|
||||
event.respondWith(this.debugger.handleFetch(req));
|
||||
return;
|
||||
|
|
|
@ -893,6 +893,34 @@ describe('Driver', () => {
|
|||
expect(await scope.caches.keys()).not.toEqual([]);
|
||||
});
|
||||
|
||||
describe('serving ngsw/state', () => {
|
||||
it('should show debug info (when in NORMAL state)', async () => {
|
||||
expect(await makeRequest(scope, '/ngsw/state'))
|
||||
.toMatch(/^NGSW Debug Info:\n\nDriver state: NORMAL/);
|
||||
});
|
||||
|
||||
it('should show debug info (when in EXISTING_CLIENTS_ONLY state)', async () => {
|
||||
driver.state = DriverReadyState.EXISTING_CLIENTS_ONLY;
|
||||
expect(await makeRequest(scope, '/ngsw/state'))
|
||||
.toMatch(/^NGSW Debug Info:\n\nDriver state: EXISTING_CLIENTS_ONLY/);
|
||||
});
|
||||
|
||||
it('should show debug info (when in SAFE_MODE state)', async () => {
|
||||
driver.state = DriverReadyState.SAFE_MODE;
|
||||
expect(await makeRequest(scope, '/ngsw/state'))
|
||||
.toMatch(/^NGSW Debug Info:\n\nDriver state: SAFE_MODE/);
|
||||
});
|
||||
|
||||
it('should show debug info when the scope is not root', async () => {
|
||||
const newScope =
|
||||
new SwTestHarnessBuilder('http://localhost/foo/bar/').withServerState(server).build();
|
||||
new Driver(newScope, newScope, new CacheDatabase(newScope, newScope));
|
||||
|
||||
expect(await makeRequest(newScope, '/foo/bar/ngsw/state'))
|
||||
.toMatch(/^NGSW Debug Info:\n\nDriver state: NORMAL/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cache naming', () => {
|
||||
// Helpers
|
||||
const cacheKeysFor = (baseHref: string) =>
|
||||
|
|
Loading…
Reference in New Issue