Support for preconnect Link headers
authoryoav@yoav.ws <yoav@yoav.ws@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Jan 2018 22:16:21 +0000 (22:16 +0000)
committeryoav@yoav.ws <yoav@yoav.ws@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Jan 2018 22:16:21 +0000 (22:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181657

Reviewed by Darin Adler.

Source/WebCore:

Move the preconnect functionality into its own function, and
also call this function when Link headers are processed.

Test: http/tests/preconnect/link-header-rel-preconnect-http.php

* loader/LinkLoader.cpp:
(WebCore::LinkLoader::loadLinksFromHeader): Call preconnectIfNeeded.
(WebCore::LinkLoader::preconnectIfNeeded): Preconnect to a host functionality moved here.
(WebCore::LinkLoader::loadLink): Call preconnectIfNeeded.
* loader/LinkLoader.h:

LayoutTests:

Add test to see Link preconnect headers trigger a connection.

* http/tests/preconnect/link-header-rel-preconnect-http-expected.txt: Added.
* http/tests/preconnect/link-header-rel-preconnect-http.html: Added.
* http/tests/preconnect/resources/header-preconnect.php: Added.
* platform/ios-simulator/TestExpectations: Skipped the test, as ios-simulator doesn't process Link headers for subresources.
* platform/win/TestExpectations: Skipped the preconnect test directory, as it doesn't work on Windows.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@227235 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/preconnect/link-header-rel-preconnect-http-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/preconnect/link-header-rel-preconnect-http.html [new file with mode: 0644]
LayoutTests/http/tests/preconnect/resources/header-preconnect.php [new file with mode: 0644]
LayoutTests/platform/ios-simulator/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/loader/LinkLoader.cpp
Source/WebCore/loader/LinkLoader.h

index f084566..ee192b6 100644 (file)
@@ -1,3 +1,18 @@
+2018-01-19  Yoav Weiss  <yoav@yoav.ws>
+
+        Support for preconnect Link headers
+        https://bugs.webkit.org/show_bug.cgi?id=181657
+
+        Reviewed by Darin Adler.
+
+        Add test to see Link preconnect headers trigger a connection.
+
+        * http/tests/preconnect/link-header-rel-preconnect-http-expected.txt: Added.
+        * http/tests/preconnect/link-header-rel-preconnect-http.html: Added.
+        * http/tests/preconnect/resources/header-preconnect.php: Added.
+        * platform/ios-simulator/TestExpectations: Skipped the test, as ios-simulator doesn't process Link headers for subresources.
+        * platform/win/TestExpectations: Skipped the preconnect test directory, as it doesn't work on Windows.
+
 2018-01-19  Joseph Pecoraro  <pecoraro@apple.com>
 
         AppCache: Log a Deprecation warning to the Console when AppCache is used
diff --git a/LayoutTests/http/tests/preconnect/link-header-rel-preconnect-http-expected.txt b/LayoutTests/http/tests/preconnect/link-header-rel-preconnect-http-expected.txt
new file mode 100644 (file)
index 0000000..db5fbef
--- /dev/null
@@ -0,0 +1,10 @@
+CONSOLE MESSAGE: Successfuly preconnected to http://localhost:8000/
+Tests that Link header's rel=preconnect works as expected over HTTP.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/preconnect/link-header-rel-preconnect-http.html b/LayoutTests/http/tests/preconnect/link-header-rel-preconnect-http.html
new file mode 100644 (file)
index 0000000..967ea92
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+description("Tests that Link header's rel=preconnect works as expected over HTTP.");
+jsTestIsAsync = true;
+
+// If the feature is not supported on this platform, fail without a timeout.
+if (!document.createElement("link").relList.supports("preconnect"))
+    finishJSTest();
+
+internals.setConsoleMessageListener(function() {
+    finishJSTest();
+});
+var script = document.createElement("script");
+script.src = "resources/header-preconnect.php";
+document.body.appendChild(script);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/preconnect/resources/header-preconnect.php b/LayoutTests/http/tests/preconnect/resources/header-preconnect.php
new file mode 100644 (file)
index 0000000..c89de4f
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+   header('Link: <http://localhost:8000>; rel=preconnect');
+?>
index 3d30b34..df3da8b 100644 (file)
@@ -59,5 +59,8 @@ wasm/window-postmessage.html [ Skip ]
 # WebGL tests which need triaging https://bugs.webkit.org/b/174100
 webgl/1.0.2/conformance/uniforms/uniform-default-values.html [ Failure ]
 
+# ios-simulator does not process link headers for subresources
+webkit.org/b/181789 http/tests/preconnect/link-header-rel-preconnect-http.html [ Skip ]
+
 # This test requires Skia, which isn't available on iOS.
 webkit.org/b/174079 fast/text/variations/skia-postscript-name.html [ ImageOnlyFailure ]
index 23bc59d..7e25ef1 100644 (file)
@@ -3786,8 +3786,7 @@ webkit.org/b/177541 accessibility/image-load-on-delay.html [ Failure ]
 
 # preconnect tests are failing on Windows.
 webkit.org/b/177626 fast/dom/HTMLLinkElement/preconnect-support.html  [ Skip ]
-webkit.org/b/177626 http/tests/preconnect/link-rel-preconnect-http.html [ Skip ]
-webkit.org/b/177626 http/tests/preconnect/link-rel-preconnect-https.html [ Skip ]
+webkit.org/b/177626 http/tests/preconnect/ [ Skip ]
 
 webkit.org/b/177964 fast/text/font-display/block-nofinish.html [ Pass ImageOnlyFailure ]
 webkit.org/b/177964 fast/text/font-display/failure-finish.html [ Pass ImageOnlyFailure ]
index a5c0cda..aedc2e8 100644 (file)
@@ -1,3 +1,21 @@
+2018-01-19  Yoav Weiss  <yoav@yoav.ws>
+
+        Support for preconnect Link headers
+        https://bugs.webkit.org/show_bug.cgi?id=181657
+
+        Reviewed by Darin Adler.
+
+        Move the preconnect functionality into its own function, and
+        also call this function when Link headers are processed.
+
+        Test: http/tests/preconnect/link-header-rel-preconnect-http.php
+
+        * loader/LinkLoader.cpp:
+        (WebCore::LinkLoader::loadLinksFromHeader): Call preconnectIfNeeded.
+        (WebCore::LinkLoader::preconnectIfNeeded): Preconnect to a host functionality moved here.
+        (WebCore::LinkLoader::loadLink): Call preconnectIfNeeded.
+        * loader/LinkLoader.h:
+
 2018-01-19  Joseph Pecoraro  <pecoraro@apple.com>
 
         AppCache: Log a Deprecation warning to the Console when AppCache is used
index e4ef3b5..b3625e6 100644 (file)
@@ -110,6 +110,7 @@ void LinkLoader::loadLinksFromHeader(const String& headerValue, const URL& baseU
         // Sanity check to avoid re-entrancy here.
         if (equalIgnoringFragmentIdentifier(url, baseURL))
             continue;
+        preconnectIfNeeded(relAttribute, url, document, header.crossOrigin());
         preloadIfNeeded(relAttribute, url, document, header.as(), header.media(), header.mimeType(), header.crossOrigin(), nullptr);
     }
 }
@@ -211,6 +212,26 @@ bool LinkLoader::isSupportedType(CachedResource::Type resourceType, const String
     return false;
 }
 
+void LinkLoader::preconnectIfNeeded(const LinkRelAttribute& relAttribute, const URL& href, Document& document, const String& crossOrigin)
+{
+    if (!relAttribute.isLinkPreconnect || !href.isValid() || !href.protocolIsInHTTPFamily() || !document.frame())
+        return;
+    ASSERT(document.settings().linkPreconnectEnabled());
+    StoredCredentialsPolicy storageCredentialsPolicy = StoredCredentialsPolicy::Use;
+    if (equalIgnoringASCIICase(crossOrigin, "anonymous") && document.securityOrigin().canAccess(SecurityOrigin::create(href)))
+        storageCredentialsPolicy = StoredCredentialsPolicy::DoNotUse;
+    ASSERT(document.frame()->loader().networkingContext());
+    platformStrategies()->loaderStrategy()->preconnectTo(*document.frame()->loader().networkingContext(), href, storageCredentialsPolicy, [weakDocument = document.createWeakPtr(), href](ResourceError error) {
+        if (!weakDocument)
+            return;
+
+        if (!error.isNull())
+            weakDocument->addConsoleMessage(MessageSource::Network, MessageLevel::Error, makeString(ASCIILiteral("Failed to preconnect to "), href.string(), ASCIILiteral(". Error: "), error.localizedDescription()));
+        else
+            weakDocument->addConsoleMessage(MessageSource::Network, MessageLevel::Info, makeString(ASCIILiteral("Successfuly preconnected to "), href.string()));
+    });
+}
+
 std::unique_ptr<LinkPreloadResourceClient> LinkLoader::preloadIfNeeded(const LinkRelAttribute& relAttribute, const URL& href, Document& document, const String& as, const String& media, const String& mimeType, const String& crossOriginMode, LinkLoader* loader)
 {
     if (!document.loader() || !relAttribute.isLinkPreload)
@@ -259,22 +280,7 @@ bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const URL& href,
             document.frame()->loader().client().prefetchDNS(href.host());
     }
 
-    if (relAttribute.isLinkPreconnect && href.isValid() && href.protocolIsInHTTPFamily() && document.frame()) {
-        ASSERT(document.settings().linkPreconnectEnabled());
-        StoredCredentialsPolicy storageCredentialsPolicy = StoredCredentialsPolicy::Use;
-        if (equalIgnoringASCIICase(crossOrigin, "anonymous") && document.securityOrigin().canAccess(SecurityOrigin::create(href)))
-            storageCredentialsPolicy = StoredCredentialsPolicy::DoNotUse;
-        ASSERT(document.frame()->loader().networkingContext());
-        platformStrategies()->loaderStrategy()->preconnectTo(*document.frame()->loader().networkingContext(), href, storageCredentialsPolicy, [weakDocument = document.createWeakPtr(), href](ResourceError error) {
-            if (!weakDocument)
-                return;
-
-            if (!error.isNull())
-                weakDocument->addConsoleMessage(MessageSource::Network, MessageLevel::Error, makeString(ASCIILiteral("Failed to preconnect to "), href.string(), ASCIILiteral(". Error: "), error.localizedDescription()));
-            else
-                weakDocument->addConsoleMessage(MessageSource::Network, MessageLevel::Info, makeString(ASCIILiteral("Successfuly preconnected to "), href.string()));
-        });
-    }
+    preconnectIfNeeded(relAttribute, href, document, crossOrigin);
 
     if (m_client.shouldLoadLink()) {
         auto resourceClient = preloadIfNeeded(relAttribute, href, document, as, media, mimeType, crossOrigin, this);
index 1755f61..db7e2e2 100644 (file)
@@ -64,6 +64,7 @@ public:
 
 private:
     void notifyFinished(CachedResource&) override;
+    static void preconnectIfNeeded(const LinkRelAttribute&, const URL& href, Document&, const String& crossOrigin);
     static std::unique_ptr<LinkPreloadResourceClient> preloadIfNeeded(const LinkRelAttribute&, const URL& href, Document&, const String& as, const String& media, const String& type, const String& crossOriginMode, LinkLoader*);
 
     LinkLoaderClient& m_client;