Make WebLoaderStrategy send to NetworkResourceLoader necessary parameters to handle full loads in NetworkProcess
https://bugs.webkit.org/show_bug.cgi?id=184763

Reviewed by Chris Dumez.

Source/WebCore:

No change of behavior yet since we do not use these parameters in NetworkProcess yet.

Add PreflightPolicy and CSP response headers as ResourceLoaderOptions.
This allows passing them from DocumentThreadableLoader to WebLoaderStrategy.

Allow getting the original headers from a SubresourceLoader.
This allows passing them from DocumentThreadableLoader down to WebLoaderStrategy.

* Modules/fetch/FetchLoader.cpp:
(WebCore::FetchLoader::startLoadingBlobURL):
(WebCore::FetchLoader::start):
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
(WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequest):
(WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest):
* loader/ResourceLoaderOptions.h:
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::originalHeaders const):
* loader/SubresourceLoader.h:
* loader/ThreadableLoader.cpp:
(WebCore::ThreadableLoaderOptions::ThreadableLoaderOptions):
(WebCore::ThreadableLoaderOptions::isolatedCopy const):
* loader/ThreadableLoader.h:
* page/EventSource.cpp:
(WebCore::EventSource::connect):
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::createRequest):

Source/WebKit:

Set all required NetworkResourceLoadParameters for asynchronous loads.
This includes preflight policy, CSP response headers, SecurityOrigin and content blockers identifier.

Update NetworkLoadChecker to handle preflight policy.
This is not needed right now since sync XHR and ping loads are using the default ConsiderPreflight policy.
But this will be needed for XHR/fetch/EventSource loads.

* NetworkProcess/NetworkLoadChecker.cpp:
(WebKit::NetworkLoadChecker::NetworkLoadChecker):
(WebKit::NetworkLoadChecker::checkRedirection):
(WebKit::NetworkLoadChecker::validateResponse):
(WebKit::NetworkLoadChecker::checkCORSRequest):
* NetworkProcess/NetworkLoadChecker.h:
(WebKit::NetworkLoadChecker::create):
* NetworkProcess/NetworkResourceLoadParameters.cpp:
(WebKit::NetworkResourceLoadParameters::encode const):
(WebKit::NetworkResourceLoadParameters::decode):
* NetworkProcess/NetworkResourceLoadParameters.h:
* NetworkProcess/NetworkResourceLoader.cpp:
* NetworkProcess/PingLoad.cpp:
(WebKit::PingLoad::PingLoad):
* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@230942 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 6cfbe7e..408e6b4 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,38 @@
+2018-04-23  Youenn Fablet  <youenn@apple.com>
+
+        Make WebLoaderStrategy send to NetworkResourceLoader necessary parameters to handle full loads in NetworkProcess
+        https://bugs.webkit.org/show_bug.cgi?id=184763
+
+        Reviewed by Chris Dumez.
+
+        No change of behavior yet since we do not use these parameters in NetworkProcess yet.
+
+        Add PreflightPolicy and CSP response headers as ResourceLoaderOptions.
+        This allows passing them from DocumentThreadableLoader to WebLoaderStrategy.
+
+        Allow getting the original headers from a SubresourceLoader.
+        This allows passing them from DocumentThreadableLoader down to WebLoaderStrategy.
+
+        * Modules/fetch/FetchLoader.cpp:
+        (WebCore::FetchLoader::startLoadingBlobURL):
+        (WebCore::FetchLoader::start):
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
+        (WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequest):
+        (WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest):
+        * loader/ResourceLoaderOptions.h:
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::originalHeaders const):
+        * loader/SubresourceLoader.h:
+        * loader/ThreadableLoader.cpp:
+        (WebCore::ThreadableLoaderOptions::ThreadableLoaderOptions):
+        (WebCore::ThreadableLoaderOptions::isolatedCopy const):
+        * loader/ThreadableLoader.h:
+        * page/EventSource.cpp:
+        (WebCore::EventSource::connect):
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::createRequest):
+
 2018-04-23  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         [WPE][GTK] Remove WlUniquePtr<wl_display> footgun
diff --git a/Source/WebCore/Modules/fetch/FetchLoader.cpp b/Source/WebCore/Modules/fetch/FetchLoader.cpp
index 5412fd2..c01331f 100644
--- a/Source/WebCore/Modules/fetch/FetchLoader.cpp
+++ b/Source/WebCore/Modules/fetch/FetchLoader.cpp
@@ -73,7 +73,7 @@
     ThreadableLoaderOptions options;
     options.sendLoadCallbacks = SendCallbacks;
     options.dataBufferingPolicy = DoNotBufferData;
-    options.preflightPolicy = ConsiderPreflight;
+    options.preflightPolicy = PreflightPolicy::Consider;
     options.credentials = FetchOptions::Credentials::Include;
     options.mode = FetchOptions::Mode::SameOrigin;
     options.contentSecurityPolicyEnforcement = ContentSecurityPolicyEnforcement::DoNotEnforce;
@@ -84,7 +84,9 @@
 
 void FetchLoader::start(ScriptExecutionContext& context, const FetchRequest& request)
 {
-    ThreadableLoaderOptions options(request.fetchOptions(), ConsiderPreflight,
+    ResourceLoaderOptions resourceLoaderOptions = request.fetchOptions();
+    resourceLoaderOptions.preflightPolicy = PreflightPolicy::Consider;
+    ThreadableLoaderOptions options(resourceLoaderOptions,
         context.shouldBypassMainWorldContentSecurityPolicy() ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceConnectSrcDirective,
         String(cachedResourceRequestInitiators().fetch),
         ResponseFilteringPolicy::Disable);
diff --git a/Source/WebCore/loader/DocumentThreadableLoader.cpp b/Source/WebCore/loader/DocumentThreadableLoader.cpp
index 240daa1..4e692e1 100644
--- a/Source/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/Source/WebCore/loader/DocumentThreadableLoader.cpp
@@ -109,7 +109,7 @@
 
     // No need to do preflight if the network stack will do it for us.
     if (!m_async && platformStrategies()->loaderStrategy()->isDoingLoadingSecurityChecks())
-        m_options.preflightPolicy = PreventPreflight;
+        m_options.preflightPolicy = PreflightPolicy::Prevent;
 
     // Referrer and Origin headers should be set after the preflight if any.
     ASSERT(!request.hasHTTPReferrer() && !request.hasHTTPOrigin());
@@ -134,6 +134,9 @@
         m_options.filteringPolicy = ResponseFilteringPolicy::Disable;
     }
 
+    if (m_contentSecurityPolicy || !document.shouldBypassMainWorldContentSecurityPolicy())
+        m_options.cspResponseHeaders = this->contentSecurityPolicy().responseHeaders();
+
     // As per step 11 of https://fetch.spec.whatwg.org/#main-fetch, data scheme (if same-origin data-URL flag is set) and about scheme are considered same-origin.
     if (request.url().protocolIsData())
         m_sameOriginRequest = options.sameOriginDataURLFlag == SameOriginDataURLFlag::Set;
@@ -155,7 +158,7 @@
 {
     ASSERT(m_options.mode == FetchOptions::Mode::Cors);
 
-    if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)
+    if ((m_options.preflightPolicy == PreflightPolicy::Consider && isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields())) || m_options.preflightPolicy == PreflightPolicy::Prevent)
         makeSimpleCrossOriginAccessRequest(WTFMove(request));
     else {
 #if ENABLE(SERVICE_WORKER)
@@ -179,8 +182,8 @@
 
 void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(ResourceRequest&& request)
 {
-    ASSERT(m_options.preflightPolicy != ForcePreflight);
-    ASSERT(m_options.preflightPolicy == PreventPreflight || isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()));
+    ASSERT(m_options.preflightPolicy != PreflightPolicy::Force);
+    ASSERT(m_options.preflightPolicy == PreflightPolicy::Prevent || isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()));
 
     // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
     if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol().toStringWithoutCopying())) {
diff --git a/Source/WebCore/loader/ResourceLoaderOptions.h b/Source/WebCore/loader/ResourceLoaderOptions.h
index 3d9a1a3..e792dde 100644
--- a/Source/WebCore/loader/ResourceLoaderOptions.h
+++ b/Source/WebCore/loader/ResourceLoaderOptions.h
@@ -30,6 +30,7 @@
 
 #pragma once
 
+#include "ContentSecurityPolicyResponseHeaders.h"
 #include "FetchOptions.h"
 #include "HTTPHeaderNames.h"
 #include "ServiceWorkerTypes.h"
@@ -111,6 +112,12 @@
     DoNotSniff,
 };
 
+enum class PreflightPolicy {
+    Consider,
+    Force,
+    Prevent
+};
+
 struct ResourceLoaderOptions : public FetchOptions {
     ResourceLoaderOptions() { }
 
@@ -158,6 +165,9 @@
     unsigned maxRedirectCount { 20 };
 
     Vector<String> derivedCachedDataTypesToRetrieve;
+
+    PreflightPolicy preflightPolicy { PreflightPolicy::Consider };
+    std::optional<ContentSecurityPolicyResponseHeaders> cspResponseHeaders;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/loader/SubresourceLoader.cpp b/Source/WebCore/loader/SubresourceLoader.cpp
index f7d24f2..2c3a1ee 100644
--- a/Source/WebCore/loader/SubresourceLoader.cpp
+++ b/Source/WebCore/loader/SubresourceLoader.cpp
@@ -784,4 +784,9 @@
     m_documentLoader->cachedResourceLoader().resourceTimingInformation().addResourceTiming(*m_resource, *document, WTFMove(resourceTiming));
 }
 
+const HTTPHeaderMap* SubresourceLoader::originalHeaders() const
+{
+    return (m_resource  && m_resource->originalRequest()) ? &m_resource->originalRequest()->httpHeaderFields() : nullptr;
+}
+
 }
diff --git a/Source/WebCore/loader/SubresourceLoader.h b/Source/WebCore/loader/SubresourceLoader.h
index 1959845..c673818 100644
--- a/Source/WebCore/loader/SubresourceLoader.h
+++ b/Source/WebCore/loader/SubresourceLoader.h
@@ -50,6 +50,7 @@
     void cancelIfNotFinishing();
     bool isSubresourceLoader() const override;
     CachedResource* cachedResource();
+    WEBCORE_EXPORT const HTTPHeaderMap* originalHeaders() const;
 
     SecurityOrigin* origin() { return m_origin.get(); }
 #if PLATFORM(IOS)
diff --git a/Source/WebCore/loader/ThreadableLoader.cpp b/Source/WebCore/loader/ThreadableLoader.cpp
index ef90eab..bc64ebb 100644
--- a/Source/WebCore/loader/ThreadableLoader.cpp
+++ b/Source/WebCore/loader/ThreadableLoader.cpp
@@ -54,9 +54,8 @@
 {
 }
 
-ThreadableLoaderOptions::ThreadableLoaderOptions(const ResourceLoaderOptions& baseOptions, PreflightPolicy preflightPolicy, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, String&& initiator, ResponseFilteringPolicy filteringPolicy)
+ThreadableLoaderOptions::ThreadableLoaderOptions(const ResourceLoaderOptions& baseOptions, ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement, String&& initiator, ResponseFilteringPolicy filteringPolicy)
     : ResourceLoaderOptions(baseOptions)
-    , preflightPolicy(preflightPolicy)
     , contentSecurityPolicyEnforcement(contentSecurityPolicyEnforcement)
     , initiator(WTFMove(initiator))
     , filteringPolicy(filteringPolicy)
@@ -93,9 +92,9 @@
     copy.derivedCachedDataTypesToRetrieve.reserveInitialCapacity(this->derivedCachedDataTypesToRetrieve.size());
     for (auto& derivedCachedDataType : this->derivedCachedDataTypesToRetrieve)
         copy.derivedCachedDataTypesToRetrieve.uncheckedAppend(derivedCachedDataType.isolatedCopy());
+    copy.preflightPolicy = this->preflightPolicy;
 
     // ThreadableLoaderOptions
-    copy.preflightPolicy = this->preflightPolicy;
     copy.contentSecurityPolicyEnforcement = this->contentSecurityPolicyEnforcement;
     copy.initiator = this->initiator.isolatedCopy();
     copy.filteringPolicy = this->filteringPolicy;
diff --git a/Source/WebCore/loader/ThreadableLoader.h b/Source/WebCore/loader/ThreadableLoader.h
index 421e39c..861748b 100644
--- a/Source/WebCore/loader/ThreadableLoader.h
+++ b/Source/WebCore/loader/ThreadableLoader.h
@@ -43,12 +43,6 @@
     class ScriptExecutionContext;
     class ThreadableLoaderClient;
 
-    enum PreflightPolicy {
-        ConsiderPreflight,
-        ForcePreflight,
-        PreventPreflight
-    };
-
     enum class ContentSecurityPolicyEnforcement {
         DoNotEnforce,
         EnforceChildSrcDirective,
@@ -64,12 +58,11 @@
     struct ThreadableLoaderOptions : ResourceLoaderOptions {
         ThreadableLoaderOptions();
         explicit ThreadableLoaderOptions(FetchOptions&&);
-        ThreadableLoaderOptions(const ResourceLoaderOptions&, PreflightPolicy, ContentSecurityPolicyEnforcement, String&& initiator, ResponseFilteringPolicy);
+        ThreadableLoaderOptions(const ResourceLoaderOptions&, ContentSecurityPolicyEnforcement, String&& initiator, ResponseFilteringPolicy);
         ~ThreadableLoaderOptions();
 
         ThreadableLoaderOptions isolatedCopy() const;
 
-        PreflightPolicy preflightPolicy { ConsiderPreflight };
         ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement { ContentSecurityPolicyEnforcement::EnforceConnectSrcDirective };
         String initiator; // This cannot be an AtomicString, as isolatedCopy() wouldn't create an object that's safe for passing to another thread.
         ResponseFilteringPolicy filteringPolicy { ResponseFilteringPolicy::Disable };
diff --git a/Source/WebCore/page/EventSource.cpp b/Source/WebCore/page/EventSource.cpp
index 6636252..f16ce5f 100644
--- a/Source/WebCore/page/EventSource.cpp
+++ b/Source/WebCore/page/EventSource.cpp
@@ -100,7 +100,7 @@
     ThreadableLoaderOptions options;
     options.sendLoadCallbacks = SendCallbacks;
     options.credentials = m_withCredentials ? FetchOptions::Credentials::Include : FetchOptions::Credentials::SameOrigin;
-    options.preflightPolicy = PreventPreflight;
+    options.preflightPolicy = PreflightPolicy::Prevent;
     options.mode = FetchOptions::Mode::Cors;
     options.cache = FetchOptions::Cache::NoStore;
     options.dataBufferingPolicy = DoNotBufferData;
diff --git a/Source/WebCore/xml/XMLHttpRequest.cpp b/Source/WebCore/xml/XMLHttpRequest.cpp
index 6c482d2..8cea223 100644
--- a/Source/WebCore/xml/XMLHttpRequest.cpp
+++ b/Source/WebCore/xml/XMLHttpRequest.cpp
@@ -583,7 +583,7 @@
     options.sendLoadCallbacks = SendCallbacks;
     // The presence of upload event listeners forces us to use preflighting because POSTing to an URL that does not
     // permit cross origin requests should look exactly like POSTing to an URL that does not respond at all.
-    options.preflightPolicy = m_uploadListenerFlag ? ForcePreflight : ConsiderPreflight;
+    options.preflightPolicy = m_uploadListenerFlag ? PreflightPolicy::Force : PreflightPolicy::Consider;
     options.credentials = m_includeCredentials ? FetchOptions::Credentials::Include : FetchOptions::Credentials::SameOrigin;
     options.mode = FetchOptions::Mode::Cors;
     options.contentSecurityPolicyEnforcement = scriptExecutionContext()->shouldBypassMainWorldContentSecurityPolicy() ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceConnectSrcDirective;
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index a98d966..447e037 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,34 @@
+2018-04-23  Youenn Fablet  <youenn@apple.com>
+
+        Make WebLoaderStrategy send to NetworkResourceLoader necessary parameters to handle full loads in NetworkProcess
+        https://bugs.webkit.org/show_bug.cgi?id=184763
+
+        Reviewed by Chris Dumez.
+
+        Set all required NetworkResourceLoadParameters for asynchronous loads.
+        This includes preflight policy, CSP response headers, SecurityOrigin and content blockers identifier.
+
+        Update NetworkLoadChecker to handle preflight policy.
+        This is not needed right now since sync XHR and ping loads are using the default ConsiderPreflight policy.
+        But this will be needed for XHR/fetch/EventSource loads. 
+
+        * NetworkProcess/NetworkLoadChecker.cpp:
+        (WebKit::NetworkLoadChecker::NetworkLoadChecker):
+        (WebKit::NetworkLoadChecker::checkRedirection):
+        (WebKit::NetworkLoadChecker::validateResponse):
+        (WebKit::NetworkLoadChecker::checkCORSRequest):
+        * NetworkProcess/NetworkLoadChecker.h:
+        (WebKit::NetworkLoadChecker::create):
+        * NetworkProcess/NetworkResourceLoadParameters.cpp:
+        (WebKit::NetworkResourceLoadParameters::encode const):
+        (WebKit::NetworkResourceLoadParameters::decode):
+        * NetworkProcess/NetworkResourceLoadParameters.h:
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        * NetworkProcess/PingLoad.cpp:
+        (WebKit::PingLoad::PingLoad):
+        * WebProcess/Network/WebLoaderStrategy.cpp:
+        (WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess):
+
 2018-04-23  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [Extra zoom mode] REGRESSION(230860) Unable to change time input values using UI
diff --git a/Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp b/Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp
index 62d05de..e6e14da 100644
--- a/Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp
@@ -41,12 +41,13 @@
 
 using namespace WebCore;
 
-NetworkLoadChecker::NetworkLoadChecker(WebCore::FetchOptions&& options, PAL::SessionID sessionID, WebCore::HTTPHeaderMap&& originalRequestHeaders, URL&& url, RefPtr<SecurityOrigin>&& sourceOrigin)
+NetworkLoadChecker::NetworkLoadChecker(WebCore::FetchOptions&& options, PAL::SessionID sessionID, WebCore::HTTPHeaderMap&& originalRequestHeaders, URL&& url, RefPtr<SecurityOrigin>&& sourceOrigin, PreflightPolicy preflightPolicy)
     : m_options(WTFMove(options))
     , m_sessionID(sessionID)
     , m_originalRequestHeaders(WTFMove(originalRequestHeaders))
     , m_url(WTFMove(url))
     , m_origin(WTFMove(sourceOrigin))
+    , m_preflightPolicy(preflightPolicy)
 {
     if (m_options.mode == FetchOptions::Mode::Cors || m_options.mode == FetchOptions::Mode::SameOrigin)
         m_isSameOriginRequest = m_url.protocolIsData() || m_url.protocolIsBlob() || m_origin->canRequest(m_url);
@@ -192,12 +193,21 @@
     ASSERT(m_options.mode == FetchOptions::Mode::Cors);
 
     // Except in case where preflight is needed, loading should be able to continue on its own.
-    if (m_isSimpleRequest && isSimpleCrossOriginAccessRequest(request.httpMethod(), m_originalRequestHeaders)) {
+    switch (m_preflightPolicy) {
+    case PreflightPolicy::Force:
+        checkCORSRequestWithPreflight(WTFMove(request), WTFMove(handler));
+        break;
+    case PreflightPolicy::Consider:
+        if (!m_isSimpleRequest || !isSimpleCrossOriginAccessRequest(request.httpMethod(), m_originalRequestHeaders)) {
+            checkCORSRequestWithPreflight(WTFMove(request), WTFMove(handler));
+            return;
+        }
+        FALLTHROUGH;
+    case PreflightPolicy::Prevent:
         updateRequestForAccessControl(request, *m_origin, m_storedCredentialsPolicy);
         handler(WTFMove(request));
-        return;
+        break;
     }
-    checkCORSRequestWithPreflight(WTFMove(request), WTFMove(handler));
 }
 
 void NetworkLoadChecker::checkCORSRedirectedRequest(ResourceRequest&& request, ValidationHandler&& handler)
diff --git a/Source/WebKit/NetworkProcess/NetworkLoadChecker.h b/Source/WebKit/NetworkProcess/NetworkLoadChecker.h
index 5fac363..f4b907d 100644
--- a/Source/WebKit/NetworkProcess/NetworkLoadChecker.h
+++ b/Source/WebKit/NetworkProcess/NetworkLoadChecker.h
@@ -42,9 +42,9 @@
 
 class NetworkLoadChecker : public RefCounted<NetworkLoadChecker> {
 public:
-    static Ref<NetworkLoadChecker> create(WebCore::FetchOptions&& options, PAL::SessionID sessionID, WebCore::HTTPHeaderMap&& originalHeaders, WebCore::URL&& url, RefPtr<WebCore::SecurityOrigin>&& sourceOrigin)
+    static Ref<NetworkLoadChecker> create(WebCore::FetchOptions&& options, PAL::SessionID sessionID, WebCore::HTTPHeaderMap&& originalHeaders, WebCore::URL&& url, RefPtr<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::PreflightPolicy preflightPolicy)
     {
-        return adoptRef(*new NetworkLoadChecker { WTFMove(options), sessionID, WTFMove(originalHeaders), WTFMove(url), WTFMove(sourceOrigin) });
+        return adoptRef(*new NetworkLoadChecker { WTFMove(options), sessionID, WTFMove(originalHeaders), WTFMove(url), WTFMove(sourceOrigin), preflightPolicy });
     }
     ~NetworkLoadChecker();
 
@@ -68,7 +68,7 @@
     WebCore::StoredCredentialsPolicy storedCredentialsPolicy() const { return m_storedCredentialsPolicy; }
 
 private:
-    NetworkLoadChecker(WebCore::FetchOptions&&, PAL::SessionID, WebCore::HTTPHeaderMap&&, WebCore::URL&&, RefPtr<WebCore::SecurityOrigin>&&);
+    NetworkLoadChecker(WebCore::FetchOptions&&, PAL::SessionID, WebCore::HTTPHeaderMap&&, WebCore::URL&&, RefPtr<WebCore::SecurityOrigin>&&, WebCore::PreflightPolicy);
 
     WebCore::ContentSecurityPolicy* contentSecurityPolicy() const;
     bool isChecking() const { return !!m_corsPreflightChecker; }
@@ -108,6 +108,7 @@
     mutable std::unique_ptr<WebCore::ContentSecurityPolicy> m_contentSecurityPolicy;
     size_t m_redirectCount { 0 };
     WebCore::URL m_previousURL;
+    WebCore::PreflightPolicy m_preflightPolicy;
 };
 
 }
diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp
index 79c827c..6f57a04 100644
--- a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp
@@ -92,12 +92,14 @@
     encoder << cspResponseHeaders;
     encoder << originalRequestHeaders;
 
+    encoder << shouldRestrictHTTPResponseAccess;
+
+    encoder.encodeEnum(preflightPolicy);
+
 #if ENABLE(CONTENT_EXTENSIONS)
     encoder << mainDocumentURL;
     encoder << userContentControllerIdentifier;
 #endif
-
-    encoder << shouldRestrictHTTPResponseAccess;
 }
 
 bool NetworkResourceLoadParameters::decode(IPC::Decoder& decoder, NetworkResourceLoadParameters& result)
@@ -187,6 +189,15 @@
     if (!decoder.decode(result.originalRequestHeaders))
         return false;
 
+    std::optional<bool> shouldRestrictHTTPResponseAccess;
+    decoder >> shouldRestrictHTTPResponseAccess;
+    if (!shouldRestrictHTTPResponseAccess)
+        return false;
+    result.shouldRestrictHTTPResponseAccess = *shouldRestrictHTTPResponseAccess;
+
+    if (!decoder.decodeEnum(result.preflightPolicy))
+        return false;
+
 #if ENABLE(CONTENT_EXTENSIONS)
     if (!decoder.decode(result.mainDocumentURL))
         return false;
@@ -198,12 +209,6 @@
     result.userContentControllerIdentifier = *userContentControllerIdentifier;
 #endif
 
-    std::optional<bool> shouldRestrictHTTPResponseAccess;
-    decoder >> shouldRestrictHTTPResponseAccess;
-    if (!shouldRestrictHTTPResponseAccess)
-        return false;
-    result.shouldRestrictHTTPResponseAccess = *shouldRestrictHTTPResponseAccess;
-
     return true;
 }
     
diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h
index 74290ce..e5e99d5 100644
--- a/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h
+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h
@@ -60,6 +60,7 @@
     std::optional<WebCore::ContentSecurityPolicyResponseHeaders> cspResponseHeaders;
     WebCore::HTTPHeaderMap originalRequestHeaders;
     bool shouldRestrictHTTPResponseAccess { false };
+    WebCore::PreflightPolicy preflightPolicy { WebCore::PreflightPolicy::Consider };
 
 #if ENABLE(CONTENT_EXTENSIONS)
     WebCore::URL mainDocumentURL;
diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
index b370036..40d119a 100644
--- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
@@ -127,7 +127,7 @@
     }
 
     if (shouldUseNetworkLoadChecker(!!synchronousReply, m_parameters)) {
-        m_networkLoadChecker = NetworkLoadChecker::create(FetchOptions { m_parameters.options }, m_parameters.sessionID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef());
+        m_networkLoadChecker = NetworkLoadChecker::create(FetchOptions { m_parameters.options }, m_parameters.sessionID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy);
         if (m_parameters.cspResponseHeaders)
             m_networkLoadChecker->setCSPResponseHeaders(ContentSecurityPolicyResponseHeaders { m_parameters.cspResponseHeaders.value() });
 #if ENABLE(CONTENT_EXTENSIONS)
diff --git a/Source/WebKit/NetworkProcess/PingLoad.cpp b/Source/WebKit/NetworkProcess/PingLoad.cpp
index 3efbadb..d8ca72a 100644
--- a/Source/WebKit/NetworkProcess/PingLoad.cpp
+++ b/Source/WebKit/NetworkProcess/PingLoad.cpp
@@ -42,7 +42,7 @@
     : m_parameters(WTFMove(parameters))
     , m_completionHandler(WTFMove(completionHandler))
     , m_timeoutTimer(*this, &PingLoad::timeoutTimerFired)
-    , m_networkLoadChecker(NetworkLoadChecker::create(FetchOptions { m_parameters.options}, m_parameters.sessionID, WTFMove(m_parameters.originalRequestHeaders), URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef()))
+    , m_networkLoadChecker(NetworkLoadChecker::create(FetchOptions { m_parameters.options}, m_parameters.sessionID, WTFMove(m_parameters.originalRequestHeaders), URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy))
 {
 
     if (m_parameters.cspResponseHeaders)
diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
index bbbabc6..0d475b7 100644
--- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
+++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
@@ -274,6 +274,32 @@
     loadParameters.maximumBufferingTime = maximumBufferingTime;
     loadParameters.derivedCachedDataTypesToRetrieve = resourceLoader.options().derivedCachedDataTypesToRetrieve;
     loadParameters.options = resourceLoader.options();
+    loadParameters.preflightPolicy = resourceLoader.options().preflightPolicy;
+
+    auto* document = resourceLoader.frame() ? resourceLoader.frame()->document() : nullptr;
+    if (resourceLoader.options().cspResponseHeaders)
+        loadParameters.cspResponseHeaders = resourceLoader.options().cspResponseHeaders;
+    else if (document && !document->shouldBypassMainWorldContentSecurityPolicy()) {
+        if (auto* contentSecurityPolicy = document->contentSecurityPolicy())
+            loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders();
+    }
+
+    if (resourceLoader.isSubresourceLoader()) {
+        if (auto* headers = static_cast<SubresourceLoader&>(resourceLoader).originalHeaders())
+            loadParameters.originalRequestHeaders = *headers;
+    }
+
+#if ENABLE(CONTENT_EXTENSIONS)
+    if (document) {
+        loadParameters.mainDocumentURL = document->topDocument().url();
+        // FIXME: Instead of passing userContentControllerIdentifier, the NetworkProcess should be able to get it using webPageId.
+        auto* webFrameLoaderClient = toWebFrameLoaderClient(resourceLoader.frame()->loader().client());
+        auto* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr;
+        auto* webPage = webFrame ? webFrame->page() : nullptr;
+        if (webPage)
+            loadParameters.userContentControllerIdentifier = webPage->userContentControllerIdentifier();
+    }
+#endif
 
     if (loadParameters.options.mode != FetchOptions::Mode::Navigate) {
         // FIXME: All loaders should provide their origin if navigation mode is cors/no-cors/same-origin.