Skip to content

Commit

Permalink
fix(service-worker): correctly serve ngsw/state with a non-root SW …
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
gkalpak authored and atscott committed Jul 9, 2020
1 parent bc00e8d commit dc42c97
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/service-worker/worker/src/driver.ts
Expand Up @@ -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).
Expand Down Expand Up @@ -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;
Expand Down
28 changes: 28 additions & 0 deletions packages/service-worker/worker/test/happy_spec.ts
Expand Up @@ -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) =>
Expand Down

0 comments on commit dc42c97

Please sign in to comment.