Title: [205076] trunk
Revision
205076
Author
[email protected]
Date
2016-08-27 03:40:37 -0700 (Sat, 27 Aug 2016)

Log Message

[Fetch API] Blob type should be set from Response/Request contentType header
https://bugs.webkit.org/show_bug.cgi?id=161228

Patch by Youenn Fablet <[email protected]> on 2016-08-27
Reviewed by Alex Christensen.

LayoutTests/imported/w3c:

* web-platform-tests/fetch/api/request/request-consume.html:
* web-platform-tests/fetch/api/request/request-headers-expected.txt:
* web-platform-tests/fetch/api/request/request-headers.html:
* web-platform-tests/fetch/api/response/response-consume-expected.txt:
* web-platform-tests/fetch/api/response/response-consume.html:
* web-platform-tests/fetch/api/response/response-init-002-expected.txt:
* web-platform-tests/fetch/api/response/response-init-002.html:

Source/WebCore:

Covered by updated tests.

Renaming FetchBody::m_mimeType to m_contentType since that better relates to Content-Type header.
Updated FetchRequest and FetchResponse to set m_contentType according request/response headers.
Handled the case of a Request created from JS, a Response created from JS and a Response created internally to
be used as resolve value in the fetch promise.

In case Content-Type is set but is empty, its empty value should be used for blob type.
Updated contentType checks to use isNull in lieu of isEmpty.

* Modules/fetch/FetchBody.cpp:
(WebCore::FetchBody::updateContentType): Routine to synchronize headers with m_contentType.
(WebCore::FetchBody::FetchBody): Renamed m_mimeType to m_contentType.
(WebCore::FetchBody::blob): Ditto.
* Modules/fetch/FetchBody.h: Ditto.
(WebCore::FetchBody::contentType):
(WebCore::FetchBody::setMimeType): Deleted.
(WebCore::FetchBody::mimeType): Deleted.
* Modules/fetch/FetchRequest.cpp:
(WebCore::FetchRequest::setBody): set FetchBody::m_contentType according HTTP headers.
* Modules/fetch/FetchResponse.cpp:
(WebCore::FetchResponse::initializeWith): Ditto.
(WebCore::FetchResponse::BodyLoader::didReceiveResponse): Ditto.

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (205075 => 205076)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-08-27 10:40:37 UTC (rev 205076)
@@ -1,3 +1,18 @@
+2016-08-27  Youenn Fablet  <[email protected]>
+
+        [Fetch API] Blob type should be set from Response/Request contentType header
+        https://bugs.webkit.org/show_bug.cgi?id=161228
+
+        Reviewed by Alex Christensen.
+
+        * web-platform-tests/fetch/api/request/request-consume.html:
+        * web-platform-tests/fetch/api/request/request-headers-expected.txt:
+        * web-platform-tests/fetch/api/request/request-headers.html:
+        * web-platform-tests/fetch/api/response/response-consume-expected.txt:
+        * web-platform-tests/fetch/api/response/response-consume.html:
+        * web-platform-tests/fetch/api/response/response-init-002-expected.txt:
+        * web-platform-tests/fetch/api/response/response-init-002.html:
+
 2016-08-26  Andreas Kling  <[email protected]>
 
         The :enabled/:disabled selectors should only match elements that can be disabled.

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume.html (205075 => 205076)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume.html	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume.html	2016-08-27 10:40:37 UTC (rev 205076)
@@ -19,8 +19,11 @@
       });
     }
 
-    function checkBodyBlob(request, expectedBody) {
+    function checkBodyBlob(request, expectedBody, checkContentType) {
       return request.blob().then(function(bodyAsBlob) {
+        if (checkContentType)
+          assert_equals(bodyAsBlob.type, "text/plain", "Blob body type should be computed from the request Content-Type");
+
         var promise = new Promise(function (resolve, reject) {
           var reader = new FileReader();
           reader._onload_ = function(evt) {
@@ -62,7 +65,7 @@
 
     function checkRequestBody(body, bodyType, checkFunction) {
       promise_test(function(test) {
-        var request = new Request("", {"method": "POST", "body": body });
+        var request = new Request("", {"method": "POST", "body": body, "headers": [["Content-Type", "text/PLAIN"]] });
         assert_false(request.bodyUsed, "bodyUsed is false at init");
         return checkFunction(request, body);
       }, "Consume request's body as " + bodyType);
@@ -74,7 +77,7 @@
     var blob = new Blob([textData], { "type" : "text/plain" });
 
     checkRequestBody(textData, "text", checkBodyText);
-    checkRequestBody(textData, "blob", checkBodyBlob);
+    checkRequestBody(textData, "blob", function(request, body) { checkBodyBlob(request, body, true); });
     checkRequestBody(textData, "arrayBuffer", checkBodyArrayBuffer);
     checkRequestBody(textData, "json", checkBodyJSON);
     checkRequestBody(formData, "formData", checkBodyFormData);

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-headers-expected.txt (205075 => 205076)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-headers-expected.txt	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-headers-expected.txt	2016-08-27 10:40:37 UTC (rev 205076)
@@ -54,4 +54,5 @@
 PASS Request should get its content-type from the body if none is provided 
 PASS Request should get its content-type from init headers if one is provided 
 PASS Testing request header creations with various objects 
+PASS Testing empty Request Content-Type header 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-headers.html (205075 => 205076)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-headers.html	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-headers.html	2016-08-27 10:40:37 UTC (rev 205076)
@@ -161,6 +161,13 @@
         assert_equals(request3.headers.get("hello"), "worldOOH");
       }, "Testing request header creations with various objects");
 
+      promise_test(function(test) {
+        var request = new Request("", {"headers" : [["Content-Type", ""]], "body" : "this is my plate", "method" : "POST"});
+        return request.blob().then(function(blob) {
+          assert_equals(blob.type, "", "Blob type should be the empty string");
+        });
+      }, "Testing empty Request Content-Type header");
+
     </script>
   </body>
 </html>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-expected.txt (205075 => 205076)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-expected.txt	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-expected.txt	2016-08-27 10:40:37 UTC (rev 205076)
@@ -12,4 +12,7 @@
 PASS Consume stream response's body as text 
 PASS Consume stream response's body as json 
 PASS Consume stream response's body as arrayBuffer 
+PASS Consume fetched response's body as blob 
+PASS Consume fetched response's body as text 
+PASS Consume fetched response's body as arrayBuffer 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume.html (205075 => 205076)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume.html	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume.html	2016-08-27 10:40:37 UTC (rev 205076)
@@ -19,8 +19,11 @@
       });
     }
 
-    function checkBodyBlob(response, expectedBody) {
+    function checkBodyBlob(response, expectedBody, checkContentType) {
       return response.blob().then(function(bodyAsBlob) {
+        if (checkContentType)
+          assert_equals(bodyAsBlob.type, "text/plain", "Blob body type should be computed from the response Content-Type");
+
         var promise = new Promise( function (resolve, reject) {
           var reader = new FileReader();
           reader._onload_ = function(evt) {
@@ -62,7 +65,7 @@
 
     function checkResponseBody(body, bodyType, checkFunction) {
       promise_test(function(test) {
-        var response = new Response(body);
+        var response = new Response(body, { "headers": [["Content-Type", "text/PLAIN"]] });
         assert_false(response.bodyUsed, "bodyUsed is false at init");
         return checkFunction(response, body);
       }, "Consume response's body as " + bodyType);
@@ -74,7 +77,7 @@
     var blob = new Blob([textData], { "type" : "text/plain" });
 
     checkResponseBody(textData, "text", checkBodyText);
-    checkResponseBody(textData, "blob", checkBodyBlob);
+    checkResponseBody(textData, "blob", function(response, body) { checkBodyBlob(response, body, true); });
     checkResponseBody(textData, "arrayBuffer", checkBodyArrayBuffer);
     checkResponseBody(textData, "json", checkBodyJSON);
     checkResponseBody(formData, "formData", checkBodyFormData);
@@ -111,6 +114,18 @@
     checkReadableStreamResponseBody(textData, "json", checkBodyJSON);
     checkReadableStreamResponseBody(textData, "arrayBuffer", checkBodyArrayBuffer);
 
+    function checkFetchedResponseBody(bodyType, checkFunction) {
+      return promise_test(function(test) {
+        return fetch("../resources/top.txt").then(function(response) {
+          assert_false(response.bodyUsed, "bodyUsed is false at init");
+          return checkFunction(response, "top");
+        });
+      }, "Consume fetched response's body as " + bodyType);
+    }
+    checkFetchedResponseBody("blob", checkBodyBlob);
+    checkFetchedResponseBody("text", checkBodyText);
+    checkFetchedResponseBody("arrayBuffer", checkBodyArrayBuffer);
+
     </script>
   </body>
 </html>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-init-002-expected.txt (205075 => 205076)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-init-002-expected.txt	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-init-002-expected.txt	2016-08-27 10:40:37 UTC (rev 205076)
@@ -5,4 +5,5 @@
 FAIL Initialize Response's body with application/x-www-form-urlencoded;charset=UTF-8 assert_true: Content-Type header should be "application/x-www-form-urlencoded;charset=UTF-8"  expected true got false
 PASS Initialize Response's body with text/plain;charset=UTF-8 
 PASS Read Response's body as readableStream 
+PASS Testing empty Response Content-Type header 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-init-002.html (205075 => 205076)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-init-002.html	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-init-002.html	2016-08-27 10:40:37 UTC (rev 205076)
@@ -57,6 +57,14 @@
         var response = new Response(body);
         return validateStreamFromString(response.body.getReader(), body);
       }, "Read Response's body as readableStream");
+
+      promise_test(function(test) {
+        var response = new Response("This is my fork", {"headers" : [["Content-Type", ""]]});
+        return response.blob().then(function(blob) {
+          assert_equals(blob.type, "", "Blob type should be the empty string");
+        });
+      }, "Testing empty Response Content-Type header");
+
     </script>
   </body>
 </html>

Modified: trunk/Source/WebCore/ChangeLog (205075 => 205076)


--- trunk/Source/WebCore/ChangeLog	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/Source/WebCore/ChangeLog	2016-08-27 10:40:37 UTC (rev 205076)
@@ -1,3 +1,34 @@
+2016-08-27  Youenn Fablet  <[email protected]>
+
+        [Fetch API] Blob type should be set from Response/Request contentType header
+        https://bugs.webkit.org/show_bug.cgi?id=161228
+
+        Reviewed by Alex Christensen.
+
+        Covered by updated tests.
+
+        Renaming FetchBody::m_mimeType to m_contentType since that better relates to Content-Type header.
+        Updated FetchRequest and FetchResponse to set m_contentType according request/response headers.
+        Handled the case of a Request created from JS, a Response created from JS and a Response created internally to
+        be used as resolve value in the fetch promise.
+
+        In case Content-Type is set but is empty, its empty value should be used for blob type.
+        Updated contentType checks to use isNull in lieu of isEmpty.
+
+        * Modules/fetch/FetchBody.cpp:
+        (WebCore::FetchBody::updateContentType): Routine to synchronize headers with m_contentType.
+        (WebCore::FetchBody::FetchBody): Renamed m_mimeType to m_contentType.
+        (WebCore::FetchBody::blob): Ditto.
+        * Modules/fetch/FetchBody.h: Ditto.
+        (WebCore::FetchBody::contentType):
+        (WebCore::FetchBody::setMimeType): Deleted.
+        (WebCore::FetchBody::mimeType): Deleted.
+        * Modules/fetch/FetchRequest.cpp:
+        (WebCore::FetchRequest::setBody): set FetchBody::m_contentType according HTTP headers.
+        * Modules/fetch/FetchResponse.cpp:
+        (WebCore::FetchResponse::initializeWith): Ditto.
+        (WebCore::FetchResponse::BodyLoader::didReceiveResponse): Ditto.
+
 2016-08-26  Alex Christensen  <[email protected]>
 
         Fix Windows build after r205065.

Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.cpp (205075 => 205076)


--- trunk/Source/WebCore/Modules/fetch/FetchBody.cpp	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.cpp	2016-08-27 10:40:37 UTC (rev 205076)
@@ -34,6 +34,7 @@
 #include "DOMRequestState.h"
 #include "Dictionary.h"
 #include "FetchBodyOwner.h"
+#include "FetchHeaders.h"
 #include "FetchResponseSource.h"
 #include "FormData.h"
 #include "HTTPParsers.h"
@@ -46,7 +47,7 @@
 
 FetchBody::FetchBody(Ref<Blob>&& blob)
     : m_type(Type::Blob)
-    , m_mimeType(blob->type())
+    , m_contentType(blob->type())
     , m_blob(WTFMove(blob))
 {
 }
@@ -53,7 +54,7 @@
 
 FetchBody::FetchBody(Ref<DOMFormData>&& formData)
     : m_type(Type::FormData)
-    , m_mimeType(ASCIILiteral("multipart/form-data"))
+    , m_contentType(ASCIILiteral("multipart/form-data"))
     , m_formData(WTFMove(formData))
 {
     // FIXME: Handle the boundary parameter of multipart/form-data MIME type.
@@ -61,7 +62,7 @@
 
 FetchBody::FetchBody(String&& text)
     : m_type(Type::Text)
-    , m_mimeType(ASCIILiteral("text/plain;charset=UTF-8"))
+    , m_contentType(ASCIILiteral("text/plain;charset=UTF-8"))
     , m_text(WTFMove(text))
 {
 }
@@ -88,6 +89,17 @@
     return FetchBody(WTFMove(*body));
 }
 
+void FetchBody::updateContentType(FetchHeaders& headers)
+{
+    String contentType = headers.fastGet(HTTPHeaderName::ContentType);
+    if (!contentType.isNull()) {
+        m_contentType = contentType;
+        return;
+    }
+    if (!m_contentType.isNull())
+        headers.fastSet(HTTPHeaderName::ContentType, m_contentType);
+}
+
 void FetchBody::arrayBuffer(FetchBodyOwner& owner, DeferredWrapper&& promise)
 {
     ASSERT(m_type != Type::None);
@@ -99,7 +111,7 @@
 {
     ASSERT(m_type != Type::None);
     m_consumer.setType(FetchBodyConsumer::Type::Blob);
-    m_consumer.setContentType(Blob::normalizedContentType(extractMIMETypeFromMediaType(m_mimeType)));
+    m_consumer.setContentType(Blob::normalizedContentType(extractMIMETypeFromMediaType(m_contentType)));
     consume(owner, WTFMove(promise));
 }
 

Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.h (205075 => 205076)


--- trunk/Source/WebCore/Modules/fetch/FetchBody.h	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.h	2016-08-27 10:40:37 UTC (rev 205076)
@@ -45,6 +45,7 @@
 namespace WebCore {
 
 class FetchBodyOwner;
+class FetchHeaders;
 class FetchResponseSource;
 class FormData;
 
@@ -62,8 +63,9 @@
 
     bool isEmpty() const { return m_type == Type::None; }
 
-    void setMimeType(const String& mimeType) { m_mimeType = mimeType; }
-    String mimeType() const { return m_mimeType; }
+    void updateContentType(FetchHeaders&);
+    void setContentType(const String& contentType) { m_contentType = contentType; }
+    String contentType() const { return m_contentType; }
 
     static FetchBody extract(JSC::ExecState&, JSC::JSValue);
     static FetchBody extractFromBody(FetchBody*);
@@ -96,7 +98,7 @@
     void consumeBlob(FetchBodyOwner&, DeferredWrapper&&);
 
     Type m_type { Type::None };
-    String m_mimeType;
+    String m_contentType;
 
     // FIXME: Add support for BufferSource and URLSearchParams.
     RefPtr<Blob> m_blob;

Modified: trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp (205075 => 205076)


--- trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp	2016-08-27 10:40:37 UTC (rev 205076)
@@ -268,12 +268,8 @@
         request->setDisturbed();
     }
 
-    String type = m_headers->fastGet(HTTPHeaderName::ContentType);
-    if (!body.isUndefined() && type.isEmpty() && !m_body.mimeType().isEmpty()) {
-        type = m_body.mimeType();
-        m_headers->fastSet(HTTPHeaderName::ContentType, type);
-    }
-    m_body.setMimeType(type);
+    m_body.updateContentType(m_headers);
+
     if (!validateBodyAndMethod(m_body, m_internalRequest))
         ec = TypeError;
 }

Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp (205075 => 205076)


--- trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp	2016-08-27 09:18:54 UTC (rev 205075)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp	2016-08-27 10:40:37 UTC (rev 205076)
@@ -83,8 +83,7 @@
 void FetchResponse::initializeWith(JSC::ExecState& execState, JSC::JSValue body)
 {
     m_body = FetchBody::extract(execState, body);
-    if (m_headers->fastGet(HTTPHeaderName::ContentType).isEmpty() && !m_body.mimeType().isEmpty())
-        m_headers->fastSet(HTTPHeaderName::ContentType, m_body.mimeType());
+    m_body.updateContentType(m_headers);
 }
 
 FetchResponse::FetchResponse(ScriptExecutionContext& context, FetchBody&& body, Ref<FetchHeaders>&& headers, ResourceResponse&& response)
@@ -176,6 +175,7 @@
 
     m_response.m_response = resourceResponse;
     m_response.m_headers->filterAndFill(resourceResponse.httpHeaderFields(), FetchHeaders::Guard::Response);
+    m_response.m_body.setContentType(m_response.m_headers->fastGet(HTTPHeaderName::ContentType));
 
     std::exchange(m_promise, Nullopt)->resolve(m_response);
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to