- 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();