Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Network connection integrity policies are missing when connecting via…
… <link rel=preconnect>

https://bugs.webkit.org/show_bug.cgi?id=257096
rdar://107356544

Reviewed by Tim Horton.

Add logic to set network connection integrity policy flags when sending a network request triggered
by a link element with `rel=preconnect`. See below for more details.

* Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
* Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm:
(-[WKWebView _networkProcessIdentifier]):

Add a testing hook that returns the network process PID, for use in a new (internal) API test.

* Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::policySourceDocumentLoaderForFrame):

Pull existing logic for grabbing a suitable `DocumentLoader` for a given frame out of
`addParametersShared` and into a separate helper function, so that we can use it in multiple places.

(WebKit::addParametersShared):
(WebKit::WebLoaderStrategy::preconnectTo):

Use the new helper function above to populate network connection integrity flags on the outbound
resource load when handling preconnect.

* Tools/TestWebKitAPI/cocoa/HTTPServer.h:
* Tools/TestWebKitAPI/cocoa/HTTPServer.mm:
(TestWebKitAPI::HTTPServer::totalConnections const):

Add a helper method on the mock HTTP server to return the total connection count.

Canonical link: https://commits.webkit.org/264382@main
  • Loading branch information
whsieh committed May 22, 2023
1 parent 8792d34 commit c2ec9c1
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 13 deletions.
Expand Up @@ -95,6 +95,8 @@ struct WKAppPrivacyReportTestingData {
@property (nonatomic, setter=_setScrollingUpdatesDisabledForTesting:) BOOL _scrollingUpdatesDisabledForTesting;
@property (nonatomic, readonly) NSString *_scrollingTreeAsText;

@property (nonatomic, readonly) pid_t _networkProcessIdentifier;

@property (nonatomic, readonly) unsigned long _countOfUpdatesWithLayerChanges;

- (void)_processWillSuspendForTesting:(void (^)(void))completionHandler;
Expand Down
9 changes: 9 additions & 0 deletions Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm
Expand Up @@ -29,6 +29,7 @@
#import "AudioSessionRoutingArbitratorProxy.h"
#import "GPUProcessProxy.h"
#import "MediaSessionCoordinatorProxyPrivate.h"
#import "NetworkProcessProxy.h"
#import "PlaybackSessionManagerProxy.h"
#import "PrintInfo.h"
#import "RemoteLayerTreeDrawingAreaProxy.h"
Expand All @@ -40,6 +41,7 @@
#import "WebProcessPool.h"
#import "WebProcessProxy.h"
#import "WebViewImpl.h"
#import "WebsiteDataStore.h"
#import "_WKFrameHandleInternal.h"
#import "_WKInspectorInternal.h"
#import <WebCore/RuntimeApplicationChecks.h>
Expand Down Expand Up @@ -213,6 +215,13 @@ - (NSString *)_scrollingTreeAsText
return coordinator->scrollingTreeAsText();
}

- (pid_t)_networkProcessIdentifier
{
auto* networkProcess = _page->websiteDataStore().networkProcessIfExists();
RELEASE_ASSERT(networkProcess);
return networkProcess->processIdentifier();
}

- (void)_setScrollingUpdatesDisabledForTesting:(BOOL)disabled
{
}
Expand Down
38 changes: 25 additions & 13 deletions Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
Expand Up @@ -304,6 +304,25 @@ bool WebLoaderStrategy::tryLoadingUsingPDFJSHandler(ResourceLoader& resourceLoad
}
#endif

static RefPtr<DocumentLoader> policySourceDocumentLoaderForFrame(const LocalFrame& frame, bool isMainFrameNavigation = false)
{
RefPtr mainFrame = dynamicDowncast<LocalFrame>(frame.mainFrame());
if (!mainFrame)
return { };

RefPtr mainFrameDocumentLoader = mainFrame->loader().policyDocumentLoader();
if (!mainFrameDocumentLoader)
mainFrameDocumentLoader = mainFrame->loader().provisionalDocumentLoader();
if (!mainFrameDocumentLoader || !isMainFrameNavigation)
mainFrameDocumentLoader = mainFrame->loader().documentLoader();

RefPtr policySourceDocumentLoader = mainFrameDocumentLoader;
if (policySourceDocumentLoader && !policySourceDocumentLoader->request().url().hasSpecialScheme() && frame.document()->url().protocolIsInHTTPFamily())
policySourceDocumentLoader = frame.loader().documentLoader();

return policySourceDocumentLoader;
}

static void addParametersShared(const LocalFrame* frame, NetworkResourceLoadParameters& parameters, bool isMainFrameNavigation = false)
{
parameters.crossOriginAccessControlCheckEnabled = CrossOriginAccessControlCheckDisabler::singleton().crossOriginAccessControlCheckEnabled();
Expand All @@ -316,20 +335,11 @@ static void addParametersShared(const LocalFrame* frame, NetworkResourceLoadPara
// WebLocalFrameLoaderClient::applyToDocumentLoader stored the value on. Otherwise, we need to get the
// value from the main frame's current DocumentLoader.

auto* localFrame = dynamicDowncast<LocalFrame>(frame->mainFrame());
if (!localFrame)
RefPtr mainFrame = dynamicDowncast<LocalFrame>(frame->mainFrame());
if (!mainFrame)
return;

auto& mainFrame = *localFrame;
auto* mainFrameDocumentLoader = mainFrame.loader().policyDocumentLoader();
if (!mainFrameDocumentLoader)
mainFrameDocumentLoader = mainFrame.loader().provisionalDocumentLoader();
if (!mainFrameDocumentLoader || !isMainFrameNavigation)
mainFrameDocumentLoader = mainFrame.loader().documentLoader();

auto* policySourceDocumentLoader = mainFrameDocumentLoader;
if (policySourceDocumentLoader && !policySourceDocumentLoader->request().url().hasSpecialScheme() && frame->document()->url().protocolIsInHTTPFamily())
policySourceDocumentLoader = frame->loader().documentLoader();
RefPtr policySourceDocumentLoader = policySourceDocumentLoaderForFrame(*frame, isMainFrameNavigation);

parameters.allowPrivacyProxy = policySourceDocumentLoader ? policySourceDocumentLoader->allowPrivacyProxy() : true;

Expand All @@ -356,7 +366,7 @@ static void addParametersShared(const LocalFrame* frame, NetworkResourceLoadPara
parameters.networkConnectionIntegrityPolicy = networkConnectionIntegrityPolicy;

if (isMainFrameNavigation)
parameters.linkPreconnectEarlyHintsEnabled = mainFrame.settings().linkPreconnectEarlyHintsEnabled();
parameters.linkPreconnectEarlyHintsEnabled = mainFrame->settings().linkPreconnectEarlyHintsEnabled();
}

void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceLoader, const ResourceRequest& request, const WebResourceLoader::TrackingParameters& trackingParameters, bool shouldClearReferrerOnHTTPSToHTTPRedirect, Seconds maximumBufferingTime)
Expand Down Expand Up @@ -922,6 +932,8 @@ void WebLoaderStrategy::preconnectTo(WebCore::ResourceRequest&& request, WebPage
#if ENABLE(APP_BOUND_DOMAINS)
parameters.isNavigatingToAppBoundDomain = webFrame.isTopFrameNavigatingToAppBoundDomain();
#endif
if (RefPtr loader = policySourceDocumentLoaderForFrame(*webFrame.coreLocalFrame()))
parameters.networkConnectionIntegrityPolicy = loader->networkConnectionIntegrityPolicy();

std::optional<WebCore::ResourceLoaderIdentifier> preconnectionIdentifier;
if (completionHandler) {
Expand Down
1 change: 1 addition & 0 deletions Tools/TestWebKitAPI/cocoa/HTTPServer.h
Expand Up @@ -96,6 +96,7 @@ class HTTPServer {
NSURLRequest *request(StringView path = "/"_s) const;
NSURLRequest *requestWithLocalhost(StringView path = "/"_s) const;
WKWebViewConfiguration *httpsProxyConfiguration() const;
size_t totalConnections() const;
size_t totalRequests() const;
void cancel();
void terminateAllConnections(CompletionHandler<void()>&&);
Expand Down
5 changes: 5 additions & 0 deletions Tools/TestWebKitAPI/cocoa/HTTPServer.mm
Expand Up @@ -291,6 +291,11 @@ static void startListening(nw_listener_t listener)
});
}

size_t HTTPServer::totalConnections() const
{
return m_requestData->connections.size();
}

size_t HTTPServer::totalRequests() const
{
return m_requestData->requestCount;
Expand Down

0 comments on commit c2ec9c1

Please sign in to comment.