Title: [197396] trunk
Revision
197396
Author
[email protected]
Date
2016-03-01 02:34:17 -0800 (Tue, 01 Mar 2016)

Log Message

[Fetch API] Support Request and Response blob() when body data is a blob
https://bugs.webkit.org/show_bug.cgi?id=154820

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Adding blob specific tests. New tests are not covered yet as they require converting data from a blob into another form (JSON, text...).
Rebasing expectations with test that is now passing and new failing tests.
Fixing typos in test (Json -> JSON and removing TextDecoder use).

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

Source/WebCore:

Adding support for returning the same Blob that is stored in Body in case JS blob() is called.
Adding support for Blob creation when data is stored as text.
Updated JSDOMBinding and JSDOMPromise to return a JS ArrayBuffer for Vector<char> as well as Vector<unsigned char>.

Covered by added tests.

* Modules/fetch/FetchBody.cpp:
(WebCore::FetchBody::arrayBuffer):
(WebCore::FetchBody::blob):
(WebCore::FetchBody::extractFromText):
* Modules/fetch/FetchBody.h:
* bindings/js/JSDOMBinding.h:
(WebCore::toJS):
* bindings/js/JSDOMPromise.h:
(WebCore::DeferredWrapper::resolve): Deleted.

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (197395 => 197396)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-03-01 09:05:37 UTC (rev 197395)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-03-01 10:34:17 UTC (rev 197396)
@@ -1,3 +1,19 @@
+2016-03-01  Youenn Fablet  <[email protected]>
+
+        [Fetch API] Support Request and Response blob() when body data is a blob
+        https://bugs.webkit.org/show_bug.cgi?id=154820
+
+        Reviewed by Darin Adler.
+
+        Adding blob specific tests. New tests are not covered yet as they require converting data from a blob into another form (JSON, text...).
+        Rebasing expectations with test that is now passing and new failing tests.
+        Fixing typos in test (Json -> JSON and removing TextDecoder use).
+
+        * web-platform-tests/fetch/api/request/request-consume-expected.txt:
+        * web-platform-tests/fetch/api/request/request-consume.html:
+        * web-platform-tests/fetch/api/response/response-consume-expected.txt:
+        * web-platform-tests/fetch/api/response/response-consume.html:
+
 2016-02-29  Chris Dumez  <[email protected]>
 
         Use HTML parsing rules for textarea.maxLength

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-expected.txt (197395 => 197396)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-expected.txt	2016-03-01 09:05:37 UTC (rev 197395)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-expected.txt	2016-03-01 10:34:17 UTC (rev 197396)
@@ -1,9 +1,13 @@
 
 PASS Consume request's body as text 
-FAIL Consume request's body as blob promise_test: Unhandled rejection with value: undefined
+PASS Consume request's body as blob 
 PASS Consume request's body as arrayBuffer 
 PASS Consume request's body as json 
 FAIL Consume request's body as formData promise_test: Unhandled rejection with value: undefined
+PASS Consume blob response's body as blob 
+FAIL Consume blob response's body as text promise_test: Unhandled rejection with value: undefined
+FAIL Consume blob response's body as json promise_test: Unhandled rejection with value: undefined
+FAIL Consume blob response's body as arrayBuffer promise_test: Unhandled rejection with value: undefined
 PASS Consume JSON from text: '"null"' 
 PASS Consume JSON from text: '"1"' 
 PASS Consume JSON from text: '"true"' 

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


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume.html	2016-03-01 09:05:37 UTC (rev 197395)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume.html	2016-03-01 10:34:17 UTC (rev 197396)
@@ -79,12 +79,28 @@
 
     var formData = new FormData();
     formData.append("name", "value")
-    checkRequestBody("This is request's body", "text", checkBodyText);
-    checkRequestBody("This is request's body", "blob", checkBodyBlob);
-    checkRequestBody("This is request's body", "arrayBuffer", checkBodyArrayBuffer);
-    checkRequestBody(JSON.stringify("This is request's body"), "json", checkBodyJSON);
+    var textData = "This is response's body";
+    var blob = new Blob([textData], { "type" : "text/plain" });
+
+    checkRequestBody(textData, "text", checkBodyText);
+    checkRequestBody(textData, "blob", checkBodyBlob);
+    checkRequestBody(textData, "arrayBuffer", checkBodyArrayBuffer);
+    checkRequestBody(JSON.stringify(textData), "json", checkBodyJSON);
     checkRequestBody(formData, "formData", checkBodyFormData);
 
+    function checkBlobResponseBody(blobBody, blobData, bodyType, checkFunction) {
+      promise_test(function(test) {
+        var response = new Response(blobBody);
+        assert_false(response.bodyUsed, "bodyUsed is false at init");
+        return checkFunction(response, blobData);
+      }, "Consume blob response's body as " + bodyType);
+    }
+
+    checkBlobResponseBody(blob, textData, "blob", checkBodyBlob);
+    checkBlobResponseBody(blob, textData, "text", checkBodyText);
+    checkBlobResponseBody(blob, textData, "json", checkBodyJSON);
+    checkBlobResponseBody(blob, textData, "arrayBuffer", checkBodyArrayBuffer);
+
     var goodJSONValues = ["null", "1", "true", "\"string\""];
     goodJSONValues.forEach(function(value) {
       promise_test(function(test) {

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


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-expected.txt	2016-03-01 09:05:37 UTC (rev 197395)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-expected.txt	2016-03-01 10:34:17 UTC (rev 197396)
@@ -1,7 +1,11 @@
 
 PASS Consume response's body as text 
-FAIL Consume response's body as blob promise_test: Unhandled rejection with value: undefined
-FAIL Consume response's body as arrayBuffer promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: TextDecoder"
+PASS Consume response's body as blob 
+PASS Consume response's body as arrayBuffer 
 PASS Consume response's body as json 
 FAIL Consume response's body as formData promise_test: Unhandled rejection with value: undefined
+PASS Consume blob response's body as blob 
+FAIL Consume blob response's body as text promise_test: Unhandled rejection with value: undefined
+FAIL Consume blob response's body as json promise_test: Unhandled rejection with value: undefined
+FAIL Consume blob response's body as arrayBuffer promise_test: Unhandled rejection with value: undefined
 

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


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume.html	2016-03-01 09:05:37 UTC (rev 197395)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume.html	2016-03-01 10:34:17 UTC (rev 197396)
@@ -37,18 +37,26 @@
       });
     }
 
+    <!-- Taken from https://developers.google.com -->
+    function str2ab(str) {
+      var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
+      var bufView = new Uint16Array(buf);
+      for (var i=0, strLen=str.length; i < strLen; i++) {
+        bufView[i] = str.charCodeAt(i);
+      }
+      return buf;
+    }
+
     function checkBodyArrayBuffer(response, expectedBody) {
       return response.arrayBuffer().then( function(bodyAsArrayBuffer) {
-        var decoder = new TextDecoder("utf-8");
-        var strBody = decoder.decode(bodyAsArrayBuffer);
-        assert_equals(strBody, expectedBody, "Retrieve and verify response's body");
+        assert_array_equals(bodyAsArrayBuffer, str2ab(expectedBody), "Retrieve and verify response's body");
         assert_true(response.bodyUsed, "body as arrayBuffer: bodyUsed turned true");
       });
     }
 
-    function checkBodyJson(response, expectedBody) {
-      return response.json().then(function(bodyAsJson) {
-        var strBody = JSON.stringify(bodyAsJson)
+    function checkBodyJSON(response, expectedBody) {
+      return response.json().then(function(bodyAsJSON) {
+        var strBody = JSON.stringify(bodyAsJSON)
         assert_equals(strBody, expectedBody, "Retrieve and verify response's body");
         assert_true(response.bodyUsed, "body as json: bodyUsed turned true");
       });
@@ -70,12 +78,31 @@
     }
 
     var formData = new FormData();
-    formData.append("name", "value")
-    checkResponseBody("This is response's body", "text", checkBodyText);
-    checkResponseBody("This is response's body", "blob", checkBodyBlob);
-    checkResponseBody("This is response's body", "arrayBuffer", checkBodyArrayBuffer);
-    checkResponseBody(JSON.stringify("This is response's body"), "json", checkBodyJson);
+    formData.append("name", "value");
+    var textData = "This is response's body";
+    var blob = new Blob([textData], { "type" : "text/plain" });
+
+    checkResponseBody(textData, "text", checkBodyText);
+    checkResponseBody(textData, "blob", checkBodyBlob);
+    checkResponseBody(textData, "arrayBuffer", checkBodyArrayBuffer);
+
+    checkResponseBody(JSON.stringify("This is response's body"), "json", checkBodyJSON);
+
     checkResponseBody(formData, "formData", checkBodyFormData);
+
+    function checkBlobResponseBody(blobBody, blobData, bodyType, checkFunction) {
+      promise_test(function(test) {
+        var response = new Response(blobBody);
+        assert_false(response.bodyUsed, "bodyUsed is false at init");
+        return checkFunction(response, blobData);
+      }, "Consume blob response's body as " + bodyType);
+    }
+
+    checkBlobResponseBody(blob, textData, "blob", checkBodyBlob);
+    checkBlobResponseBody(blob, textData, "text", checkBodyText);
+    checkBlobResponseBody(blob, textData, "json", checkBodyJSON);
+    checkBlobResponseBody(blob, textData, "arrayBuffer", checkBodyArrayBuffer);
+
     </script>
   </body>
 </html>

Modified: trunk/Source/WebCore/ChangeLog (197395 => 197396)


--- trunk/Source/WebCore/ChangeLog	2016-03-01 09:05:37 UTC (rev 197395)
+++ trunk/Source/WebCore/ChangeLog	2016-03-01 10:34:17 UTC (rev 197396)
@@ -1,3 +1,26 @@
+2016-03-01  Youenn Fablet  <[email protected]>
+
+        [Fetch API] Support Request and Response blob() when body data is a blob
+        https://bugs.webkit.org/show_bug.cgi?id=154820
+
+        Reviewed by Darin Adler.
+
+        Adding support for returning the same Blob that is stored in Body in case JS blob() is called.
+        Adding support for Blob creation when data is stored as text.
+        Updated JSDOMBinding and JSDOMPromise to return a JS ArrayBuffer for Vector<char> as well as Vector<unsigned char>.
+
+        Covered by added tests.
+
+        * Modules/fetch/FetchBody.cpp:
+        (WebCore::FetchBody::arrayBuffer):
+        (WebCore::FetchBody::blob):
+        (WebCore::FetchBody::extractFromText):
+        * Modules/fetch/FetchBody.h:
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::toJS):
+        * bindings/js/JSDOMPromise.h:
+        (WebCore::DeferredWrapper::resolve): Deleted.
+
 2016-02-29  Chris Dumez  <[email protected]>
 
         Have parseHTMLInteger() / parseHTMLNonNegativeInteger() use WTF::Optional

Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.cpp (197395 => 197396)


--- trunk/Source/WebCore/Modules/fetch/FetchBody.cpp	2016-03-01 09:05:37 UTC (rev 197395)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.cpp	2016-03-01 10:34:17 UTC (rev 197396)
@@ -33,6 +33,7 @@
 
 #include "Dictionary.h"
 #include "ExceptionCode.h"
+#include "HTTPParsers.h"
 #include "JSBlob.h"
 #include "JSDOMFormData.h"
 #include <runtime/JSONObject.h>
@@ -102,12 +103,10 @@
         return;
 
     if (m_type == Type::Text) {
-        // FIXME: promise expects a Vector<unsigned char> that will be converted to an ArrayBuffer.
-        // We should try to create a Vector<unsigned char> or an ArrayBuffer directly from m_text.
-        CString data = ""
-        Vector<unsigned char> value(data.length());
-        memcpy(value.data(), data.data(), data.length());
-        promise.resolve(WTFMove(value));
+        // FIXME: Ideally we would like to have an ArrayBuffer directly from m_text.
+        Vector<char> data = ""
+        RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(data.data(), data.size());
+        promise.resolve(buffer);
         return;
     }
     // FIXME: Support other types.
@@ -131,6 +130,16 @@
     if (processIfEmptyOrDisturbed(promise))
         return;
 
+    if (m_type == Type::Blob) {
+        promise.resolve(m_blob);
+        return;
+    }
+    if (m_type == Type::Text) {
+        String contentType = Blob::normalizedContentType(extractMIMETypeFromMediaType(m_mimeType));
+        promise.resolve(Blob::create(extractFromText(), contentType));
+        return;
+    }
+
     // FIXME: Support other types.
     promise.reject(0);
 }
@@ -165,6 +174,16 @@
     promise.reject(0);
 }
 
+Vector<char> FetchBody::extractFromText() const
+{
+    ASSERT(m_type == Type::Text);
+    // FIXME: This double allocation is not efficient. Might want to fix that at WTFString level.
+    CString data = ""
+    Vector<char> value(data.length());
+    memcpy(value.data(), data.data(), data.length());
+    return value;
 }
 
+}
+
 #endif // ENABLE(FETCH_API)

Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.h (197395 => 197396)


--- trunk/Source/WebCore/Modules/fetch/FetchBody.h	2016-03-01 09:05:37 UTC (rev 197395)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.h	2016-03-01 10:34:17 UTC (rev 197396)
@@ -36,6 +36,7 @@
 #include "JSDOMPromise.h"
 
 namespace JSC {
+class ArrayBuffer;
 class ExecState;
 class JSValue;
 };
@@ -47,7 +48,7 @@
 
 class FetchBody {
 public:
-    typedef DOMPromise<Vector<unsigned char>, ExceptionCode> ArrayBufferPromise;
+    typedef DOMPromise<RefPtr<JSC::ArrayBuffer>, ExceptionCode> ArrayBufferPromise;
     void arrayBuffer(ArrayBufferPromise&&);
 
     typedef DOMPromise<RefPtr<DOMFormData>, ExceptionCode> FormDataPromise;
@@ -81,6 +82,8 @@
     FetchBody(Ref<DOMFormData>&&);
     FetchBody(String&&);
 
+    Vector<char> extractFromText() const;
+
     Type m_type = Type::None;
     String m_mimeType;
     bool m_isDisturbed = false;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to