Diff
Modified: trunk/LayoutTests/ChangeLog (252396 => 252397)
--- trunk/LayoutTests/ChangeLog 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/LayoutTests/ChangeLog 2019-11-13 10:22:04 UTC (rev 252397)
@@ -1,3 +1,15 @@
+2019-11-13 Rob Buis <[email protected]>
+
+ Support stale-while-revalidate cache strategy
+ https://bugs.webkit.org/show_bug.cgi?id=201461
+
+ Reviewed by Youenn Fablet.
+
+ Skip newly imported tests for WK1.
+
+ * platform/ios-wk1/TestExpectations:
+ * platform/mac-wk1/TestExpectations:
+
2019-11-12 Fujii Hironori <[email protected]>
Unreviewed test gardening for WinCairo
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (252396 => 252397)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2019-11-13 10:22:04 UTC (rev 252397)
@@ -1,3 +1,35 @@
+2019-11-13 Rob Buis <[email protected]>
+
+ Support stale-while-revalidate cache strategy
+ https://bugs.webkit.org/show_bug.cgi?id=201461
+
+ Reviewed by Youenn Fablet.
+
+ Import stale-while-revalidate WPT tests.
+
+ * resources/import-expectations.json:
+ * web-platform-tests/fetch/stale-while-revalidate/fetch-expected.txt: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https-expected.txt: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/fetch.html: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py: Added.
+ (main):
+ * web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py: Added.
+ (main):
+ * web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py: Added.
+ (id_token):
+ (main):
+ * web-platform-tests/fetch/stale-while-revalidate/resources/w3c-import.log: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/stale-css-expected.txt: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/stale-css.html: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/stale-image-expected.txt: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/stale-image.html: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/stale-script-expected.txt: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/stale-script.html: Added.
+ * web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js: Added.
+ (async.broadcast):
+ * web-platform-tests/fetch/stale-while-revalidate/w3c-import.log: Added.
+
2019-11-12 Carlos Alberto Lopez Perez <[email protected]>
[GTK][WPE] Support Pointer Events
Modified: trunk/LayoutTests/imported/w3c/resources/import-expectations.json (252396 => 252397)
--- trunk/LayoutTests/imported/w3c/resources/import-expectations.json 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/LayoutTests/imported/w3c/resources/import-expectations.json 2019-11-13 10:22:04 UTC (rev 252397)
@@ -176,6 +176,7 @@
"web-platform-tests/fetch/api": "import",
"web-platform-tests/fetch/api/cors": "import",
"web-platform-tests/fetch/range": "import",
+ "web-platform-tests/fetch/stale-while-revalidate": "import",
"web-platform-tests/fullscreen": "skip",
"web-platform-tests/gamepad": "skip",
"web-platform-tests/generic-sensor": "skip",
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-expected.txt (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-expected.txt 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,3 @@
+
+PASS Second fetch returns same response
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https-expected.txt (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https-expected.txt 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,3 @@
+
+PASS Second fetch returns same response
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Stale Revalidation Requests don't get sent to service worker</title>
+ <script src=""
+ <script src=""
+ <script src=""
+ <script src=""
+</head>
+<body>
+<script>
+
+ // Duplicating this resource to make service worker scoping simpler.
+ async function setupRegistrationAndWaitToBeControlled(t, scope) {
+ const controlled = new Promise((resolve) => {
+ navigator.serviceWorker._oncontrollerchange_ = () => { resolve(); };
+ });
+ const reg = await navigator.serviceWorker.register('sw-intercept.js');
+ await wait_for_state(t, reg.installing, 'activated');
+ await controlled;
+ add_completion_callback(_ => reg.unregister());
+ return reg;
+ }
+
+ // Using 250ms polling interval to provide enough 'network calmness' to give
+ // the background low priority revalidation request a chance to kick in.
+ function wait250ms(test) {
+ return new Promise(resolve => {
+ test.step_timeout(() => {
+ resolve();
+ }, 250);
+ });
+ }
+
+ promise_test(async (test) => {
+ var request_token = token();
+ const uri = 'resources/stale-script.py?token=' + request_token;
+
+ await setupRegistrationAndWaitToBeControlled(test, 'resources/stale-script.py');
+
+ var service_worker_count = 0;
+ navigator.serviceWorker.addEventListener('message', function once(event) {
+ if (event.data.endsWith(uri)) {
+ service_worker_count++;
+ }
+ });
+
+ const response = await fetch(uri);
+ const response2 = await fetch(uri);
+ assert_equals(response.headers.get('Unique-Id'), response2.headers.get('Unique-Id'));
+ while(true) {
+ const revalidation_check = await fetch(`resources/stale-script.py?query&token=` + request_token);
+ if (revalidation_check.headers.get('Count') == '2') {
+ // The service worker should not see the revalidation request.
+ assert_equals(service_worker_count, 2);
+ break;
+ }
+ await wait250ms(test);
+ }
+ }, 'Second fetch returns same response');
+
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Tests Stale While Revalidate is not executed for fetch API</title>
+<script src=""
+<script src=""
+<script src=""
+<script>
+function wait25ms(test) {
+ return new Promise(resolve => {
+ test.step_timeout(() => {
+ resolve();
+ }, 25);
+ });
+}
+
+promise_test(async (test) => {
+ var request_token = token();
+
+ const response = await fetch(`resources/stale-script.py?token=` + request_token);
+ const response2 = await fetch(`resources/stale-script.py?token=` + request_token);
+
+ assert_equals(response.headers.get('Unique-Id'), response2.headers.get('Unique-Id'));
+
+ while(true) {
+ const revalidation_check = await fetch(`resources/stale-script.py?query&token=` + request_token);
+ if (revalidation_check.headers.get('Count') == '2') {
+ break;
+ }
+ await wait25ms(test);
+ }
+}, 'Second fetch returns same response');
+</script>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,28 @@
+def main(request, response):
+
+ token = request.GET.first("token", None)
+ is_query = request.GET.first("query", None) != None
+ with request.server.stash.lock:
+ value = request.server.stash.take(token)
+ count = 0
+ if value != None:
+ count = int(value)
+ if is_query:
+ if count < 2:
+ request.server.stash.put(token, count)
+ else:
+ count = count + 1
+ request.server.stash.put(token, count)
+ if is_query:
+ headers = [("Count", count)]
+ content = ""
+ return 200, headers, content
+ else:
+ content = "body { background: rgb(0, 128, 0); }"
+ if count > 1:
+ content = "body { background: rgb(255, 0, 0); }"
+
+ headers = [("Content-Type", "text/css"),
+ ("Cache-Control", "private, max-age=0, stale-while-revalidate=60")]
+
+ return 200, headers, content
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,38 @@
+import os.path
+
+def main(request, response):
+
+ token = request.GET.first("token", None)
+ is_query = request.GET.first("query", None) != None
+ with request.server.stash.lock:
+ value = request.server.stash.take(token)
+ count = 0
+ if value != None:
+ count = int(value)
+ if is_query:
+ if count < 2:
+ request.server.stash.put(token, count)
+ else:
+ count = count + 1
+ request.server.stash.put(token, count)
+
+ if is_query:
+ headers = [("Count", count)]
+ content = ""
+ return 200, headers, content
+ else:
+ filename = "green-16x16.png"
+ if count > 1:
+ filename = "green-256x256.png"
+
+ path = os.path.join(os.path.dirname(__file__), "../../../images", filename)
+ body = open(path, "rb").read()
+
+ response.add_required_headers = False
+ response.writer.write_status(200)
+ response.writer.write_header("content-length", len(body))
+ response.writer.write_header("Cache-Control", "private, max-age=0, stale-while-revalidate=60")
+ response.writer.write_header("content-type", "image/png")
+ response.writer.end_headers()
+
+ response.writer.write(body)
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,32 @@
+import random, string, datetime
+
+def id_token():
+ letters = string.ascii_lowercase
+ return ''.join(random.choice(letters) for i in range(20))
+
+def main(request, response):
+ token = request.GET.first("token", None)
+ is_query = request.GET.first("query", None) != None
+ with request.server.stash.lock:
+ value = request.server.stash.take(token)
+ count = 0
+ if value != None:
+ count = int(value)
+ if is_query:
+ if count < 2:
+ request.server.stash.put(token, count)
+ else:
+ count = count + 1
+ request.server.stash.put(token, count)
+
+ if is_query:
+ headers = [("Count", count)]
+ content = ""
+ return 200, headers, content
+ else:
+ unique_id = id_token()
+ headers = [("Content-Type", "text/_javascript_"),
+ ("Cache-Control", "private, max-age=0, stale-while-revalidate=60"),
+ ("Unique-Id", unique_id)]
+ content = "report('{}')".format(unique_id)
+ return 200, headers, content
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/w3c-import.log (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/w3c-import.log (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/w3c-import.log 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,19 @@
+The tests in this directory were imported from the W3C repository.
+Do NOT modify these tests directly in WebKit.
+Instead, create a pull request on the WPT github:
+ https://github.com/web-platform-tests/wpt
+
+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
+
+Do NOT modify or remove this file.
+
+------------------------------------------------------------------------
+Properties requiring vendor prefixes:
+None
+Property values requiring vendor prefixes:
+None
+------------------------------------------------------------------------
+List of files:
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-css.py
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-image.py
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/resources/stale-script.py
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css-expected.txt (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css-expected.txt 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,3 @@
+
+PASS Cache returns stale resource
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Tests Stale While Revalidate works for css</title>
+<script src=""
+<script src=""
+<script src=""
+<body>
+<script>
+
+var request_token = token();
+async_test(t => {
+ window._onload_ = t.step_func(() => {
+ t.step_timeout(() => {
+ assert_equals(window.getComputedStyle(document.body).getPropertyValue('background-color'), "rgb(0, 128, 0)");
+ var link2 = document.createElement("link");
+ link2._onload_ = t.step_func(() => {
+ assert_equals(window.getComputedStyle(document.body).getPropertyValue('background-color'), "rgb(0, 128, 0)");
+ var checkResult = () => {
+ // We poll because we don't know when the revalidation will occur.
+ fetch("resources/stale-css.py?query&token=" + request_token).then(t.step_func((response) => {
+ var count = response.headers.get("Count");
+ if (count == '2') {
+ t.done();
+ } else {
+ t.step_timeout(checkResult, 25);
+ }
+ }));
+ };
+ t.step_timeout(checkResult, 25);
+ });
+ link2.rel = "stylesheet";
+ link2.type = "text/css";
+ link2.href = "" + request_token;
+ document.body.appendChild(link2);
+ }, 0);
+ });
+}, 'Cache returns stale resource');
+
+var link = document.createElement("link");
+link.rel = "stylesheet";
+link.type = "text/css";
+link.href = "" + request_token;
+document.body.appendChild(link);
+</script>
+</body>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image-expected.txt (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image-expected.txt 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,4 @@
+
+
+PASS Cache returns stale resource
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Tests Stale While Revalidate works for images</title>
+<script src=""
+<script src=""
+<script src=""
+<body>
+<!--
+Use a child document to load the second stale image into because
+an image loaded into the same document will skip cache-control headers.
+See: https://html.spec.whatwg.org/#the-list-of-available-images
+-->
+<iframe id="child" srcdoc=""></iframe>
+<script>
+var request_token = token();
+async_test(t => {
+ window._onload_ = t.step_func(() => {
+ t.step_timeout(() => {
+ assert_equals(document.getElementById("firstimage").width, 16, "Width is 16");
+ var childDocument = document.getElementById('child').contentDocument;
+ var img2 = childDocument.createElement("img");
+ img2._onload_ = t.step_func(() => {
+ assert_equals(img2.width, 16, "image dimension");
+ var checkResult = () => {
+ // We poll because we don't know when the revalidation will occur.
+ fetch("resources/stale-image.py?query&token=" + request_token).then(t.step_func((response) => {
+ var count = response.headers.get("Count");
+ if (count == '2') {
+ t.done();
+ } else {
+ t.step_timeout(checkResult, 25);
+ }
+ }));
+ };
+ t.step_timeout(checkResult, 25);
+ });
+ img2.src = "" + request_token;
+ childDocument.body.appendChild(img2);
+ }, 0);
+ });
+}, 'Cache returns stale resource');
+
+var img = document.createElement("img");
+img.src = "" + request_token;
+img.id = "firstimage";
+document.body.appendChild(img);
+</script>
+</body>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script-expected.txt (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script-expected.txt 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,3 @@
+
+PASS Cache returns stale resource
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Tests Stale While Revalidate works for scripts</title>
+<script src=""
+<script src=""
+<script src=""
+<body>
+<script>
+var last_modified;
+var last_modified_count = 0;
+var request_token = token();
+
+// The script will call report via a uniquely generated ID on the subresource.
+// If it is a cache hit the ID will be the same and the test will pass.
+function report(mod) {
+ if (!last_modified) {
+ last_modified = mod;
+ last_modified_count = 1;
+ } else if (last_modified == mod) {
+ last_modified_count++;
+ }
+}
+
+async_test(t => {
+ window._onload_ = t.step_func(() => {
+ step_timeout(() => {
+ var script = document.createElement("script");
+ script.src = "" + request_token;
+ document.body.appendChild(script);
+ script._onload_ = t.step_func(() => {
+ assert_equals(last_modified_count, 2, "last modified");
+ var checkResult = () => {
+ // We poll because we don't know when the revalidation will occur.
+ fetch("resources/stale-script.py?query&token=" + request_token).then(t.step_func((response) => {
+ var count = response.headers.get("Count");
+ if (count == '2') {
+ t.done();
+ } else {
+ t.step_timeout(checkResult, 25);
+ }
+ }));
+ };
+ t.step_timeout(checkResult, 25);
+ });
+ }, 0);
+ });
+}, 'Cache returns stale resource');
+
+var script = document.createElement("script");
+script.src = "" + request_token;
+document.body.appendChild(script);
+</script>
+</body>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,14 @@
+async function broadcast(msg) {
+ for (const client of await clients.matchAll()) {
+ client.postMessage(msg);
+ }
+}
+
+self.addEventListener('fetch', event => {
+ event.waitUntil(broadcast(event.request.url));
+ event.respondWith(fetch(event.request));
+});
+
+self.addEventListener('activate', event => {
+ self.clients.claim();
+});
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/w3c-import.log (0 => 252397)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/w3c-import.log (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/w3c-import.log 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,22 @@
+The tests in this directory were imported from the W3C repository.
+Do NOT modify these tests directly in WebKit.
+Instead, create a pull request on the WPT github:
+ https://github.com/web-platform-tests/wpt
+
+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
+
+Do NOT modify or remove this file.
+
+------------------------------------------------------------------------
+Properties requiring vendor prefixes:
+None
+Property values requiring vendor prefixes:
+None
+------------------------------------------------------------------------
+List of files:
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html
+/LayoutTests/imported/w3c/web-platform-tests/fetch/stale-while-revalidate/sw-intercept.js
Modified: trunk/LayoutTests/platform/ios-wk1/TestExpectations (252396 => 252397)
--- trunk/LayoutTests/platform/ios-wk1/TestExpectations 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/LayoutTests/platform/ios-wk1/TestExpectations 2019-11-13 10:22:04 UTC (rev 252397)
@@ -2005,4 +2005,7 @@
webkit.org/b/159724 [ Debug ] imported/w3c/web-platform-tests/xhr/send-redirect-post-upload.htm [ Skip ]
# Skip IsLoggedIn
-http/tests/is-logged-in/ [ Skip ]
\ No newline at end of file
+http/tests/is-logged-in/ [ Skip ]
+
+# Stale-while-revalidate is not supported on WK1
+imported/w3c/web-platform-tests/fetch/stale-while-revalidate [ Skip ]
Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (252396 => 252397)
--- trunk/LayoutTests/platform/mac-wk1/TestExpectations 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations 2019-11-13 10:22:04 UTC (rev 252397)
@@ -822,3 +822,6 @@
webkit.org/b/203501 imported/w3c/web-platform-tests/css/css-animations/animation-transform-pause-and-set-time.html [ ImageOnlyFailure ]
webkit.org/b/203517 imported/w3c/web-platform-tests/css/css-sizing/dynamic-available-size-iframe.html [ Pass ImageOnlyFailure ]
+
+# Stale-while-revalidate is not supported on WK1
+imported/w3c/web-platform-tests/fetch/stale-while-revalidate [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (252396 => 252397)
--- trunk/Source/WebCore/ChangeLog 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebCore/ChangeLog 2019-11-13 10:22:04 UTC (rev 252397)
@@ -1,3 +1,26 @@
+2019-11-13 Rob Buis <[email protected]>
+
+ Support stale-while-revalidate cache strategy
+ https://bugs.webkit.org/show_bug.cgi?id=201461
+
+ Reviewed by Youenn Fablet.
+
+ Start parsing the stale-while-revalidate Cache-Control directive
+ and expose it on ResourceResponse.
+
+ Tests: imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch-sw.https.html
+ imported/w3c/web-platform-tests/fetch/stale-while-revalidate/fetch.html
+ imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-css.html
+ imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-image.html
+ imported/w3c/web-platform-tests/fetch/stale-while-revalidate/stale-script.html
+
+ * platform/network/CacheValidation.cpp:
+ (WebCore::parseCacheControlDirectives):
+ * platform/network/CacheValidation.h:
+ * platform/network/ResourceResponseBase.cpp:
+ (WebCore::ResourceResponseBase::cacheControlStaleWhileRevalidate const):
+ * platform/network/ResourceResponseBase.h:
+
2019-11-12 Simon Fraser <[email protected]>
Move CSSUnitType enum to its own file
Modified: trunk/Source/WebCore/platform/network/CacheValidation.cpp (252396 => 252397)
--- trunk/Source/WebCore/platform/network/CacheValidation.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebCore/platform/network/CacheValidation.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -313,8 +313,18 @@
double maxStale = directives[i].second.toDouble(&ok);
if (ok)
result.maxStale = Seconds { maxStale };
- } else if (equalLettersIgnoringASCIICase(directives[i].first, "immutable"))
+ } else if (equalLettersIgnoringASCIICase(directives[i].first, "immutable")) {
result.immutable = true;
+ } else if (equalLettersIgnoringASCIICase(directives[i].first, "stale-while-revalidate")) {
+ if (result.staleWhileRevalidate) {
+ // First stale-while-revalidate directive wins if there are multiple ones.
+ continue;
+ }
+ bool ok;
+ double staleWhileRevalidate = directives[i].second.toDouble(&ok);
+ if (ok)
+ result.staleWhileRevalidate = Seconds { staleWhileRevalidate };
+ }
}
}
Modified: trunk/Source/WebCore/platform/network/CacheValidation.h (252396 => 252397)
--- trunk/Source/WebCore/platform/network/CacheValidation.h 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebCore/platform/network/CacheValidation.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -69,6 +69,7 @@
Markable<Seconds, Seconds::MarkableTraits> maxAge;
Markable<Seconds, Seconds::MarkableTraits> maxStale;
+ Markable<Seconds, Seconds::MarkableTraits> staleWhileRevalidate;
bool noCache : 1;
bool noStore : 1;
bool mustRevalidate : 1;
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp (252396 => 252397)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -657,6 +657,13 @@
return m_cacheControlDirectives.maxAge;
}
+Optional<Seconds> ResourceResponseBase::cacheControlStaleWhileRevalidate() const
+{
+ if (!m_haveParsedCacheControlHeader)
+ parseCacheControlDirectives();
+ return m_cacheControlDirectives.staleWhileRevalidate;
+}
+
static Optional<WallTime> parseDateValueInHeader(const HTTPHeaderMap& headers, HTTPHeaderName headerName)
{
String headerValue = headers.get(headerName);
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (252396 => 252397)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -137,6 +137,7 @@
WEBCORE_EXPORT bool cacheControlContainsImmutable() const;
WEBCORE_EXPORT bool hasCacheValidatorFields() const;
WEBCORE_EXPORT Optional<Seconds> cacheControlMaxAge() const;
+ WEBCORE_EXPORT Optional<Seconds> cacheControlStaleWhileRevalidate() const;
WEBCORE_EXPORT Optional<WallTime> date() const;
WEBCORE_EXPORT Optional<Seconds> age() const;
WEBCORE_EXPORT Optional<WallTime> expires() const;
Modified: trunk/Source/WebKit/ChangeLog (252396 => 252397)
--- trunk/Source/WebKit/ChangeLog 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/ChangeLog 2019-11-13 10:22:04 UTC (rev 252397)
@@ -1,3 +1,63 @@
+2019-11-13 Rob Buis <[email protected]>
+
+ Support stale-while-revalidate cache strategy
+ https://bugs.webkit.org/show_bug.cgi?id=201461
+
+ Reviewed by Youenn Fablet.
+
+ Add a new UseDecision value AsyncRevalidate for async revalidation. This is used
+ when the retrieved cache entry is a stale-while-revalidate response [1].
+ In case of AsyncRevalidate, a check is made to see if there is a
+ current async revalidation ongoing for the entry, if not one is
+ started. Regardless, the stale entry is returned, until either the
+ async revalidation ends successfully or at the moment when the
+ response expires for real.
+
+ [1] https://fetch.spec.whatwg.org/#concept-stale-while-revalidate-response
+
+ * NetworkProcess/NetworkSession.cpp:
+ (WebKit::NetworkSession::NetworkSession):
+ * NetworkProcess/NetworkSession.h:
+ (WebKit::NetworkSession::isStaleWhileRevalidateEnabled const):
+ * NetworkProcess/NetworkSessionCreationParameters.cpp:
+ (WebKit::NetworkSessionCreationParameters::encode const):
+ (WebKit::NetworkSessionCreationParameters::decode):
+ * NetworkProcess/NetworkSessionCreationParameters.h:
+ * NetworkProcess/cache/AsyncRevalidation.cpp: Added.
+ (WebKit::NetworkCache::constructRevalidationRequest):
+ (WebKit::NetworkCache::AsyncRevalidation::staleWhileRevalidateEnding):
+ (WebKit::NetworkCache::AsyncRevalidation::AsyncRevalidation):
+ * NetworkProcess/cache/AsyncRevalidation.h: Added.
+ (WebKit::NetworkCache::AsyncRevalidation::load const):
+ * NetworkProcess/cache/NetworkCache.cpp:
+ (WebKit::NetworkCache::responseNeedsRevalidation):
+ (WebKit::NetworkCache::makeUseDecision):
+ (WebKit::NetworkCache::makeStoreDecision):
+ (WebKit::NetworkCache::Cache::startAsyncRevalidationIfNeeded):
+ (WebKit::NetworkCache::Cache::retrieve):
+ (WebKit::NetworkCache::responseHasExpired): Deleted.
+ * NetworkProcess/cache/NetworkCache.h:
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
+ (WebKit::NetworkCache::dumpHTTPHeadersDiff):
+ (WebKit::NetworkCache::requestsHeadersMatch):
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
+ (WebKit::NetworkCache::dumpHTTPHeadersDiff): Deleted.
+ (WebKit::NetworkCache::requestsHeadersMatch): Deleted.
+ * Sources.txt:
+ * UIProcess/API/C/WKWebsiteDataStoreConfigurationRef.cpp:
+ (WKWebsiteDataStoreConfigurationGetStaleWhileRevalidateEnabled):
+ (WKWebsiteDataStoreConfigurationSetStaleWhileRevalidateEnabled):
+ * UIProcess/API/C/WKWebsiteDataStoreConfigurationRef.h:
+ * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+ (WebKit::WebsiteDataStore::parameters):
+ * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
+ (WebKit::WebsiteDataStoreConfiguration::copy const):
+ * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
+ (WebKit::WebsiteDataStoreConfiguration::staleWhileRevalidateEnabled const):
+ (WebKit::WebsiteDataStoreConfiguration::setStaleWhileRevalidateEnabled):
+ * WebKit.xcodeproj/project.pbxproj:
+
2019-11-12 Simon Fraser <[email protected]>
Convert CSSPrimitiveValue::UnitType to an enum class, and cleanup
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -108,6 +108,8 @@
SandboxExtension::consumePermanently(parameters.resourceLoadStatisticsDirectoryExtensionHandle);
}
+ m_isStaleWhileRevalidateEnabled = parameters.staleWhileRevalidateEnabled;
+
m_adClickAttribution->setPingLoadFunction([this, weakThis = makeWeakPtr(this)](NetworkResourceLoadParameters&& loadParameters, CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&& completionHandler) {
if (!weakThis)
return;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -124,6 +124,8 @@
unsigned testSpeedMultiplier() const { return m_testSpeedMultiplier; }
+ bool isStaleWhileRevalidateEnabled() const { return m_isStaleWhileRevalidateEnabled; }
+
protected:
NetworkSession(NetworkProcess&, const NetworkSessionCreationParameters&);
@@ -144,6 +146,7 @@
bool m_downgradeReferrer { true };
bool m_thirdPartyCookieBlockingEnabled { false };
#endif
+ bool m_isStaleWhileRevalidateEnabled { false };
UniqueRef<AdClickAttributionManager> m_adClickAttribution;
HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -78,6 +78,7 @@
encoder << fastServerTrustEvaluationEnabled;
encoder << networkCacheSpeculativeValidationEnabled;
encoder << shouldUseTestingNetworkSession;
+ encoder << staleWhileRevalidateEnabled;
encoder << testSpeedMultiplier;
encoder << suppressesConnectionTerminationOnSystemChange;
}
@@ -243,7 +244,12 @@
decoder >> shouldUseTestingNetworkSession;
if (!shouldUseTestingNetworkSession)
return WTF::nullopt;
-
+
+ Optional<bool> staleWhileRevalidateEnabled;
+ decoder >> staleWhileRevalidateEnabled;
+ if (!staleWhileRevalidateEnabled)
+ return WTF::nullopt;
+
Optional<unsigned> testSpeedMultiplier;
decoder >> testSpeedMultiplier;
if (!testSpeedMultiplier)
@@ -292,6 +298,7 @@
, WTFMove(*fastServerTrustEvaluationEnabled)
, WTFMove(*networkCacheSpeculativeValidationEnabled)
, WTFMove(*shouldUseTestingNetworkSession)
+ , WTFMove(*staleWhileRevalidateEnabled)
, WTFMove(*testSpeedMultiplier)
, WTFMove(*suppressesConnectionTerminationOnSystemChange)
}};
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -96,6 +96,7 @@
bool fastServerTrustEvaluationEnabled { false };
bool networkCacheSpeculativeValidationEnabled { false };
bool shouldUseTestingNetworkSession { false };
+ bool staleWhileRevalidateEnabled { false };
unsigned testSpeedMultiplier { 1 };
bool suppressesConnectionTerminationOnSystemChange { false };
};
Added: trunk/Source/WebKit/NetworkProcess/cache/AsyncRevalidation.cpp (0 => 252397)
--- trunk/Source/WebKit/NetworkProcess/cache/AsyncRevalidation.cpp (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/cache/AsyncRevalidation.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AsyncRevalidation.h"
+
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+#include <WebCore/CacheValidation.h>
+#include <WebCore/ResourceRequest.h>
+
+namespace WebKit {
+namespace NetworkCache {
+
+static inline WebCore::ResourceRequest constructRevalidationRequest(const Key& key, const WebCore::ResourceRequest& request, const Entry& entry)
+{
+ WebCore::ResourceRequest revalidationRequest = request;
+ if (!key.partition().isEmpty())
+ revalidationRequest.setCachePartition(key.partition());
+ ASSERT_WITH_MESSAGE(key.range().isEmpty(), "range is not supported");
+
+ revalidationRequest.makeUnconditional();
+ auto eTag = entry.response().httpHeaderField(WebCore::HTTPHeaderName::ETag);
+ if (!eTag.isEmpty())
+ revalidationRequest.setHTTPHeaderField(WebCore::HTTPHeaderName::IfNoneMatch, eTag);
+
+ auto lastModified = entry.response().httpHeaderField(WebCore::HTTPHeaderName::LastModified);
+ if (!lastModified.isEmpty())
+ revalidationRequest.setHTTPHeaderField(WebCore::HTTPHeaderName::IfModifiedSince, lastModified);
+
+ revalidationRequest.setPriority(WebCore::ResourceLoadPriority::Low);
+
+ return revalidationRequest;
+}
+
+void AsyncRevalidation::staleWhileRevalidateEnding()
+{
+ if (m_completionHandler)
+ m_completionHandler(Result::Timeout);
+}
+
+AsyncRevalidation::AsyncRevalidation(Cache& cache, const GlobalFrameID& frameID, const WebCore::ResourceRequest& request, std::unique_ptr<NetworkCache::Entry>&& entry, CompletionHandler<void(Result)>&& handler)
+ : m_timer(*this, &AsyncRevalidation::staleWhileRevalidateEnding)
+ , m_completionHandler(WTFMove(handler))
+{
+ auto key = entry->key();
+ auto revalidationRequest = constructRevalidationRequest(key, request, *entry.get());
+ auto age = WebCore::computeCurrentAge(entry->response(), entry->timeStamp());
+ auto lifetime = WebCore::computeFreshnessLifetimeForHTTPFamily(entry->response(), entry->timeStamp());
+ auto responseMaxStaleness = entry->response().cacheControlStaleWhileRevalidate();
+ ASSERT(responseMaxStaleness);
+ m_timer.startOneShot(*responseMaxStaleness + (lifetime - age));
+ m_load = makeUnique<SpeculativeLoad>(cache, frameID, WTFMove(revalidationRequest), WTFMove(entry), [this, key, revalidationRequest](auto&& revalidatedEntry) {
+ ASSERT(!revalidatedEntry || !revalidatedEntry->needsValidation());
+ ASSERT(!revalidatedEntry || revalidatedEntry->key() == key);
+ if (m_completionHandler)
+ m_completionHandler(revalidatedEntry ? Result::Success : Result::Failure);
+ });
+}
+
+} // namespace NetworkCache
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
Added: trunk/Source/WebKit/NetworkProcess/cache/AsyncRevalidation.h (0 => 252397)
--- trunk/Source/WebKit/NetworkProcess/cache/AsyncRevalidation.h (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/cache/AsyncRevalidation.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+
+#include "NetworkCache.h"
+#include "NetworkCacheEntry.h"
+#include "NetworkCacheSpeculativeLoad.h"
+#include <wtf/CompletionHandler.h>
+
+namespace WebCore {
+class ResourceRequest;
+};
+
+namespace WebKit {
+
+class SpeculativeLoad;
+
+namespace NetworkCache {
+
+class AsyncRevalidation {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ enum class Result {
+ Failure,
+ Timeout,
+ Success,
+ };
+ AsyncRevalidation(Cache&, const GlobalFrameID&, const WebCore::ResourceRequest&, std::unique_ptr<NetworkCache::Entry>&&, CompletionHandler<void(Result)>&&);
+
+ const SpeculativeLoad& load() const { return *m_load; }
+
+private:
+ void staleWhileRevalidateEnding();
+
+ std::unique_ptr<SpeculativeLoad> m_load;
+ WebCore::Timer m_timer;
+ CompletionHandler<void(Result)> m_completionHandler;
+};
+
+} // namespace NetworkCache
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -26,10 +26,13 @@
#include "config.h"
#include "NetworkCache.h"
+#include "AsyncRevalidation.h"
#include "Logging.h"
+#include "NetworkCacheSpeculativeLoad.h"
#include "NetworkCacheSpeculativeLoadManager.h"
#include "NetworkCacheStorage.h"
#include "NetworkProcess.h"
+#include "NetworkSession.h"
#include <WebCore/CacheValidation.h>
#include <WebCore/HTTPHeaderNames.h>
#include <WebCore/LowPowerModeNotifier.h>
@@ -152,10 +155,10 @@
return false;
}
-static bool responseHasExpired(const WebCore::ResourceResponse& response, WallTime timestamp, Optional<Seconds> maxStale)
+static UseDecision responseNeedsRevalidation(NetworkSession& networkSession, const WebCore::ResourceResponse& response, WallTime timestamp, Optional<Seconds> maxStale)
{
if (response.cacheControlContainsNoCache())
- return true;
+ return UseDecision::Validate;
auto age = WebCore::computeCurrentAge(response, timestamp);
auto lifetime = WebCore::computeFreshnessLifetimeForHTTPFamily(response, timestamp);
@@ -162,25 +165,36 @@
auto maximumStaleness = maxStale ? maxStale.value() : 0_ms;
bool hasExpired = age - lifetime > maximumStaleness;
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ if (hasExpired && !maxStale && networkSession.isStaleWhileRevalidateEnabled()) {
+ auto responseMaxStaleness = response.cacheControlStaleWhileRevalidate();
+ maximumStaleness += responseMaxStaleness ? responseMaxStaleness.value() : 0_ms;
+ bool inResponseStaleness = age - lifetime < maximumStaleness;
+ if (inResponseStaleness)
+ return UseDecision::AsyncRevalidate;
+ }
+#endif
+ if (hasExpired) {
#ifndef LOG_DISABLED
- if (hasExpired)
- LOG(NetworkCache, "(NetworkProcess) needsRevalidation hasExpired age=%f lifetime=%f max-stale=%g", age, lifetime, maxStale);
+ LOG(NetworkCache, "(NetworkProcess) needsRevalidation hasExpired age=%f lifetime=%f max-staleness=%f", age, lifetime, maximumStaleness);
#endif
+ return UseDecision::Validate;
+ }
- return hasExpired;
+ return UseDecision::Use;
}
-static bool responseNeedsRevalidation(const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, WallTime timestamp)
+static UseDecision responseNeedsRevalidation(NetworkSession& networkSession, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, WallTime timestamp)
{
auto requestDirectives = WebCore::parseCacheControlDirectives(request.httpHeaderFields());
if (requestDirectives.noCache)
- return true;
+ return UseDecision::Validate;
// For requests we ignore max-age values other than zero.
if (requestDirectives.maxAge && requestDirectives.maxAge.value() == 0_ms)
- return true;
+ return UseDecision::Validate;
- return responseHasExpired(response, timestamp, requestDirectives.maxStale);
+ return responseNeedsRevalidation(networkSession, response, timestamp, requestDirectives.maxStale);
}
static UseDecision makeUseDecision(NetworkProcess& networkProcess, const PAL::SessionID& sessionID, const Entry& entry, const WebCore::ResourceRequest& request)
@@ -197,8 +211,9 @@
if (cachePolicyAllowsExpired(request.cachePolicy()))
return UseDecision::Use;
- if (!responseNeedsRevalidation(entry.response(), request, entry.timeStamp()))
- return UseDecision::Use;
+ auto decision = responseNeedsRevalidation(*networkProcess.networkSession(sessionID), entry.response(), request, entry.timeStamp());
+ if (decision != UseDecision::Validate)
+ return decision;
if (!entry.response().hasCacheValidatorFields())
return UseDecision::NoDueToMissingValidatorFields;
@@ -251,8 +266,12 @@
bool storeUnconditionallyForHistoryNavigation = isMainResource || originalRequest.priority() == WebCore::ResourceLoadPriority::VeryHigh;
if (!storeUnconditionallyForHistoryNavigation) {
auto now = WallTime::now();
- bool hasNonZeroLifetime = !response.cacheControlContainsNoCache() && WebCore::computeFreshnessLifetimeForHTTPFamily(response, now) > 0_ms;
-
+ Seconds allowedStale { 0_ms };
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ if (auto value = response.cacheControlStaleWhileRevalidate())
+ allowedStale = value.value();
+#endif
+ bool hasNonZeroLifetime = !response.cacheControlContainsNoCache() && (WebCore::computeFreshnessLifetimeForHTTPFamily(response, now) > 0_ms || allowedStale > 0_ms);
bool possiblyReusable = response.hasCacheValidatorFields() || hasNonZeroLifetime;
if (!possiblyReusable)
return StoreDecision::NoDueToUnlikelyToReuse;
@@ -296,6 +315,18 @@
}
#endif
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+void Cache::startAsyncRevalidationIfNeeded(const WebCore::ResourceRequest& request, const NetworkCache::Key& key, std::unique_ptr<Entry>&& entry, const GlobalFrameID& frameID)
+{
+ m_pendingAsyncRevalidations.ensure(key, [&] {
+ return makeUnique<AsyncRevalidation>(*this, frameID, request, WTFMove(entry), [this, key](AsyncRevalidation::Result result) {
+ m_pendingAsyncRevalidations.remove(key);
+ LOG(NetworkCache, "(NetworkProcess) Async revalidation completed for '%s' with result %d", key.identifier().utf8().data(), static_cast<int>(result));
+ });
+ });
+}
+#endif
+
void Cache::retrieve(const WebCore::ResourceRequest& request, const GlobalFrameID& frameID, RetrieveCompletionHandler&& completionHandler)
{
ASSERT(request.url().protocolIsInHTTPFamily());
@@ -334,12 +365,11 @@
}
#endif
- m_storage->retrieve(storageKey, priority, [request, completionHandler = WTFMove(completionHandler), info = WTFMove(info), storageKey, networkProcess = makeRef(networkProcess()), sessionID = m_sessionID](auto record, auto timings) mutable {
+ m_storage->retrieve(storageKey, priority, [this, protectedThis = makeRef(*this), request, completionHandler = WTFMove(completionHandler), info = WTFMove(info), storageKey, networkProcess = makeRef(networkProcess()), sessionID = m_sessionID, frameID](auto record, auto timings) mutable {
info.storageTimings = timings;
if (!record) {
LOG(NetworkCache, "(NetworkProcess) not found in storage");
-
completeRetrieve(WTFMove(completionHandler), nullptr, info);
return false;
}
@@ -350,6 +380,14 @@
auto useDecision = entry ? makeUseDecision(networkProcess, sessionID, *entry, request) : UseDecision::NoDueToDecodeFailure;
switch (useDecision) {
+ case UseDecision::AsyncRevalidate: {
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ auto entryCopy = makeUnique<Entry>(*entry);
+ entryCopy->setNeedsValidation(true);
+ startAsyncRevalidationIfNeeded(request, storageKey, WTFMove(entryCopy), frameID);
+#endif
+ FALLTHROUGH;
+ }
case UseDecision::Use:
break;
case UseDecision::Validate:
Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCache.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -50,6 +50,7 @@
namespace NetworkCache {
+class AsyncRevalidation;
class Cache;
class SpeculativeLoadManager;
@@ -82,6 +83,7 @@
enum class UseDecision {
Use,
Validate,
+ AsyncRevalidate,
NoDueToVaryingHeaderMismatch,
NoDueToMissingValidatorFields,
NoDueToDecodeFailure,
@@ -167,6 +169,8 @@
#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
SpeculativeLoadManager* speculativeLoadManager() { return m_speculativeLoadManager.get(); }
+
+ void startAsyncRevalidationIfNeeded(const WebCore::ResourceRequest&, const NetworkCache::Key&, std::unique_ptr<Entry>&&, const GlobalFrameID&);
#endif
NetworkProcess& networkProcess() { return m_networkProcess.get(); }
@@ -193,6 +197,8 @@
#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
std::unique_ptr<WebCore::LowPowerModeNotifier> m_lowPowerModeNotifier;
std::unique_ptr<SpeculativeLoadManager> m_speculativeLoadManager;
+
+ HashMap<Key, std::unique_ptr<AsyncRevalidation>> m_pendingAsyncRevalidations;
#endif
unsigned m_traverseCount { 0 };
Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -155,6 +155,43 @@
m_completionHandler(WTFMove(m_cacheEntry));
}
+#if !LOG_DISABLED
+
+static void dumpHTTPHeadersDiff(const HTTPHeaderMap& headersA, const HTTPHeaderMap& headersB)
+{
+ auto aEnd = headersA.end();
+ for (auto it = headersA.begin(); it != aEnd; ++it) {
+ String valueB = headersB.get(it->key);
+ if (valueB.isNull())
+ LOG(NetworkCacheSpeculativePreloading, "* '%s' HTTP header is only in first request (value: %s)", it->key.utf8().data(), it->value.utf8().data());
+ else if (it->value != valueB)
+ LOG(NetworkCacheSpeculativePreloading, "* '%s' HTTP header differs in both requests: %s != %s", it->key.utf8().data(), it->value.utf8().data(), valueB.utf8().data());
+ }
+ auto bEnd = headersB.end();
+ for (auto it = headersB.begin(); it != bEnd; ++it) {
+ if (!headersA.contains(it->key))
+ LOG(NetworkCacheSpeculativePreloading, "* '%s' HTTP header is only in second request (value: %s)", it->key.utf8().data(), it->value.utf8().data());
+ }
+}
+
+#endif
+
+bool requestsHeadersMatch(const ResourceRequest& speculativeValidationRequest, const ResourceRequest& actualRequest)
+{
+ ASSERT(!actualRequest.isConditional());
+ ResourceRequest speculativeRequest = speculativeValidationRequest;
+ speculativeRequest.makeUnconditional();
+
+ if (speculativeRequest.httpHeaderFields() != actualRequest.httpHeaderFields()) {
+ LOG(NetworkCacheSpeculativePreloading, "Cannot reuse speculatively validated entry because HTTP headers used for validation do not match");
+#if !LOG_DISABLED
+ dumpHTTPHeadersDiff(speculativeRequest.httpHeaderFields(), actualRequest.httpHeaderFields());
+#endif
+ return false;
+ }
+ return true;
+}
+
} // namespace NetworkCache
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -78,6 +78,8 @@
bool m_didComplete { false };
};
+bool requestsHeadersMatch(const WebCore::ResourceRequest& speculativeValidationRequest, const WebCore::ResourceRequest& actualRequest);
+
} // namespace NetworkCache
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp (252396 => 252397)
--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -256,43 +256,6 @@
{
}
-#if !LOG_DISABLED
-
-static void dumpHTTPHeadersDiff(const HTTPHeaderMap& headersA, const HTTPHeaderMap& headersB)
-{
- auto aEnd = headersA.end();
- for (auto it = headersA.begin(); it != aEnd; ++it) {
- String valueB = headersB.get(it->key);
- if (valueB.isNull())
- LOG(NetworkCacheSpeculativePreloading, "* '%s' HTTP header is only in first request (value: %s)", it->key.utf8().data(), it->value.utf8().data());
- else if (it->value != valueB)
- LOG(NetworkCacheSpeculativePreloading, "* '%s' HTTP header differs in both requests: %s != %s", it->key.utf8().data(), it->value.utf8().data(), valueB.utf8().data());
- }
- auto bEnd = headersB.end();
- for (auto it = headersB.begin(); it != bEnd; ++it) {
- if (!headersA.contains(it->key))
- LOG(NetworkCacheSpeculativePreloading, "* '%s' HTTP header is only in second request (value: %s)", it->key.utf8().data(), it->value.utf8().data());
- }
-}
-
-#endif
-
-static bool requestsHeadersMatch(const ResourceRequest& speculativeValidationRequest, const ResourceRequest& actualRequest)
-{
- ASSERT(!actualRequest.isConditional());
- ResourceRequest speculativeRequest = speculativeValidationRequest;
- speculativeRequest.makeUnconditional();
-
- if (speculativeRequest.httpHeaderFields() != actualRequest.httpHeaderFields()) {
- LOG(NetworkCacheSpeculativePreloading, "Cannot reuse speculatively validated entry because HTTP headers used for validation do not match");
-#if !LOG_DISABLED
- dumpHTTPHeadersDiff(speculativeRequest.httpHeaderFields(), actualRequest.httpHeaderFields());
-#endif
- return false;
- }
- return true;
-}
-
bool SpeculativeLoadManager::canUsePreloadedEntry(const PreloadedEntry& entry, const ResourceRequest& actualRequest)
{
if (!entry.wasRevalidated())
Modified: trunk/Source/WebKit/Sources.txt (252396 => 252397)
--- trunk/Source/WebKit/Sources.txt 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/Sources.txt 2019-11-13 10:22:04 UTC (rev 252397)
@@ -78,6 +78,7 @@
NetworkProcess/cache/CacheStorageEngineCache.cpp
NetworkProcess/cache/CacheStorageEngineCaches.cpp
NetworkProcess/cache/CacheStorageEngineConnection.cpp
+NetworkProcess/cache/AsyncRevalidation.cpp
NetworkProcess/cache/NetworkCache.cpp
NetworkProcess/cache/NetworkCacheBlobStorage.cpp
NetworkProcess/cache/NetworkCacheCoders.cpp
Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreConfigurationRef.cpp (252396 => 252397)
--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreConfigurationRef.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreConfigurationRef.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -139,3 +139,13 @@
{
WebKit::toImpl(configuration)->setTestingSessionEnabled(enabled);
}
+
+bool WKWebsiteDataStoreConfigurationGetStaleWhileRevalidateEnabled(WKWebsiteDataStoreConfigurationRef configuration)
+{
+ return WebKit::toImpl(configuration)->staleWhileRevalidateEnabled();
+}
+
+void WKWebsiteDataStoreConfigurationSetStaleWhileRevalidateEnabled(WKWebsiteDataStoreConfigurationRef configuration, bool enabled)
+{
+ WebKit::toImpl(configuration)->setStaleWhileRevalidateEnabled(enabled);
+}
Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreConfigurationRef.h (252396 => 252397)
--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreConfigurationRef.h 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreConfigurationRef.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -66,6 +66,9 @@
WK_EXPORT bool WKWebsiteDataStoreConfigurationGetTestingSessionEnabled(WKWebsiteDataStoreConfigurationRef configuration);
WK_EXPORT void WKWebsiteDataStoreConfigurationSetTestingSessionEnabled(WKWebsiteDataStoreConfigurationRef configuration, bool enabled);
+WK_EXPORT bool WKWebsiteDataStoreConfigurationGetStaleWhileRevalidateEnabled(WKWebsiteDataStoreConfigurationRef configuration);
+WK_EXPORT void WKWebsiteDataStoreConfigurationSetStaleWhileRevalidateEnabled(WKWebsiteDataStoreConfigurationRef configuration, bool enabled);
+
#ifdef __cplusplus
}
#endif
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm (252396 => 252397)
--- trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm 2019-11-13 10:22:04 UTC (rev 252397)
@@ -150,6 +150,7 @@
m_configuration->fastServerTrustEvaluationEnabled(),
m_configuration->networkCacheSpeculativeValidationEnabled(),
m_configuration->testingSessionEnabled(),
+ m_configuration->staleWhileRevalidateEnabled(),
m_configuration->testSpeedMultiplier(),
m_configuration->suppressesConnectionTerminationOnSystemChange(),
};
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp (252396 => 252397)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -56,6 +56,7 @@
copy->m_serviceWorkerProcessTerminationDelayEnabled = this->m_serviceWorkerProcessTerminationDelayEnabled;
copy->m_fastServerTrustEvaluationEnabled = this->m_fastServerTrustEvaluationEnabled;
copy->m_networkCacheSpeculativeValidationEnabled = this->m_networkCacheSpeculativeValidationEnabled;
+ copy->m_staleWhileRevalidateEnabled = this->m_staleWhileRevalidateEnabled;
copy->m_cacheStorageDirectory = this->m_cacheStorageDirectory;
copy->m_perOriginStorageQuota = this->m_perOriginStorageQuota;
copy->m_networkCacheDirectory = this->m_networkCacheDirectory;
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h (252396 => 252397)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h 2019-11-13 10:22:04 UTC (rev 252397)
@@ -84,10 +84,13 @@
bool testingSessionEnabled() const { return m_testingSessionEnabled; }
void setTestingSessionEnabled(bool enabled) { m_testingSessionEnabled = enabled; }
-
+
+ bool staleWhileRevalidateEnabled() const { return m_staleWhileRevalidateEnabled; }
+ void setStaleWhileRevalidateEnabled(bool enabled) { m_staleWhileRevalidateEnabled = enabled; }
+
unsigned testSpeedMultiplier() const { return m_testSpeedMultiplier; }
void setTestSpeedMultiplier(unsigned multiplier) { m_testSpeedMultiplier = multiplier; }
-
+
#if PLATFORM(COCOA)
CFDictionaryRef proxyConfiguration() const { return m_proxyConfiguration.get(); }
void setProxyConfiguration(CFDictionaryRef configuration) { m_proxyConfiguration = configuration; }
@@ -159,6 +162,7 @@
#else
bool m_networkCacheSpeculativeValidationEnabled { false };
#endif
+ bool m_staleWhileRevalidateEnabled { false };
String m_localStorageDirectory;
String m_mediaKeysStorageDirectory;
String m_deviceIdHashSaltsStorageDirectory;
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (252396 => 252397)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-11-13 10:22:04 UTC (rev 252397)
@@ -1395,6 +1395,7 @@
A78CCDDC193AC9FB005ECC25 /* com.apple.WebKit.WebContent.sb in CopyFiles */ = {isa = PBXBuildFile; fileRef = A78CCDD9193AC9E3005ECC25 /* com.apple.WebKit.WebContent.sb */; };
A7D792D81767CCA300881CBE /* ActivityAssertion.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D792D41767CB0900881CBE /* ActivityAssertion.h */; };
AAB145E6223F931200E489D8 /* PrefetchCache.h in Headers */ = {isa = PBXBuildFile; fileRef = AAB145E4223F931200E489D8 /* PrefetchCache.h */; };
+ AAFA634F234F7C6400FFA864 /* AsyncRevalidation.h in Headers */ = {isa = PBXBuildFile; fileRef = AAFA634E234F7C6300FFA864 /* AsyncRevalidation.h */; };
B62E7312143047B00069EC35 /* WKHitTestResult.h in Headers */ = {isa = PBXBuildFile; fileRef = B62E7311143047B00069EC35 /* WKHitTestResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
B878B615133428DC006888E9 /* CorrectionPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = B878B613133428DC006888E9 /* CorrectionPanel.h */; };
BC017D0716260FF4007054F5 /* WKDOMDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = BC017CFF16260FF4007054F5 /* WKDOMDocument.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4181,6 +4182,8 @@
A7E93CEB192531AA00A1DC48 /* AuxiliaryProcessIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AuxiliaryProcessIOS.mm; path = ios/AuxiliaryProcessIOS.mm; sourceTree = "<group>"; };
AAB145E4223F931200E489D8 /* PrefetchCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefetchCache.h; sourceTree = "<group>"; };
AAB145E5223F931200E489D8 /* PrefetchCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrefetchCache.cpp; sourceTree = "<group>"; };
+ AAFA634E234F7C6300FFA864 /* AsyncRevalidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncRevalidation.h; sourceTree = "<group>"; };
+ AAFA6350234F7C7300FFA864 /* AsyncRevalidation.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncRevalidation.cpp; sourceTree = "<group>"; };
B396EA5512E0ED2D00F4FEB7 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
B62E730F143047A60069EC35 /* WKHitTestResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKHitTestResult.cpp; sourceTree = "<group>"; };
B62E7311143047B00069EC35 /* WKHitTestResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKHitTestResult.h; sourceTree = "<group>"; };
@@ -9217,6 +9220,8 @@
E489D2821A0A2BE80078C06A /* cache */ = {
isa = PBXGroup;
children = (
+ AAFA6350234F7C7300FFA864 /* AsyncRevalidation.cpp */,
+ AAFA634E234F7C6300FFA864 /* AsyncRevalidation.h */,
41897ED61F415D860016FA42 /* CacheStorageEngine.cpp */,
41897ED21F415D850016FA42 /* CacheStorageEngine.h */,
41C858191F510DEE0065E085 /* CacheStorageEngineCache.cpp */,
@@ -9465,6 +9470,7 @@
A175C44A21AA3171000037D0 /* ArgumentCodersCocoa.h in Headers */,
CE1A0BD21A48E6C60054EF74 /* AssertionServicesSPI.h in Headers */,
515E7728183DD6F60007203F /* AsyncRequest.h in Headers */,
+ AAFA634F234F7C6400FFA864 /* AsyncRevalidation.h in Headers */,
BCEE966D112FAF57006BCC24 /* Attachment.h in Headers */,
E1A31732134CEA6C007C9A4F /* AttributedString.h in Headers */,
512F589712A8838800629530 /* AuthenticationChallengeProxy.h in Headers */,
Modified: trunk/Tools/ChangeLog (252396 => 252397)
--- trunk/Tools/ChangeLog 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Tools/ChangeLog 2019-11-13 10:22:04 UTC (rev 252397)
@@ -1,3 +1,15 @@
+2019-11-13 Rob Buis <[email protected]>
+
+ Support stale-while-revalidate cache strategy
+ https://bugs.webkit.org/show_bug.cgi?id=201461
+
+ Reviewed by Youenn Fablet.
+
+ Enable stale-while-revalidate for the test runner.
+
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::websiteDataStore):
+
2019-11-12 Wenson Hsieh <[email protected]>
[iOS] WKWebView does not respect system spellchecking preference
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (252396 => 252397)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2019-11-13 09:26:27 UTC (rev 252396)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2019-11-13 10:22:04 UTC (rev 252397)
@@ -532,6 +532,7 @@
WKWebsiteDataStoreConfigurationSetResourceLoadStatisticsDirectory(configuration.get(), toWK(temporaryFolder + pathSeparator + "ResourceLoadStatistics").get());
WKWebsiteDataStoreConfigurationSetPerOriginStorageQuota(configuration.get(), 400 * 1024);
WKWebsiteDataStoreConfigurationSetNetworkCacheSpeculativeValidationEnabled(configuration.get(), true);
+ WKWebsiteDataStoreConfigurationSetStaleWhileRevalidateEnabled(configuration.get(), true);
WKWebsiteDataStoreConfigurationSetTestingSessionEnabled(configuration.get(), true);
}
dataStore = WKWebsiteDataStoreCreateWithConfiguration(configuration.get());