Title: [283081] trunk/Source/WebKit
Revision
283081
Author
[email protected]
Date
2021-09-25 09:12:26 -0700 (Sat, 25 Sep 2021)

Log Message

Pending preconnect key should include User-Agent
https://bugs.webkit.org/show_bug.cgi?id=230565

Reviewed by Chris Dumez.

When using an HTTPS proxy, the HTTP connection cache key used for connection coalescing in
CFNetwork includes the User-Agent (<rdar://problem/59434166>). This means we should also
include it in the preconnect cache key. Otherwise, we might delay the main resource load on
preconnect unnecessarily in cases where the User-Agent mismatches and the preconnect gets
thrown away. This can happen if (for instance) a page is force-loaded into desktop or mobile
mode on iOS, which causes a UA change after the call to decidePolicyForNavigationAction.

* NetworkProcess/NetworkLoadScheduler.cpp:
(WebKit::mainResourceLoadKey):
(WebKit::NetworkLoadScheduler::scheduleMainResourceLoad):
(WebKit::NetworkLoadScheduler::unscheduleMainResourceLoad):
(WebKit::NetworkLoadScheduler::startedPreconnectForMainResource):
(WebKit::NetworkLoadScheduler::finishedPreconnectForMainResource):
* NetworkProcess/NetworkLoadScheduler.h:
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::preconnectTo):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (283080 => 283081)


--- trunk/Source/WebKit/ChangeLog	2021-09-25 15:47:55 UTC (rev 283080)
+++ trunk/Source/WebKit/ChangeLog	2021-09-25 16:12:26 UTC (rev 283081)
@@ -1,3 +1,27 @@
+2021-09-25  Ben Nham  <[email protected]>
+
+        Pending preconnect key should include User-Agent
+        https://bugs.webkit.org/show_bug.cgi?id=230565
+
+        Reviewed by Chris Dumez.
+
+        When using an HTTPS proxy, the HTTP connection cache key used for connection coalescing in
+        CFNetwork includes the User-Agent (<rdar://problem/59434166>). This means we should also
+        include it in the preconnect cache key. Otherwise, we might delay the main resource load on
+        preconnect unnecessarily in cases where the User-Agent mismatches and the preconnect gets
+        thrown away. This can happen if (for instance) a page is force-loaded into desktop or mobile
+        mode on iOS, which causes a UA change after the call to decidePolicyForNavigationAction.
+
+        * NetworkProcess/NetworkLoadScheduler.cpp:
+        (WebKit::mainResourceLoadKey):
+        (WebKit::NetworkLoadScheduler::scheduleMainResourceLoad):
+        (WebKit::NetworkLoadScheduler::unscheduleMainResourceLoad):
+        (WebKit::NetworkLoadScheduler::startedPreconnectForMainResource):
+        (WebKit::NetworkLoadScheduler::finishedPreconnectForMainResource):
+        * NetworkProcess/NetworkLoadScheduler.h:
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::preconnectTo):
+
 2021-09-24  Lauro Moura  <[email protected]>
 
         Non-unified partial build fixes late September edition

Modified: trunk/Source/WebKit/NetworkProcess/NetworkLoadScheduler.cpp (283080 => 283081)


--- trunk/Source/WebKit/NetworkProcess/NetworkLoadScheduler.cpp	2021-09-25 15:47:55 UTC (rev 283080)
+++ trunk/Source/WebKit/NetworkProcess/NetworkLoadScheduler.cpp	2021-09-25 16:12:26 UTC (rev 283081)
@@ -153,6 +153,13 @@
         context->unschedule(load);
 }
 
+// We add User-Agent to the preconnect key since it part of the HTTP connection cache key used for
+// coalescing sockets in CFNetwork when using an HTTPS proxy (<rdar://problem/59434166>).
+static std::tuple<String, String> mainResourceLoadKey(const String& protocolHostAndPort, const String& userAgent)
+{
+    return std::make_tuple(protocolHostAndPort.isNull() ? emptyString() : protocolHostAndPort, userAgent.isNull() ? emptyString() : userAgent);
+}
+
 void NetworkLoadScheduler::scheduleMainResourceLoad(NetworkLoad& load)
 {
     String protocolHostAndPort = load.url().protocolHostAndPort();
@@ -161,7 +168,7 @@
         return;
     }
 
-    auto iter = m_pendingMainResourcePreconnects.find(protocolHostAndPort);
+    auto iter = m_pendingMainResourcePreconnects.find(mainResourceLoadKey(protocolHostAndPort, load.parameters().request.httpUserAgent()));
     if (iter == m_pendingMainResourcePreconnects.end()) {
         load.start();
         return;
@@ -185,7 +192,7 @@
     if (metrics)
         updateOriginProtocolInfo(protocolHostAndPort, metrics->protocol);
 
-    auto iter = m_pendingMainResourcePreconnects.find(protocolHostAndPort);
+    auto iter = m_pendingMainResourcePreconnects.find(mainResourceLoadKey(protocolHostAndPort, load.parameters().request.httpUserAgent()));
     if (iter == m_pendingMainResourcePreconnects.end())
         return;
 
@@ -194,9 +201,10 @@
         maybePrunePreconnectInfo(iter);
 }
 
-void NetworkLoadScheduler::startedPreconnectForMainResource(const URL& url)
+void NetworkLoadScheduler::startedPreconnectForMainResource(const URL& url, const String& userAgent)
 {
-    auto iter = m_pendingMainResourcePreconnects.find(url.protocolHostAndPort());
+    auto key = mainResourceLoadKey(url.protocolHostAndPort(), userAgent);
+    auto iter = m_pendingMainResourcePreconnects.find(key);
     if (iter != m_pendingMainResourcePreconnects.end()) {
         PendingMainResourcePreconnectInfo& info = iter->value;
         info.pendingPreconnects++;
@@ -204,12 +212,12 @@
     }
 
     PendingMainResourcePreconnectInfo info;
-    m_pendingMainResourcePreconnects.add(url.protocolHostAndPort(), WTFMove(info));
+    m_pendingMainResourcePreconnects.add(key, WTFMove(info));
 }
 
-void NetworkLoadScheduler::finishedPreconnectForMainResource(const URL& url, const WebCore::ResourceError& error)
+void NetworkLoadScheduler::finishedPreconnectForMainResource(const URL& url, const String& userAgent, const WebCore::ResourceError& error)
 {
-    auto iter = m_pendingMainResourcePreconnects.find(url.protocolHostAndPort());
+    auto iter = m_pendingMainResourcePreconnects.find(mainResourceLoadKey(url.protocolHostAndPort(), userAgent));
     if (iter == m_pendingMainResourcePreconnects.end())
         return;
 

Modified: trunk/Source/WebKit/NetworkProcess/NetworkLoadScheduler.h (283080 => 283081)


--- trunk/Source/WebKit/NetworkProcess/NetworkLoadScheduler.h	2021-09-25 15:47:55 UTC (rev 283080)
+++ trunk/Source/WebKit/NetworkProcess/NetworkLoadScheduler.h	2021-09-25 16:12:26 UTC (rev 283081)
@@ -28,6 +28,7 @@
 #include <WebCore/LoadSchedulingMode.h>
 #include <WebCore/NetworkLoadMetrics.h>
 #include <WebCore/PageIdentifier.h>
+#include <tuple>
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/ListHashSet.h>
@@ -50,8 +51,8 @@
     void schedule(NetworkLoad&);
     void unschedule(NetworkLoad&, const WebCore::NetworkLoadMetrics* = nullptr);
 
-    void startedPreconnectForMainResource(const URL&);
-    void finishedPreconnectForMainResource(const URL&, const WebCore::ResourceError&);
+    void startedPreconnectForMainResource(const URL&, const String& userAgent);
+    void finishedPreconnectForMainResource(const URL&, const String& userAgent, const WebCore::ResourceError&);
 
     void setResourceLoadSchedulingMode(WebCore::PageIdentifier, WebCore::LoadSchedulingMode);
     void prioritizeLoads(const Vector<NetworkLoad*>&);
@@ -77,7 +78,8 @@
         unsigned pendingPreconnects {1};
         ListHashSet<NetworkLoad *> pendingLoads;
     };
-    using PendingPreconnectMap = HashMap<String, PendingMainResourcePreconnectInfo>;
+    // Maps (protocolHostAndPort, userAgent) => PendingMainResourcePreconnectInfo.
+    using PendingPreconnectMap = HashMap<std::tuple<String, String>, PendingMainResourcePreconnectInfo>;
     PendingPreconnectMap m_pendingMainResourcePreconnects;
 
     void maybePrunePreconnectInfo(PendingPreconnectMap::iterator&);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (283080 => 283081)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-09-25 15:47:55 UTC (rev 283080)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2021-09-25 16:12:26 UTC (rev 283081)
@@ -1402,9 +1402,9 @@
     parameters.storedCredentialsPolicy = storedCredentialsPolicy;
     parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
 
-    networkSession->networkLoadScheduler().startedPreconnectForMainResource(url);
-    auto task = new PreconnectTask(*networkSession, WTFMove(parameters), [networkSession, url](const WebCore::ResourceError& error) {
-        networkSession->networkLoadScheduler().finishedPreconnectForMainResource(url, error);
+    networkSession->networkLoadScheduler().startedPreconnectForMainResource(url, userAgent);
+    auto task = new PreconnectTask(*networkSession, WTFMove(parameters), [networkSession, url, userAgent](const WebCore::ResourceError& error) {
+        networkSession->networkLoadScheduler().finishedPreconnectForMainResource(url, userAgent, error);
     });
     task->setTimeout(10_s);
     task->start();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to