Skip to content

Commit

Permalink
Better handling of NetworkLoad lifecycle inside willPerformHTTPRedire…
Browse files Browse the repository at this point in the history
…ction

https://bugs.webkit.org/show_bug.cgi?id=259830
rdar://113149435

Reviewed by Chris Dumez.

NetworkLoad::didCompleteWithError has lifecycle side effects, so account for that.

This lifecycle change was introduced in a refactor: https://commits.webkit.org/266246@main

* LayoutTests/http/tests/security/resources/network-load-sw.js: Added.
* LayoutTests/http/tests/security/resources/network-load-swasdf.py: Added.
* LayoutTests/http/tests/security/resources/network-load.js: Added.
* LayoutTests/http/tests/security/service-worker-network-load-expected.txt: Added.
* LayoutTests/http/tests/security/service-worker-network-load.html: Added.

* Source/WebKit/NetworkProcess/NetworkLoad.cpp:
(WebKit::NetworkLoad::willPerformHTTPRedirection):

Canonical link: https://commits.webkit.org/266608@main
  • Loading branch information
beidson committed Aug 5, 2023
1 parent 17723aa commit 014d6ff
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 0 deletions.
33 changes: 33 additions & 0 deletions LayoutTests/http/tests/security/resources/network-load-sw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
async function wait_for_performance_entries(url) {
let entries = performance.getEntriesByName(url);
if (entries.length > 0) {
return entries;
}
return new Promise((resolve) => {
new PerformanceObserver((list) => {
const entries = list.getEntriesByName(url);
if (entries.length > 0) {
resolve(entries);
}
}).observe({ entryTypes: ['resource'] });
});
}

self.addEventListener('activate', event => {
event.waitUntil(self.registration.navigationPreload.enable());
});

self.theHTML = "<script>window.top.postMessage('')</script>";

self.addEventListener('fetch', event => {
let headers;
event.respondWith(
event.preloadResponse
.then(response => {
headers = response.headers;
return response.text()
})
.then(_ => wait_for_performance_entries(event.request.url))
.then(entries =>
new Response( self.theHTML, { headers: {'Content-Type': 'text/html' }})));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python3

import os
import sys

sys.stdout.write(
'Status: 302\r\n'
'Location: network-load-swasdf\r\n\r\n'
)
52 changes: 52 additions & 0 deletions LayoutTests/http/tests/security/resources/network-load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
(function (global_scope)
{
function promise_test(func, name, properties) {
var test = new Test(name, properties);
tests.promise_tests = Promise.resolve();
tests.promise_tests = tests.promise_tests.then(function() {
return new Promise(function(resolve) {
var promise = test.step(func, test, test);
Promise.resolve(promise)
});
});
}

expose(promise_test, 'trigger');

function Test(name, properties)
{
this.name = name;
tests.push(this);
}


Test.prototype.step = function(func, this_obj)
{
return func.apply(this_obj, Array.prototype.slice.call(arguments, 2));
};

Test.prototype.step_func = function(func, this_obj)
{
var test_this = this;

return function()
{
return test_this.step.apply(test_this, [func, this_obj].concat(
Array.prototype.slice.call(arguments)));
};
};

function Tests() {}
Tests.prototype.push = function(test) {}

function expose(object, name)
{
var components = name.split(".");
var target = global_scope;
for (var i = 0; i < components.length - 1; i++) {
target = target[components[i]];
}
target[components[components.length - 1]] = object;
}
var tests = new Tests();
})(self);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

79 changes: 79 additions & 0 deletions LayoutTests/http/tests/security/service-worker-network-load.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<html>
<head>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
</script>
<script src="resources/network-load.js"></script>
<script>

var count = 0;
var iframesToCreate = 8;
window.onmessage = function(e) {
if (++count == iframesToCreate) {
if (window.testRunner)
testRunner.notifyDone();
else
alert("Done!");
}
};


function with_iframe(url) {
return new Promise(function(resolve) {
var frame = document.createElement('iframe');
frame.src = url;
document.body.appendChild(frame);
});
}

function service_register(url, scope) {
var options = { scope: scope };
return service_unregister(scope)
.then(function() {
return navigator.serviceWorker.register(url, options);
})
}

function service_unregister(scope) {
var absoluteScope = (new URL(scope, window.location).href);
return navigator.serviceWorker.getRegistration(scope)
.then(function(registration) {
if (registration && registration.scope === absoluteScope)
return registration.unregister();
})
}

function wating_stat(test, worker, state) {
return new Promise(test.step_func(function(resolve) {
worker.addEventListener('statechange', test.step_func(function() {
resolve(state);
}));
}));
}

trigger(t => {
var script = 'resources/network-load-sw.js';
var scope = 'resources/network-load-sw';

return service_register(script, scope)
.then(reg => {
return wating_stat(t, reg.installing, 'activated');
})
.then(frame => {
setTimeout(() => with_iframe(scope + 'asdf.py') , 1);
setTimeout(() => with_iframe(scope + 'asdf.py') , 0.9);
setTimeout(() => with_iframe(scope + 'asdf.py') , 1.0);
setTimeout(() => with_iframe(scope + 'asdf.py') , 1.0);
setTimeout(() => with_iframe(scope + 'asdf.py') , 1.1);
setTimeout(() => with_iframe(scope + 'asdf.py') , 1.2);
setTimeout(() => with_iframe(scope + 'asdf.py') , 1.3);

return with_iframe(scope + 'asdf.py');
})
}, 'asdfasdf')

</script>

1 change: 1 addition & 0 deletions LayoutTests/platform/mac-wk1/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,7 @@ imported/w3c/web-platform-tests/IndexedDB/reading-autoincrement-indexes.any.serv
imported/w3c/web-platform-tests/IndexedDB/reading-autoincrement-store-cursors.any.serviceworker.html [ Skip ]
imported/w3c/web-platform-tests/IndexedDB/reading-autoincrement-store.any.serviceworker.html [ Skip ]
imported/w3c/web-platform-tests/IndexedDB/storage-buckets.https.any.serviceworker.html [ Skip ]
http/tests/security/service-worker-network-load.html [ Skip ]

# No Cross-Origin-Opener-Policy / Cross-Origin-Embedder-Policy in WK1.
imported/w3c/web-platform-tests/html/anonymous-iframe [ Skip ]
Expand Down
2 changes: 2 additions & 0 deletions Source/WebKit/NetworkProcess/NetworkLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ void NetworkLoad::willPerformHTTPRedirection(ResourceResponse&& redirectResponse
if (m_currentRequest.isNull()) {
NetworkLoadMetrics emptyMetrics;
didCompleteWithError(cancelledError(m_currentRequest), emptyMetrics);
completionHandler({ });
return;
}
completionHandler(ResourceRequest(m_currentRequest));
});
Expand Down

0 comments on commit 014d6ff

Please sign in to comment.