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;