[Fetch API] Response should keep all ResourceResponse information
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Aug 2017 22:11:28 +0000 (22:11 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Aug 2017 22:11:28 +0000 (22:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175099

Patch by Youenn Fablet <youenn@apple.com> on 2017-08-05
Reviewed by Sam Weinig.

Source/WebCore:

No change of behavior, covered by existing tests.

Disabling filtering of resource response at DocumentThreadableLoader for fetch API and doing the filtering at FetchResponse level.
This requires passing the tainting parameter to FetchResponse. For that purpose, we store the tainting on the ResourceResponse itself.
This allows mimicking the concept of internal response from the fetch spec.
This might be useful for future developments related to caching the responses.

The body is now also stored in FetchResponse so a flag is added to ensure we only expose the body if allowed.

Changing storage of opaque redirect information to keep the redirection information in the response.

* Modules/fetch/FetchBodyOwner.cpp:
(WebCore::FetchBodyOwner::blob):
(WebCore::FetchBodyOwner::consumeNullBody):
* Modules/fetch/FetchBodyOwner.h:
* Modules/fetch/FetchLoader.cpp:
(WebCore::FetchLoader::start):
* Modules/fetch/FetchResponse.cpp:
(WebCore::FetchResponse::BodyLoader::didReceiveResponse):
(WebCore::FetchResponse::consume):
(WebCore::FetchResponse::consumeBodyAsStream):
(WebCore::FetchResponse::createReadableStreamSource):
* Modules/fetch/FetchResponse.h:
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::responseReceived):
(WebCore::DocumentThreadableLoader::didReceiveResponse):
(WebCore::DocumentThreadableLoader::didFinishLoading):
(WebCore::DocumentThreadableLoader::loadRequest):
* loader/DocumentThreadableLoader.h:
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::willSendRequestInternal):
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::setBodyDataFrom):
(WebCore::CachedResource::setResponse):
* platform/network/ResourceResponseBase.cpp:
(WebCore::ResourceResponseBase::crossThreadData const):
(WebCore::ResourceResponseBase::fromCrossThreadData):
(WebCore::ResourceResponseBase::filter):
* platform/network/ResourceResponseBase.h:
(WebCore::ResourceResponseBase::setTainting):
(WebCore::ResourceResponseBase::tainting const):
(WebCore::ResourceResponseBase::encode const):
(WebCore::ResourceResponseBase::decode):

LayoutTests:

Updating test now that we are no longer cancelling the load in case of opaque responses.

* http/tests/inspector/network/fetch-network-data-expected.txt:
* http/tests/inspector/network/fetch-network-data.html:

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/inspector/network/fetch-network-data-expected.txt
LayoutTests/http/tests/inspector/network/fetch-network-data.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/fetch/FetchBodyOwner.cpp
Source/WebCore/Modules/fetch/FetchBodyOwner.h
Source/WebCore/Modules/fetch/FetchLoader.cpp
Source/WebCore/Modules/fetch/FetchResponse.cpp
Source/WebCore/Modules/fetch/FetchResponse.h
Source/WebCore/loader/DocumentThreadableLoader.cpp
Source/WebCore/loader/DocumentThreadableLoader.h
Source/WebCore/loader/SubresourceLoader.cpp
Source/WebCore/loader/cache/CachedResource.cpp
Source/WebCore/platform/network/ResourceResponseBase.cpp
Source/WebCore/platform/network/ResourceResponseBase.h

index 0f77c31d0038a0a6db28164477392bb3e101e6b5..4907a1d310d62b304be552438e23f73c241da440 100644 (file)
@@ -1,3 +1,15 @@
+2017-08-05  Youenn Fablet  <youenn@apple.com>
+
+        [Fetch API] Response should keep all ResourceResponse information
+        https://bugs.webkit.org/show_bug.cgi?id=175099
+
+        Reviewed by Sam Weinig.
+
+        Updating test now that we are no longer cancelling the load in case of opaque responses.
+
+        * http/tests/inspector/network/fetch-network-data-expected.txt:
+        * http/tests/inspector/network/fetch-network-data.html:
+
 2017-08-05  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         getClientRects doesn't work with list box option elements
index b8fcd13192ce00d58a3a92f233813c304d683f51..fb6ea1707aa805ffe07ae15dee9299a0536d6791 100644 (file)
@@ -12,9 +12,10 @@ PASS: Should be able to see X-Custom-Header.
 
 -- Running test case: Network.Fetch.ModeNoCORS.CrossOrigin
 PASS: Resource should be Fetch type.
-PASS: Resource should have failed to load.
-PASS: Load should have failed.
-PASS: Load should have canceled.
+PASS: Resource should have loaded successfully.
+PASS: MIMEType should be 'application/json'.
+PASS: Status code should be 200.
+PASS: Should be able to see X-Custom-Header.
 
 -- Running test case: Network.Fetch.ModeCORS.SameOrigin
 PASS: Resource should be Fetch type.
index e3bc95b30f7ecd287681531ba9da5b59ffe7282d..5982409cb290ee725b6056ff93e737d722d6c19e 100644 (file)
@@ -52,9 +52,10 @@ function test()
         name: "Network.Fetch.ModeNoCORS.CrossOrigin",
         description: "Same Origin 'no-cors' fetch => type 'opaque'. Produces an opaque failure.",
         expression: `fetch("http://localhost:8000/inspector/network/resources/cors-data.pl", {mode: "no-cors"})`,
-        failedHandler(resource) {
-            InspectorTest.expectThat(resource.failed, "Load should have failed.");
-            InspectorTest.expectThat(resource.canceled, "Load should have canceled.");
+        loadedHandler(resource) {
+            InspectorTest.expectEqual(resource.mimeType, "application/json", "MIMEType should be 'application/json'.");
+            InspectorTest.expectEqual(resource.statusCode, 200, "Status code should be 200.");
+            InspectorTest.expectEqual(resource.responseHeaders["X-Custom-Header"], "Custom-Header-Value", "Should be able to see X-Custom-Header.");
         }
     });
 
index dbb97bcf4f05ee64e53ac7102871a1480fee3c8f..579e4d02b849e8befa738043c268610b930e3e98 100644 (file)
@@ -1,3 +1,54 @@
+2017-08-05  Youenn Fablet  <youenn@apple.com>
+
+        [Fetch API] Response should keep all ResourceResponse information
+        https://bugs.webkit.org/show_bug.cgi?id=175099
+
+        Reviewed by Sam Weinig.
+
+        No change of behavior, covered by existing tests.
+
+        Disabling filtering of resource response at DocumentThreadableLoader for fetch API and doing the filtering at FetchResponse level.
+        This requires passing the tainting parameter to FetchResponse. For that purpose, we store the tainting on the ResourceResponse itself.
+        This allows mimicking the concept of internal response from the fetch spec.
+        This might be useful for future developments related to caching the responses.
+
+        The body is now also stored in FetchResponse so a flag is added to ensure we only expose the body if allowed.
+
+        Changing storage of opaque redirect information to keep the redirection information in the response.
+
+        * Modules/fetch/FetchBodyOwner.cpp:
+        (WebCore::FetchBodyOwner::blob):
+        (WebCore::FetchBodyOwner::consumeNullBody):
+        * Modules/fetch/FetchBodyOwner.h:
+        * Modules/fetch/FetchLoader.cpp:
+        (WebCore::FetchLoader::start):
+        * Modules/fetch/FetchResponse.cpp:
+        (WebCore::FetchResponse::BodyLoader::didReceiveResponse):
+        (WebCore::FetchResponse::consume):
+        (WebCore::FetchResponse::consumeBodyAsStream):
+        (WebCore::FetchResponse::createReadableStreamSource):
+        * Modules/fetch/FetchResponse.h:
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::responseReceived):
+        (WebCore::DocumentThreadableLoader::didReceiveResponse):
+        (WebCore::DocumentThreadableLoader::didFinishLoading):
+        (WebCore::DocumentThreadableLoader::loadRequest):
+        * loader/DocumentThreadableLoader.h:
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::willSendRequestInternal):
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::setBodyDataFrom):
+        (WebCore::CachedResource::setResponse):
+        * platform/network/ResourceResponseBase.cpp:
+        (WebCore::ResourceResponseBase::crossThreadData const):
+        (WebCore::ResourceResponseBase::fromCrossThreadData):
+        (WebCore::ResourceResponseBase::filter):
+        * platform/network/ResourceResponseBase.h:
+        (WebCore::ResourceResponseBase::setTainting):
+        (WebCore::ResourceResponseBase::tainting const):
+        (WebCore::ResourceResponseBase::encode const):
+        (WebCore::ResourceResponseBase::decode):
+
 2017-08-05  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         WebDriver: use in-view center point for clicks instead of bounding box center point
index 1f5d7753866da424540fbce31ce1a8166d3753ef..37d30f8c577dc0b1157f0421fd3e634006178247 100644 (file)
@@ -88,7 +88,7 @@ void FetchBodyOwner::arrayBuffer(Ref<DeferredPromise>&& promise)
 void FetchBodyOwner::blob(Ref<DeferredPromise>&& promise)
 {
     if (isBodyNull()) {
-        promise->resolve<IDLInterface<Blob>>(Blob::create({ }, Blob::normalizedContentType(extractMIMETypeFromMediaType(m_contentType))).get());
+        promise->resolve<IDLInterface<Blob>>(Blob::create({ }, Blob::normalizedContentType(extractMIMETypeFromMediaType(m_contentType))));
         return;
     }
     if (isDisturbedOrLocked()) {
@@ -133,6 +133,27 @@ void FetchBodyOwner::consumeOnceLoadingFinished(FetchBodyConsumer::Type type, Re
     m_body->consumeOnceLoadingFinished(type, WTFMove(promise), m_contentType);
 }
 
+void FetchBodyOwner::consumeNullBody(FetchBodyConsumer::Type consumerType, Ref<DeferredPromise>&& promise)
+{
+    switch (consumerType) {
+    case FetchBodyConsumer::Type::ArrayBuffer:
+        fulfillPromiseWithArrayBuffer(WTFMove(promise), nullptr, 0);
+        return;
+    case FetchBodyConsumer::Type::Blob:
+        promise->resolve<IDLInterface<Blob>>(Blob::create({ }, String()));
+        return;
+    case FetchBodyConsumer::Type::JSON:
+        promise->reject(SyntaxError);
+        return;
+    case FetchBodyConsumer::Type::Text:
+        promise->resolve<IDLDOMString>({ });
+        return;
+    case FetchBodyConsumer::Type::None:
+        ASSERT_NOT_REACHED();
+        return;
+    }
+}
+
 void FetchBodyOwner::formData(Ref<DeferredPromise>&& promise)
 {
     if (isBodyNull()) {
index 5b631d707673a173c6b8f1eccd379473adff8584..c3213e972139300d4a51854c0559ab55014a955b 100644 (file)
@@ -66,6 +66,7 @@ protected:
     void extractBody(ScriptExecutionContext&, FetchBody::Init&&);
     void updateContentType();
     void consumeOnceLoadingFinished(FetchBodyConsumer::Type, Ref<DeferredPromise>&&);
+    void consumeNullBody(FetchBodyConsumer::Type, Ref<DeferredPromise>&&);
 
     void setBody(FetchBody&& body) { m_body = WTFMove(body); }
 
index fbebeb74c0a866076b357af51d74f9ddb516bec9..e3a51f1ae84392bf30fc8b5d33531a09db85ccac 100644 (file)
@@ -75,7 +75,7 @@ void FetchLoader::start(ScriptExecutionContext& context, const FetchRequest& req
     ThreadableLoaderOptions options(request.fetchOptions(), ConsiderPreflight,
         context.shouldBypassMainWorldContentSecurityPolicy() ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceConnectSrcDirective,
         String(cachedResourceRequestInitiators().fetch),
-        ResponseFilteringPolicy::Enable);
+        ResponseFilteringPolicy::Disable);
     options.sendLoadCallbacks = SendCallbacks;
     options.dataBufferingPolicy = DoNotBufferData;
     options.sameOriginDataURLFlag = SameOriginDataURLFlag::Set;
index 8d9d6a65dd28868cd299a767713af09649e698f9..68adb559fe9530f7456dc96f9884b7ffdd6a81be 100644 (file)
@@ -175,8 +175,10 @@ void FetchResponse::BodyLoader::didReceiveResponse(const ResourceResponse& resou
 {
     ASSERT(m_promise);
 
-    m_response.m_response = resourceResponse;
-    m_response.m_headers->filterAndFill(resourceResponse.httpHeaderFields(), FetchHeaders::Guard::Response);
+    m_response.m_response = ResourceResponseBase::filter(resourceResponse);
+    m_response.m_shouldExposeBody = resourceResponse.tainting() != ResourceResponse::Tainting::Opaque;
+
+    m_response.m_headers->filterAndFill(m_response.m_response.httpHeaderFields(), FetchHeaders::Guard::Response);
     m_response.updateContentType();
 
     std::exchange(m_promise, std::nullopt)->resolve(m_response);
@@ -227,6 +229,11 @@ void FetchResponse::consume(unsigned type, Ref<DeferredPromise>&& wrapper)
     ASSERT(type <= static_cast<unsigned>(FetchBodyConsumer::Type::Text));
     auto consumerType = static_cast<FetchBodyConsumer::Type>(type);
 
+    if (!m_shouldExposeBody) {
+        consumeNullBody(consumerType, WTFMove(wrapper));
+        return;
+    }
+
     if (isLoading()) {
         consumeOnceLoadingFinished(consumerType, WTFMove(wrapper));
         return;
@@ -273,6 +280,7 @@ void FetchResponse::finishConsumingStream(Ref<DeferredPromise>&& promise)
 
 void FetchResponse::consumeBodyAsStream()
 {
+    ASSERT(m_shouldExposeBody);
     ASSERT(m_readableStreamSource);
     m_isDisturbed = true;
     if (!isLoading()) {
@@ -326,7 +334,7 @@ ReadableStreamSource* FetchResponse::createReadableStreamSource()
     ASSERT(!m_readableStreamSource);
     ASSERT(!m_isDisturbed);
 
-    if (isBodyNull())
+    if (isBodyNull() || !m_shouldExposeBody)
         return nullptr;
 
     m_readableStreamSource = adoptRef(*new FetchResponseSource(*this));
index bf0b3354ebdd711fc843a36783a5109dcbb432c5..f9b02fb0e587ab4eb3d559794b391f79f5a1dc66 100644 (file)
@@ -130,6 +130,7 @@ private:
     ResourceResponse m_response;
     std::optional<BodyLoader> m_bodyLoader;
     mutable String m_responseURL;
+    bool m_shouldExposeBody { true };
 
     FetchBodyConsumer m_consumer { FetchBodyConsumer::Type::ArrayBuffer  };
 };
index 34997fc691cb983ec7d0bc5c3058370008011086..7ee60beafdc250638282a7c87eba4cc73acc882b 100644 (file)
@@ -290,10 +290,10 @@ void DocumentThreadableLoader::dataSent(CachedResource& resource, unsigned long
 void DocumentThreadableLoader::responseReceived(CachedResource& resource, const ResourceResponse& response)
 {
     ASSERT_UNUSED(resource, &resource == m_resource);
-    didReceiveResponse(m_resource->identifier(), response, m_resource->responseTainting());
+    didReceiveResponse(m_resource->identifier(), response);
 }
 
-void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, ResourceResponse::Tainting tainting)
+void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
 {
     ASSERT(m_client);
     ASSERT(response.type() != ResourceResponse::Type::Error);
@@ -309,8 +309,8 @@ void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, cons
     }
 
     if (response.type() == ResourceResponse::Type::Default) {
-        m_client->didReceiveResponse(identifier, ResourceResponse::filterResponse(response, tainting));
-        if (tainting == ResourceResponse::Tainting::Opaque) {
+        m_client->didReceiveResponse(identifier, ResourceResponseBase::filter(response));
+        if (response.tainting() == ResourceResponse::Tainting::Opaque) {
             clearResource();
             if (m_client)
                 m_client->didFinishLoading(identifier);
@@ -380,9 +380,8 @@ void DocumentThreadableLoader::didFinishLoading(unsigned long identifier)
             m_client->didReceiveData(m_resource->resourceBuffer()->data(), m_resource->resourceBuffer()->size());
         } else {
             ASSERT(response.type() == ResourceResponse::Type::Default);
-            
-            auto tainting = m_resource->responseTainting();
-            m_client->didReceiveResponse(identifier, ResourceResponse::filterResponse(response, tainting));
+
+            m_client->didReceiveResponse(identifier, ResourceResponseBase::filter(response));
             m_client->didReceiveData(m_resource->resourceBuffer()->data(), m_resource->resourceBuffer()->size());
         }
     }
@@ -486,7 +485,7 @@ void DocumentThreadableLoader::loadRequest(ResourceRequest&& request, SecurityCh
         if (requestURL.isLocalFile()) {
             // We don't want XMLHttpRequest to raise an exception for file:// resources, see <rdar://problem/4962298>.
             // FIXME: XMLHttpRequest quirks should be in XMLHttpRequest code, not in DocumentThreadableLoader.cpp.
-            didReceiveResponse(identifier, response, ResourceResponse::Tainting::Basic);
+            didReceiveResponse(identifier, response);
             didFinishLoading(identifier);
             return;
         }
@@ -509,13 +508,12 @@ void DocumentThreadableLoader::loadRequest(ResourceRequest&& request, SecurityCh
         }
     }
 
-    ResourceResponse::Tainting tainting = ResourceResponse::Tainting::Basic;
     if (!m_sameOriginRequest) {
         if (m_options.mode == FetchOptions::Mode::NoCors)
-            tainting = ResourceResponse::Tainting::Opaque;
+            response.setTainting(ResourceResponse::Tainting::Opaque);
         else {
             ASSERT(m_options.mode == FetchOptions::Mode::Cors);
-            tainting = ResourceResponse::Tainting::Cors;
+            response.setTainting(ResourceResponse::Tainting::Cors);
             String accessControlErrorDescription;
             if (!passesAccessControlCheck(response, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)) {
                 logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, response.url(), accessControlErrorDescription, ResourceError::Type::AccessControl));
@@ -523,7 +521,7 @@ void DocumentThreadableLoader::loadRequest(ResourceRequest&& request, SecurityCh
             }
         }
     }
-    didReceiveResponse(identifier, response, tainting);
+    didReceiveResponse(identifier, response);
 
     if (data)
         didReceiveData(identifier, data->data(), data->size());
index 3794b7940f201de0f0875acb0665c1bb7cbc8dea..e340dcb68dc9acea9b3e458ec1253d097f9450e4 100644 (file)
@@ -88,7 +88,7 @@ namespace WebCore {
         void finishedTimingForWorkerLoad(const ResourceTiming&);
         void notifyFinished(CachedResource&) override;
 
-        void didReceiveResponse(unsigned long identifier, const ResourceResponse&, ResourceResponse::Tainting);
+        void didReceiveResponse(unsigned long identifier, const ResourceResponse&);
         void didReceiveData(unsigned long identifier, const char* data, int dataLength);
         void didFinishLoading(unsigned long identifier);
         void didFail(unsigned long identifier, const ResourceError&);
index 8910fab16dedffbdf6c48c74e120025470d44089..675259c9e6a69d95ec0013576cdc228dde92209b 100644 (file)
@@ -187,10 +187,11 @@ void SubresourceLoader::willSendRequestInternal(ResourceRequest& newRequest, con
                 return;
             }
 
-            ResourceResponse opaqueRedirectedResponse;
-            opaqueRedirectedResponse.setURL(redirectResponse.url());
+            ResourceResponse opaqueRedirectedResponse = redirectResponse;
             opaqueRedirectedResponse.setType(ResourceResponse::Type::Opaqueredirect);
+            opaqueRedirectedResponse.setTainting(ResourceResponse::Tainting::Opaqueredirect);
             m_resource->responseReceived(opaqueRedirectedResponse);
+
             NetworkLoadMetrics emptyMetrics;
             didFinishLoading(emptyMetrics);
             return;
index 4b442f658bda966976e8ea7ec8878ff0aedfd7dc..5fff7a9649bd26dbe1506c29bad88b0f6d5d34cf 100644 (file)
@@ -299,6 +299,7 @@ void CachedResource::setBodyDataFrom(const CachedResource& resource)
 {
     m_data = resource.m_data;
     m_response = resource.m_response;
+    m_response.setTainting(m_responseTainting);
     setDecodedSize(resource.decodedSize());
     setEncodedSize(resource.encodedSize());
 }
@@ -436,6 +437,8 @@ void CachedResource::setResponse(const ResourceResponse& response)
     ASSERT(m_response.type() == ResourceResponse::Type::Default);
     m_response = response;
     m_response.setRedirected(m_redirectChainCacheStatus.status != RedirectChainCacheStatus::NoRedirection);
+    if (m_response.tainting() == ResourceResponse::Tainting::Basic || m_response.tainting() == ResourceResponse::Tainting::Cors)
+        m_response.setTainting(m_responseTainting);
 
     m_varyingHeaderValues = collectVaryingRequestHeaders(m_resourceRequest, m_response, m_sessionID);
 }
index 8b6f7f436fe51e419b85578d5c219c43854f92f8..8d88d38b7acbb4128ec5f78cf07e3da631eda50f 100644 (file)
@@ -82,6 +82,7 @@ ResourceResponseBase::CrossThreadData ResourceResponseBase::crossThreadData() co
     data.httpHeaderFields = httpHeaderFields().isolatedCopy();
     data.networkLoadMetrics = m_networkLoadMetrics.isolatedCopy();
     data.type = m_type;
+    data.tainting = m_tainting;
     data.isRedirected = m_isRedirected;
 
     return data;
@@ -103,16 +104,26 @@ ResourceResponse ResourceResponseBase::fromCrossThreadData(CrossThreadData&& dat
     response.m_httpHeaderFields = WTFMove(data.httpHeaderFields);
     response.m_networkLoadMetrics = data.networkLoadMetrics;
     response.m_type = data.type;
+    response.m_tainting = data.tainting;
     response.m_isRedirected = data.isRedirected;
 
     return response;
 }
 
-ResourceResponse ResourceResponseBase::filterResponse(const ResourceResponse& response, ResourceResponse::Tainting tainting)
+ResourceResponse ResourceResponseBase::filter(const ResourceResponse& response)
 {
-    if (tainting == ResourceResponse::Tainting::Opaque) {
+    if (response.tainting() == Tainting::Opaque) {
         ResourceResponse opaqueResponse;
-        opaqueResponse.setType(ResourceResponse::Type::Opaque);
+        opaqueResponse.setTainting(Tainting::Opaque);
+        opaqueResponse.setType(Type::Opaque);
+        return opaqueResponse;
+    }
+
+    if (response.tainting() == Tainting::Opaqueredirect) {
+        ResourceResponse opaqueResponse;
+        opaqueResponse.setTainting(Tainting::Opaqueredirect);
+        opaqueResponse.setType(Type::Opaqueredirect);
+        opaqueResponse.setURL(response.url());
         return opaqueResponse;
     }
 
@@ -120,15 +131,15 @@ ResourceResponse ResourceResponseBase::filterResponse(const ResourceResponse& re
     // Let's initialize filteredResponse to remove some header fields.
     filteredResponse.lazyInit(AllFields);
 
-    if (tainting == ResourceResponse::Tainting::Basic) {
-        filteredResponse.setType(ResourceResponse::Type::Basic);
+    if (response.tainting() == Tainting::Basic) {
+        filteredResponse.setType(Type::Basic);
         filteredResponse.m_httpHeaderFields.remove(HTTPHeaderName::SetCookie);
         filteredResponse.m_httpHeaderFields.remove(HTTPHeaderName::SetCookie2);
         return filteredResponse;
     }
 
-    ASSERT(tainting == ResourceResponse::Tainting::Cors);
-    filteredResponse.setType(ResourceResponse::Type::Cors);
+    ASSERT(response.tainting() == Tainting::Cors);
+    filteredResponse.setType(Type::Cors);
 
     HTTPHeaderSet accessControlExposeHeaderSet;
     parseAccessControlExposeHeadersAllowList(response.httpHeaderField(HTTPHeaderName::AccessControlExposeHeaders), accessControlExposeHeaderSet);
index e15eb213c712eaafc8dfa13fceedd1e537ca865e..c3d9eca9930b466d1f8105dfe8a65516b2790902 100644 (file)
@@ -44,7 +44,8 @@ bool isScriptAllowedByNosniff(const ResourceResponse&);
 class ResourceResponseBase {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    enum class Type;
+    enum class Type { Basic, Cors, Default, Error, Opaque, Opaqueredirect };
+    enum class Tainting { Basic, Cors, Opaque, Opaqueredirect };
 
     struct CrossThreadData {
         CrossThreadData(const CrossThreadData&) = delete;
@@ -62,15 +63,13 @@ public:
         HTTPHeaderMap httpHeaderFields;
         NetworkLoadMetrics networkLoadMetrics;
         Type type;
+        Tainting tainting;
         bool isRedirected;
     };
 
     CrossThreadData crossThreadData() const;
     static ResourceResponse fromCrossThreadData(CrossThreadData&&);
 
-    enum class Tainting { Basic, Cors, Opaque };
-    static ResourceResponse filterResponse(const ResourceResponse&, Tainting);
-
     bool isNull() const { return m_isNull; }
     WEBCORE_EXPORT bool isHTTP() const;
     bool isSuccessful() const;
@@ -154,12 +153,16 @@ public:
         return 1280;
     }
 
-    enum class Type { Basic, Cors, Default, Error, Opaque, Opaqueredirect };
     Type type() const { return m_type; }
     void setType(Type type) { m_type = type; }
     bool isRedirected() const { return m_isRedirected; }
     void setRedirected(bool isRedirected) { m_isRedirected = isRedirected; }
 
+    void setTainting(Tainting tainting) { m_tainting = tainting; }
+    Tainting tainting() const { return m_tainting; }
+
+    static ResourceResponse filter(const ResourceResponse&);
+
     static bool compare(const ResourceResponse&, const ResourceResponse&);
 
     template<class Encoder> void encode(Encoder&) const;
@@ -224,6 +227,7 @@ private:
 
     Type m_type { Type::Default };
     bool m_isRedirected { false };
+    Tainting m_tainting { Tainting::Basic };
 };
 
 inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); }
@@ -255,6 +259,7 @@ void ResourceResponseBase::encode(Encoder& encoder) const
     encoder.encodeEnum(m_source);
     encoder << m_cacheBodyKey;
     encoder.encodeEnum(m_type);
+    encoder.encodeEnum(m_tainting);
     encoder << m_isRedirected;
 }
 
@@ -297,6 +302,8 @@ bool ResourceResponseBase::decode(Decoder& decoder, ResourceResponseBase& respon
         return false;
     if (!decoder.decodeEnum(response.m_type))
         return false;
+    if (!decoder.decodeEnum(response.m_tainting))
+        return false;
     if (!decoder.decode(response.m_isRedirected))
         return false;
     response.m_isNull = false;