Skip to content

Commit

Permalink
Set top-level module script request for SWs to same-origin mode
Browse files Browse the repository at this point in the history
Top-level module script request for service workers should be set to
same-origin mode. Link to the spec discussion issue can be found at
whatwg/html#6544.

Bug: 1194571
Change-Id: I8247669d23ef84fa879f743b699c6e11ac49bb50
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2797663
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Commit-Queue: Ghazale Hosseinabadi <ghazale@chromium.org>
Cr-Commit-Position: refs/heads/master@{#869300}
  • Loading branch information
Ghazale Hosseinabadi authored and Chromium LUCI CQ committed Apr 5, 2021
1 parent cc290ae commit 4a72343
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 4 deletions.
12 changes: 9 additions & 3 deletions content/browser/service_worker/service_worker_loader_helpers.cc
Expand Up @@ -204,12 +204,18 @@ network::ResourceRequest CreateRequestForServiceWorkerScript(
// Set the "Service-Worker" header for the service worker script request:
// https://w3c.github.io/ServiceWorker/#service-worker-script-request
request.headers.SetHeader("Service-Worker", "script");

// The "Fetch a module worker script graph" uses "same-origin" as mode for
// main script and "cors" otherwise.
// https://w3c.github.io/ServiceWorker/#update-algorithm
request.mode = network::mojom::RequestMode::kSameOrigin;
} else {
request.mode = network::mojom::RequestMode::kCors;
}

// The "Fetch a module worker script graph" uses "cors" as mode and "omit"
// as credentials mode.
// The "Fetch a module worker script graph" uses "omit" as credentials
// mode.
// https://w3c.github.io/ServiceWorker/#update-algorithm
request.mode = network::mojom::RequestMode::kCors;
request.credentials_mode = network::mojom::CredentialsMode::kOmit;

// The request's destination is "serviceworker" for the main and
Expand Down
Expand Up @@ -1004,7 +1004,7 @@ TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, ScriptType_Module_Main) {
std::string header;
EXPECT_TRUE(request->headers.GetHeader("Service-Worker", &header));
EXPECT_EQ("script", header);
EXPECT_EQ(request->mode, network::mojom::RequestMode::kCors);
EXPECT_EQ(request->mode, network::mojom::RequestMode::kSameOrigin);
EXPECT_EQ(request->credentials_mode, network::mojom::CredentialsMode::kOmit);
EXPECT_EQ(request->destination,
network::mojom::RequestDestination::kServiceWorker);
Expand Down
@@ -0,0 +1,10 @@
// Add a unique UUID per request to induce service worker script update.
// Time stamp: %UUID%

// The server injects the request headers here as a JSON string.
const headersAsJson = `%HEADERS%`;
const headers = JSON.parse(headersAsJson);

self.addEventListener('message', async (e) => {
e.source.postMessage(headers);
});
@@ -0,0 +1,22 @@
import json
import os
import uuid
import sys

from wptserve.utils import isomorphic_decode

def main(request, response):
path = os.path.join(os.path.dirname(isomorphic_decode(__file__)),
u"test-request-mode-worker.js")
body = open(path, u"rb").read()

data = {isomorphic_decode(key):isomorphic_decode(request.headers[key]) for key, value in request.headers.items()}

body = body.replace(b"%HEADERS%", json.dumps(data).encode("utf-8"))
body = body.replace(b"%UUID%", str(uuid.uuid4()).encode("utf-8"))

headers = []
headers.append((b"ETag", b"etag"))
headers.append((b"Content-Type", b'text/javascript'))

return headers, body
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test that mode is set to same-origin for a main module</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
// Tests a main module service worker script fetch during an update check.
// The fetch should have the mode set to 'same-origin'.
//
// The test works by registering a main module service worker. It then does an
// update. The test server responds with an updated worker script that remembers
// the http request. The updated worker reports back this request to the test
// page.
promise_test(async (t) => {
const script = "resources/test-request-mode-worker.py";
const scope = "resources/";

// Register the service worker.
await service_worker_unregister(t, scope);
const registration = await navigator.serviceWorker.register(
script, {scope, type: 'module'});
await wait_for_state(t, registration.installing, 'activated');

// Do an update.
await registration.update();

// Ask the new worker what the request was.
const newWorker = registration.installing;
const sawMessage = new Promise((resolve) => {
navigator.serviceWorker.onmessage = (event) => {
resolve(event.data);
};
});
newWorker.postMessage('getHeaders');
const result = await sawMessage;

// Test the result.
assert_equals(result['sec-fetch-mode'], 'same-origin');
assert_equals(result['origin'], undefined);

}, 'headers of a main module script');

</script>

0 comments on commit 4a72343

Please sign in to comment.