Set the Response.blob() type based on the content-type header value.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 May 2017 00:01:07 +0000 (00:01 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 May 2017 00:01:07 +0000 (00:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170849

Patch by Ben Kelly <ben@wanderview.com> on 2017-05-07
Reviewed by Youenn Fablet.

LayoutTests/imported/w3c:

* web-platform-tests/fetch/api/response/response-consume-expected.txt:

Source/WebCore:

There are two problems to fix here:

1.  Currently the FetchResponse class only called updateContentType()
when first created even though all the headers were not available.  This
patch calls updateContentType() again after the headers are populated.

2.  The fetch design requires propagating the normalized blob
type to FetchBodyConsumer as well.  Currently this is only done if
Response.blob() is called after the body is completely loaded.  If
we hit the consumeOnceLoadingFinished() path, then the type is not
passed.  This is similar to what was happening in bug 171489 with
ReadableStream bodies.  This patch sets the type on the
FetchBodyConsumer in consumeOnceLoadingFinished() as well.

Theses changes allow WebKit to pass the "Consume response's body: from
fetch to blob" case in the WPT response-consume.html test.

Test: http://w3c-test.org/fetch/api/response/response-consume.html

* Modules/fetch/FetchResponse.cpp:
(WebCore::FetchResponse::BodyLoader::didReceiveResponse): Modified to
call FetchBodyOwner::updateContentType() after filling m_headers.
(WebCore::FetchBody::consumeOnceLoadingFinished): Call
FetchBodyConsumer::setContentType() when being consumed as
a blob.
* Modules/fetch/FetchBody.h: Modify consumeOnceLoadingFinished()
to take the content type string.
* Modules/fetch/FetchBodyOwner.cpp:
(WebCore::FetchBodyOwner::consumeOnceLoadingFinished): Pass
the content type string down to FetchBody so it can be
propagated to the FetchBodyConsumer.

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

LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/fetch/FetchBody.cpp
Source/WebCore/Modules/fetch/FetchBody.h
Source/WebCore/Modules/fetch/FetchBodyOwner.cpp
Source/WebCore/Modules/fetch/FetchResponse.cpp

index caac66e..c507fca 100644 (file)
@@ -1,3 +1,12 @@
+2017-05-07  Ben Kelly <ben@wanderview.com>
+
+        Set the Response.blob() type based on the content-type header value.
+        https://bugs.webkit.org/show_bug.cgi?id=170849
+
+        Reviewed by Youenn Fablet.
+
+        * web-platform-tests/fetch/api/response/response-consume-expected.txt:
+
 2017-05-07  Sam Weinig  <sam@webkit.org>
 
         Implement Subresource Integrity (SRI)
index e3ccf2e..7535c68 100644 (file)
@@ -33,7 +33,7 @@ FAIL Consume response's body: from stream with correct multipart type to formDat
 FAIL Consume response's body: from stream without correct multipart type to formData (error case) assert_throws: function "function () { throw e }" threw "Not implemented" (undefined) expected object "TypeError" ("TypeError")
 FAIL Consume response's body: from stream with correct urlencoded type to formData promise_test: Unhandled rejection with value: "Not implemented"
 FAIL Consume response's body: from stream without correct urlencoded type to formData (error case) assert_throws: function "function () { throw e }" threw "Not implemented" (undefined) expected object "TypeError" ("TypeError")
-FAIL Consume response's body: from fetch to blob assert_equals: Blob body type should be computed from the response Content-Type expected "text/plain" but got ""
+PASS Consume response's body: from fetch to blob 
 PASS Consume response's body: from fetch to text 
 PASS Consume response's body: from fetch to arrayBuffer 
 FAIL Consume response's body: from fetch without correct type to formData (error case) assert_throws: function "function () { throw e }" threw "Not implemented" (undefined) expected object "TypeError" ("TypeError")
index 0d80c9b..5768e98 100644 (file)
@@ -1,3 +1,42 @@
+2017-05-07  Ben Kelly  <ben@wanderview.com>
+
+        Set the Response.blob() type based on the content-type header value.
+        https://bugs.webkit.org/show_bug.cgi?id=170849
+
+        Reviewed by Youenn Fablet.
+
+        There are two problems to fix here:
+
+        1.  Currently the FetchResponse class only called updateContentType()
+        when first created even though all the headers were not available.  This
+        patch calls updateContentType() again after the headers are populated.
+
+        2.  The fetch design requires propagating the normalized blob
+        type to FetchBodyConsumer as well.  Currently this is only done if
+        Response.blob() is called after the body is completely loaded.  If
+        we hit the consumeOnceLoadingFinished() path, then the type is not
+        passed.  This is similar to what was happening in bug 171489 with
+        ReadableStream bodies.  This patch sets the type on the
+        FetchBodyConsumer in consumeOnceLoadingFinished() as well.
+
+        Theses changes allow WebKit to pass the "Consume response's body: from
+        fetch to blob" case in the WPT response-consume.html test.
+
+        Test: http://w3c-test.org/fetch/api/response/response-consume.html
+
+        * Modules/fetch/FetchResponse.cpp:
+        (WebCore::FetchResponse::BodyLoader::didReceiveResponse): Modified to
+        call FetchBodyOwner::updateContentType() after filling m_headers.
+        (WebCore::FetchBody::consumeOnceLoadingFinished): Call
+        FetchBodyConsumer::setContentType() when being consumed as
+        a blob.
+        * Modules/fetch/FetchBody.h: Modify consumeOnceLoadingFinished()
+        to take the content type string.
+        * Modules/fetch/FetchBodyOwner.cpp:
+        (WebCore::FetchBodyOwner::consumeOnceLoadingFinished): Pass
+        the content type string down to FetchBody so it can be
+        propagated to the FetchBodyConsumer.
+
 2017-05-07  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS] REGRESSION (r209409): getBoundingClientRect is wrong for fixed-position elements in resize/orientationchange
index 0d70d86..895deb1 100644 (file)
@@ -118,10 +118,12 @@ void FetchBody::text(FetchBodyOwner& owner, Ref<DeferredPromise>&& promise)
     consume(owner, WTFMove(promise));
 }
 
-void FetchBody::consumeOnceLoadingFinished(FetchBodyConsumer::Type type, Ref<DeferredPromise>&& promise)
+void FetchBody::consumeOnceLoadingFinished(FetchBodyConsumer::Type type, Ref<DeferredPromise>&& promise, const String& contentType)
 {
     m_consumer.setType(type);
     m_consumePromise = WTFMove(promise);
+    if (type == FetchBodyConsumer::Type::Blob)
+        m_consumer.setContentType(Blob::normalizedContentType(extractMIMETypeFromMediaType(contentType)));
 }
 
 void FetchBody::consume(FetchBodyOwner& owner, Ref<DeferredPromise>&& promise)
index feea6dc..2e60af8 100644 (file)
@@ -80,7 +80,7 @@ public:
 
     FetchBodyConsumer& consumer() { return m_consumer; }
 
-    void consumeOnceLoadingFinished(FetchBodyConsumer::Type, Ref<DeferredPromise>&&);
+    void consumeOnceLoadingFinished(FetchBodyConsumer::Type, Ref<DeferredPromise>&&, const String&);
     void cleanConsumePromise() { m_consumePromise = nullptr; }
 
     FetchBody clone() const;
index d667dbb..2f68593 100644 (file)
@@ -132,7 +132,7 @@ void FetchBodyOwner::consumeOnceLoadingFinished(FetchBodyConsumer::Type type, Re
         return;
     }
     m_isDisturbed = true;
-    m_body->consumeOnceLoadingFinished(type, WTFMove(promise));
+    m_body->consumeOnceLoadingFinished(type, WTFMove(promise), m_contentType);
 }
 
 void FetchBodyOwner::formData(Ref<DeferredPromise>&& promise)
index 4f1751c..2aa6f14 100644 (file)
@@ -173,6 +173,7 @@ void FetchResponse::BodyLoader::didReceiveResponse(const ResourceResponse& resou
 
     m_response.m_response = resourceResponse;
     m_response.m_headers->filterAndFill(resourceResponse.httpHeaderFields(), FetchHeaders::Guard::Response);
+    m_response.updateContentType();
 
     std::exchange(m_promise, std::nullopt)->resolve(m_response);
 }