Changeset 205115 in webkit


Ignore:
Timestamp:
Aug 29, 2016 2:18:06 AM (8 years ago)
Author:
commit-queue@webkit.org
Message:

[Fetch API] Add support for BufferSource bodies
https://bugs.webkit.org/show_bug.cgi?id=161087

Patch by Youenn Fablet <youenn@apple.com> on 2016-08-29
Reviewed by Darin Adler.

LayoutTests/imported/w3c:

  • web-platform-tests/fetch/api/basic/request-headers-expected.txt:
  • web-platform-tests/fetch/api/basic/request-headers-worker-expected.txt:
  • web-platform-tests/fetch/api/basic/request-headers.js:

(checkContentType):
(requestHeaders): Change the order of the header checks so that passing headers are checked first.

  • 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-stream-expected.txt:
  • web-platform-tests/fetch/api/response/response-consume-stream.html:

Source/WebCore:

Covered by updated tests.

Added support for ArrayBuffer, ArrayBufferView and FormData upload.
Added support for consuming ArrayBufferView.

To support FormData upload, FetchBOdy is now storing a FormData computed from the DOMFormData passed to the constructor.
This allows setting the content-type for FormData correctly with the boundary parameter.

  • Modules/fetch/FetchBody.cpp:

(WebCore::FetchBody::bodyForInternalRequest): Adding support for FormData upload.
(WebCore::FetchBody::FetchBody): Adding ArrayBuffer and ArrayBufferView constructors.
(WebCore::FetchBody::extract): Extracting in case of BufferSource (i.e. ArrayBuffer or ArrayBufferView) and FormData.
(WebCore::FetchBody::consume): Adding support to consume ArrayBufferView.
(WebCore::FetchBody::consumeAsStream): Adding support to consume ArrayBufferView as a stream.
Cloned the ArrayBuffer before enqueuing it in the stream.
(WebCore::FetchBody::consumeArrayBuffer): Cleaning m_data after being consumed.
(WebCore::FetchBody::consumeArrayBufferView): Adding support to consume ArrayBufferView.
(WebCore::FetchBody::consumeText): Cleaning m_text after being consumed.
(WebCore::FetchBody::consumeBlob): Ditto for m_blob.
(WebCore::FetchBody::bodyForInternalRequest): Adding support for ArrayBuffer and ArrayBufferView upload.

  • Modules/fetch/FetchBody.h:
  • Modules/fetch/FetchRequest.cpp:

(WebCore::FetchRequest::internalRequest): Passing ScriptExecutionContext as this is needed for FormData upload.
(WebCore::FetchRequest::setBody): Ditto.

  • Modules/fetch/FetchResponse.cpp:

(WebCore::FetchResponse::initializeWith): Ditto.
(WebCore::FetchResponse::fetch): Removing FormData upload rejection check.

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r205113 r205115  
     12016-08-29  Youenn Fablet  <youenn@apple.com>
     2
     3        [Fetch API] Add support for BufferSource bodies
     4        https://bugs.webkit.org/show_bug.cgi?id=161087
     5
     6        Reviewed by Darin Adler.
     7
     8        * web-platform-tests/fetch/api/basic/request-headers-expected.txt:
     9        * web-platform-tests/fetch/api/basic/request-headers-worker-expected.txt:
     10        * web-platform-tests/fetch/api/basic/request-headers.js:
     11        (checkContentType):
     12        (requestHeaders): Change the order of the header checks so that passing headers are checked first.
     13        * web-platform-tests/fetch/api/request/request-consume-expected.txt:
     14        * web-platform-tests/fetch/api/request/request-consume.html:
     15        * web-platform-tests/fetch/api/response/response-consume-stream-expected.txt:
     16        * web-platform-tests/fetch/api/response/response-consume-stream.html:
     17
    1182016-08-29  Youenn Fablet  <youenn@apple.com>
    219
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/request-headers-expected.txt

    r204225 r205115  
    11
    22FAIL Fetch with GET assert_equals: Request should have header origin: http://localhost:8800 expected (string) "http://localhost:8800" but got (object) null
    3 FAIL Fetch with HEAD assert_equals: Request should have header content-length: null expected (object) null but got (string) "0"
     3FAIL Fetch with HEAD assert_equals: Request should have header origin: http://localhost:8800 expected (string) "http://localhost:8800" but got (object) null
    44PASS Fetch with PUT without body
    55PASS Fetch with PUT with body
    66PASS Fetch with POST without body
    77PASS Fetch with POST with text body
    8 FAIL Fetch with POST with FormData body promise_test: Unhandled rejection with value: object "TypeError: Uploading FormData is not yet implemented"
     8PASS Fetch with POST with FormData body
    99FAIL Fetch with POST with Blob body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
    10 FAIL Fetch with POST with ArrayBuffer body promise_test: Unhandled rejection with value: object "TypeError: Type error"
     10FAIL Fetch with POST with ArrayBuffer body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     11FAIL Fetch with POST with Uint8Array body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     12FAIL Fetch with POST with Int8Array body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     13FAIL Fetch with POST with Float32Array body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     14FAIL Fetch with POST with Float64Array body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     15FAIL Fetch with POST with DataView body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
    1116PASS Fetch with POST with Blob body with mime type
    1217FAIL Fetch with Chicken assert_equals: Request should have header content-length: null expected (object) null but got (string) "0"
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/request-headers-worker-expected.txt

    r204225 r205115  
    11
    22FAIL Fetch with GET assert_equals: Request should have header origin: http://localhost:8800 expected (string) "http://localhost:8800" but got (object) null
    3 FAIL Fetch with HEAD assert_equals: Request should have header content-length: null expected (object) null but got (string) "0"
     3FAIL Fetch with HEAD assert_equals: Request should have header origin: http://localhost:8800 expected (string) "http://localhost:8800" but got (object) null
    44PASS Fetch with PUT without body
    55PASS Fetch with PUT with body
     
    77PASS Fetch with POST with text body
    88FAIL Fetch with POST with Blob body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
    9 FAIL Fetch with POST with ArrayBuffer body promise_test: Unhandled rejection with value: object "TypeError: Type error"
     9FAIL Fetch with POST with ArrayBuffer body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     10FAIL Fetch with POST with Uint8Array body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     11FAIL Fetch with POST with Int8Array body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     12FAIL Fetch with POST with Float32Array body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     13FAIL Fetch with POST with Float64Array body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
     14FAIL Fetch with POST with DataView body assert_equals: Request should have header content-type: null expected (object) null but got (string) "application/x-www-form-urlencoded"
    1015PASS Fetch with POST with Blob body with mime type
    1116FAIL Fetch with Chicken assert_equals: Request should have header content-length: null expected (object) null but got (string) "0"
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/request-headers.js

    r204225 r205115  
    1212
    1313    var expectedContentType = "text/plain;charset=UTF-8";
    14     if(body === null || body instanceof ArrayBuffer)
     14    if(body === null || body instanceof ArrayBuffer || body.buffer instanceof ArrayBuffer)
    1515        expectedContentType = null;
    1616    else if (body instanceof Blob)
     
    2929      assert_equals(resp.status, 200, "HTTP status is 200");
    3030      assert_equals(resp.type , "basic", "Response's type is basic");
    31       checkContentType(resp.headers.get("x-request-content-type"), body);
    32       if (expectedContentLength !== undefined)
    33         assert_equals(resp.headers.get("x-request-content-length") , expectedContentLength, "Request should have header content-length: " + expectedContentLength);
    3431      assert_true(resp.headers.has("x-request-user-agent"), "Request has header user-agent");
    3532      assert_false(resp.headers.has("accept-charset"), "Request has header accept-charset");
    3633      assert_equals(resp.headers.get("x-request-origin") , expectedOrigin, "Request should have header origin: " + expectedOrigin);
     34      if (expectedContentLength !== undefined)
     35        assert_equals(resp.headers.get("x-request-content-length") , expectedContentLength, "Request should have header content-length: " + expectedContentLength);
     36      checkContentType(resp.headers.get("x-request-content-type"), body);
    3737    });
    3838  }, desc);
     
    5151requestHeaders("Fetch with POST with Blob body", url, "POST", new Blob(["Test"]), location.origin, "4");
    5252requestHeaders("Fetch with POST with ArrayBuffer body", url, "POST", new ArrayBuffer(4), location.origin, "4");
     53requestHeaders("Fetch with POST with Uint8Array body", url, "POST", new Uint8Array(4), location.origin, "4");
     54requestHeaders("Fetch with POST with Int8Array body", url, "POST", new Int8Array(4), location.origin, "4");
     55requestHeaders("Fetch with POST with Float32Array body", url, "POST", new Float32Array(1), location.origin, "4");
     56requestHeaders("Fetch with POST with Float64Array body", url, "POST", new Float64Array(1), location.origin, "8");
     57requestHeaders("Fetch with POST with DataView body", url, "POST", new DataView(new ArrayBuffer(8), 0, 4), location.origin, "4");
    5358requestHeaders("Fetch with POST with Blob body with mime type", url, "POST", new Blob(["Test"], { type: "text/maybe" }), location.origin, "4");
    5459requestHeaders("Fetch with Chicken", url, "Chicken", null, location.origin, null);
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume-expected.txt

    r204171 r205115  
    11
    2 PASS Consume request's body as text
    3 PASS Consume request's body as blob
    4 PASS Consume request's body as arrayBuffer
    5 PASS Consume request's body as json
    6 FAIL Consume request's body as formData promise_test: Unhandled rejection with value: undefined
     2PASS Consume String request's body as text
     3PASS Consume String request's body as blob
     4PASS Consume String request's body as arrayBuffer
     5PASS Consume String request's body as JSON
     6PASS Consume ArrayBuffer request's body as text
     7PASS Consume ArrayBuffer request's body as blob
     8PASS Consume ArrayBuffer request's body as arrayBuffer
     9PASS Consume ArrayBuffer request's body as JSON
     10PASS Consume Uint8Array request's body as text
     11PASS Consume Uint8Array request's body as blob
     12PASS Consume Uint8Array request's body as arrayBuffer
     13PASS Consume Uint8Array request's body as JSON
     14PASS Consume Int8Array request's body as text
     15PASS Consume Int8Array request's body as blob
     16PASS Consume Int8Array request's body as arrayBuffer
     17PASS Consume Int8Array request's body as JSON
     18PASS Consume Float32Array request's body as text
     19PASS Consume Float32Array request's body as blob
     20PASS Consume Float32Array request's body as arrayBuffer
     21PASS Consume Float32Array request's body as JSON
     22PASS Consume DataView request's body as text
     23PASS Consume DataView request's body as blob
     24PASS Consume DataView request's body as arrayBuffer
     25PASS Consume DataView request's body as JSON
     26FAIL Consume FormData request's body as FormData promise_test: Unhandled rejection with value: undefined
    727PASS Consume blob response's body as blob
    828PASS Consume blob response's body as text
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-consume.html

    r205076 r205115  
    1414    <script>
    1515    function checkBodyText(request, expectedBody) {
    16       return request.text().then( function(bodyAsText) {
     16      return request.text().then(function(bodyAsText) {
    1717        assert_equals(bodyAsText, expectedBody, "Retrieve and verify request's body");
    1818        assert_true(request.bodyUsed, "body as text: bodyUsed turned true");
     
    6464    }
    6565
    66     function checkRequestBody(body, bodyType, checkFunction) {
     66    function checkRequestBody(body, expected, bodyType) {
    6767      promise_test(function(test) {
    6868        var request = new Request("", {"method": "POST", "body": body, "headers": [["Content-Type", "text/PLAIN"]] });
    6969        assert_false(request.bodyUsed, "bodyUsed is false at init");
    70         return checkFunction(request, body);
    71       }, "Consume request's body as " + bodyType);
     70        return checkBodyText(request, expected);
     71      }, "Consume " + bodyType  + " request's body as text");
     72      promise_test(function(test) {
     73        var request = new Request("", {"method": "POST", "body": body });
     74        assert_false(request.bodyUsed, "bodyUsed is false at init");
     75        return checkBodyBlob(request, expected);
     76      }, "Consume " + bodyType  + " request's body as blob");
     77      promise_test(function(test) {
     78        var request = new Request("", {"method": "POST", "body": body });
     79        assert_false(request.bodyUsed, "bodyUsed is false at init");
     80        return checkBodyArrayBuffer(request, expected);
     81      }, "Consume " + bodyType  + " request's body as arrayBuffer");
     82      promise_test(function(test) {
     83        var request = new Request("", {"method": "POST", "body": body });
     84        assert_false(request.bodyUsed, "bodyUsed is false at init");
     85        return checkBodyJSON(request, expected);
     86      }, "Consume " + bodyType  + " request's body as JSON");
    7287    }
    7388
    74     var formData = new FormData();
    75     formData.append("name", "value")
    7689    var textData = JSON.stringify("This is response's body");
    7790    var blob = new Blob([textData], { "type" : "text/plain" });
    7891
    79     checkRequestBody(textData, "text", checkBodyText);
    80     checkRequestBody(textData, "blob", function(request, body) { checkBodyBlob(request, body, true); });
    81     checkRequestBody(textData, "arrayBuffer", checkBodyArrayBuffer);
    82     checkRequestBody(textData, "json", checkBodyJSON);
    83     checkRequestBody(formData, "formData", checkBodyFormData);
     92    checkRequestBody(textData, textData, "String");
     93
     94    var string = "\"123456\"";
     95    function getArrayBuffer() {
     96        var arrayBuffer = new ArrayBuffer(8);
     97        var int8Array = new Int8Array(arrayBuffer);
     98        for (var cptr = 0; cptr < 8; cptr++)
     99            int8Array[cptr] = string.charCodeAt(cptr);
     100        return arrayBuffer;
     101    }
     102
     103    function getArrayBufferWithZeros() {
     104        var arrayBuffer = new ArrayBuffer(10);
     105        var int8Array = new Int8Array(arrayBuffer);
     106        for (var cptr = 0; cptr < 8; cptr++)
     107            int8Array[cptr + 1] = string.charCodeAt(cptr);
     108        return arrayBuffer;
     109    }
     110
     111    checkRequestBody(getArrayBuffer(), string, "ArrayBuffer");
     112    checkRequestBody(new Uint8Array(getArrayBuffer()), string, "Uint8Array");
     113    checkRequestBody(new Int8Array(getArrayBufferWithZeros(), 1, 8), string, "Int8Array");
     114    checkRequestBody(new Float32Array(getArrayBuffer()), string, "Float32Array");
     115    checkRequestBody(new DataView(getArrayBufferWithZeros(), 1, 8), string, "DataView");
     116
     117    promise_test(function(test) {
     118      var formData = new FormData();
     119      formData.append("name", "value")
     120      var request = new Request("", {"method": "POST", "body": formData });
     121      assert_false(request.bodyUsed, "bodyUsed is false at init");
     122      return checkBodyFormData(request, formData);
     123    }, "Consume FormData request's body as FormData");
    84124
    85125    function checkBlobResponseBody(blobBody, blobData, bodyType, checkFunction) {
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-stream-expected.txt

    r203408 r205115  
    44PASS Read blob response's body as readableStream
    55PASS Read text response's body as readableStream
     6PASS Read array buffer response's body as readableStream
    67FAIL Read form data response's body as readableStream promise_test: Unhandled rejection with value: "not implemented"
    78PASS Getting an error Response stream
  • trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-stream.html

    r202471 r205115  
    4141
    4242promise_test(function(test) {
     43    var arrayBuffer = new ArrayBuffer(textData.length);
     44    var int8Array = new Int8Array(arrayBuffer);
     45    for (var cptr = 0; cptr < textData.length; cptr++)
     46        int8Array[cptr] = textData.charCodeAt(cptr);
     47
     48    return validateStreamFromString(new Response(arrayBuffer).body.getReader(), textData);
     49}, "Read array buffer response's body as readableStream");
     50
     51promise_test(function(test) {
    4352    var response = new Response(formData);
    4453    return validateStreamFromString(response.body.getReader(), "name=value");
  • trunk/Source/WebCore/ChangeLog

    r205114 r205115  
     12016-08-29  Youenn Fablet  <youenn@apple.com>
     2
     3        [Fetch API] Add support for BufferSource bodies
     4        https://bugs.webkit.org/show_bug.cgi?id=161087
     5
     6        Reviewed by Darin Adler.
     7
     8        Covered by updated tests.
     9
     10        Added support for ArrayBuffer, ArrayBufferView and FormData upload.
     11        Added support for consuming ArrayBufferView.
     12
     13        To support FormData upload, FetchBOdy is now storing a FormData computed from the DOMFormData passed to the constructor.
     14        This allows setting the content-type for FormData correctly with the boundary parameter.
     15
     16        * Modules/fetch/FetchBody.cpp:
     17        (WebCore::FetchBody::bodyForInternalRequest): Adding support for FormData upload.
     18        (WebCore::FetchBody::FetchBody): Adding ArrayBuffer and ArrayBufferView constructors.
     19        (WebCore::FetchBody::extract): Extracting in case of BufferSource (i.e. ArrayBuffer or ArrayBufferView) and FormData.
     20        (WebCore::FetchBody::consume): Adding support to consume ArrayBufferView.
     21        (WebCore::FetchBody::consumeAsStream): Adding support to consume ArrayBufferView as a stream.
     22        Cloned the ArrayBuffer before enqueuing it in  the stream.
     23        (WebCore::FetchBody::consumeArrayBuffer): Cleaning m_data after being consumed.
     24        (WebCore::FetchBody::consumeArrayBufferView): Adding support to consume ArrayBufferView.
     25        (WebCore::FetchBody::consumeText): Cleaning m_text after being consumed.
     26        (WebCore::FetchBody::consumeBlob): Ditto for m_blob.
     27        (WebCore::FetchBody::bodyForInternalRequest): Adding support for ArrayBuffer and ArrayBufferView upload.
     28        * Modules/fetch/FetchBody.h:
     29        * Modules/fetch/FetchRequest.cpp:
     30        (WebCore::FetchRequest::internalRequest): Passing ScriptExecutionContext as this is needed for FormData upload.
     31        (WebCore::FetchRequest::setBody): Ditto.
     32        * Modules/fetch/FetchResponse.cpp:
     33        (WebCore::FetchResponse::initializeWith): Ditto.
     34        (WebCore::FetchResponse::fetch): Removing FormData upload rejection check.
     35
    1362016-08-26  Sergio Villar Senin  <svillar@igalia.com>
    237
  • trunk/Source/WebCore/Modules/fetch/FetchBody.cpp

    r205076 r205115  
    4343#include "JSReadableStream.h"
    4444#include "ReadableStreamSource.h"
     45#include <runtime/ArrayBufferView.h>
    4546
    4647namespace WebCore {
     
    5354}
    5455
    55 FetchBody::FetchBody(Ref<DOMFormData>&& formData)
     56FetchBody::FetchBody(DOMFormData& formData, Document& document)
    5657    : m_type(Type::FormData)
    5758    , m_contentType(ASCIILiteral("multipart/form-data"))
    58     , m_formData(WTFMove(formData))
    59 {
    60     // FIXME: Handle the boundary parameter of multipart/form-data MIME type.
     59{
     60    m_formData = FormData::createMultiPart(formData, formData.encoding(), &document);
     61    m_contentType = makeString("multipart/form-data;boundary=", m_formData->boundary().data());
    6162}
    6263
     
    6869}
    6970
    70 FetchBody FetchBody::extract(JSC::ExecState& state, JSC::JSValue value)
     71FetchBody::FetchBody(Ref<ArrayBuffer>&& data)
     72    : m_type(Type::ArrayBuffer)
     73    , m_data(WTFMove(data))
     74{
     75}
     76
     77FetchBody::FetchBody(Ref<ArrayBufferView>&& dataView)
     78    : m_type(Type::ArrayBufferView)
     79    , m_dataView(WTFMove(dataView))
     80{
     81}
     82
     83FetchBody FetchBody::extract(ScriptExecutionContext& context, JSC::ExecState& state, JSC::JSValue value)
    7184{
    7285    if (value.inherits(JSBlob::info()))
    7386        return FetchBody(*JSBlob::toWrapped(value));
    74     if (value.inherits(JSDOMFormData::info()))
    75         return FetchBody(*JSDOMFormData::toWrapped(value));
     87    if (value.inherits(JSDOMFormData::info())) {
     88        ASSERT(!context.isWorkerGlobalScope());
     89        return FetchBody(*JSDOMFormData::toWrapped(value), static_cast<Document&>(context));
     90    }
    7691    if (value.isString())
    7792        return FetchBody(value.toWTFString(&state));
    7893    if (value.inherits(JSReadableStream::info()))
    7994        return { Type::ReadableStream };
    80     // FIXME: Implement BufferSource extraction.
     95    if (value.inherits(JSC::JSArrayBuffer::info())) {
     96        ArrayBuffer* data = toArrayBuffer(value);
     97        ASSERT(data);
     98        return { *data };
     99    }
     100    if (value.inherits(JSC::JSArrayBufferView::info())) {
     101        RefPtr<JSC::ArrayBufferView> data = toArrayBufferView(value);
     102        ASSERT(data);
     103        return { data.releaseNonNull() };
     104    }
    81105    return { };
    82106}
     
    151175        consumeArrayBuffer(promise);
    152176        return;
     177    case Type::ArrayBufferView:
     178        consumeArrayBufferView(promise);
     179        return;
    153180    case Type::Text:
    154181        consumeText(promise);
     
    163190        m_consumer.resolve(promise);
    164191        return;
     192    case Type::FormData:
     193        // FIXME: Support consuming FormData.
     194        promise.reject(0);
     195        return;
    165196    default:
    166         // FIXME: Support other types.
    167         promise.reject(0);
     197        ASSERT_NOT_REACHED();
    168198    }
    169199}
     
    181211    case Type::ArrayBuffer:
    182212        ASSERT(m_data);
    183         closeStream = source.enqueue(RefPtr<JSC::ArrayBuffer>(m_data));
    184         break;
     213        closeStream = source.enqueue(ArrayBuffer::tryCreate(m_data->data(), m_data->byteLength()));
     214        m_data = nullptr;
     215        break;
     216    case Type::ArrayBufferView: {
     217        ASSERT(m_dataView);
     218        closeStream = source.enqueue(ArrayBuffer::tryCreate(m_dataView->baseAddress(), m_dataView->byteLength()));
     219        m_dataView = nullptr;
     220        break;
     221    }
    185222    case Type::Text: {
    186223        Vector<uint8_t> data = extractFromText();
    187224        closeStream = source.enqueue(ArrayBuffer::tryCreate(data.data(), data.size()));
     225        m_text = { };
    188226        break;
    189227    }
     
    191229        ASSERT(m_blob);
    192230        owner.loadBlob(*m_blob, nullptr);
     231        m_blob = nullptr;
    193232        break;
    194233    case Type::None:
     
    210249void FetchBody::consumeArrayBuffer(DeferredWrapper& promise)
    211250{
     251    ASSERT(m_data);
    212252    m_consumer.resolveWithData(promise, static_cast<const uint8_t*>(m_data->data()), m_data->byteLength());
     253    m_data = nullptr;
     254}
     255
     256void FetchBody::consumeArrayBufferView(DeferredWrapper& promise)
     257{
     258    ASSERT(m_dataView);
     259    m_consumer.resolveWithData(promise, static_cast<const uint8_t*>(m_dataView->baseAddress()), m_dataView->byteLength());
     260    m_dataView = nullptr;
    213261}
    214262
     
    217265    Vector<uint8_t> data = extractFromText();
    218266    m_consumer.resolveWithData(promise, data.data(), data.size());
     267    m_text = { };
    219268}
    220269
     
    225274    m_consumePromise = WTFMove(promise);
    226275    owner.loadBlob(*m_blob, &m_consumer);
     276    m_blob = nullptr;
    227277}
    228278
     
    254304}
    255305
    256 RefPtr<FormData> FetchBody::bodyForInternalRequest() const
    257 {
    258     if (m_type == Type::None)
     306RefPtr<FormData> FetchBody::bodyForInternalRequest(ScriptExecutionContext& context) const
     307{
     308    switch (m_type) {
     309    case Type::None:
    259310        return nullptr;
    260     if (m_type == Type::Text)
     311    case Type::Text:
    261312        return FormData::create(UTF8Encoding().encode(m_text, EntitiesForUnencodables));
    262     if (m_type == Type::Blob) {
     313    case Type::Blob: {
     314        ASSERT(m_blob);
    263315        RefPtr<FormData> body = FormData::create();
    264316        body->appendBlob(m_blob->url());
    265317        return body;
    266318    }
    267     ASSERT_NOT_REACHED();
    268     return nullptr;
     319    case Type::ArrayBuffer:
     320        ASSERT(m_data);
     321        return FormData::create(m_data->data(), m_data->byteLength());
     322    case Type::ArrayBufferView:
     323        ASSERT(m_dataView);
     324        return FormData::create(m_dataView->baseAddress(), m_dataView->byteLength());
     325    case Type::FormData: {
     326        ASSERT(m_formData);
     327        ASSERT(!context.isWorkerGlobalScope());
     328        auto body = m_formData;
     329        body->generateFiles(static_cast<Document*>(&context));
     330        return body;
     331    }
     332    default:
     333        ASSERT_NOT_REACHED();
     334        return nullptr;
     335    }
    269336}
    270337
  • trunk/Source/WebCore/Modules/fetch/FetchBody.h

    r205076 r205115  
    3333
    3434#include "Blob.h"
    35 #include "DOMFormData.h"
    3635#include "FetchBodyConsumer.h"
    3736#include "FetchLoader.h"
     37#include "FormData.h"
    3838#include "JSDOMPromise.h"
    3939
     
    4545namespace WebCore {
    4646
     47class DOMFormData;
    4748class FetchBodyOwner;
    4849class FetchHeaders;
    4950class FetchResponseSource;
    50 class FormData;
     51class ScriptExecutionContext;
    5152
    5253class FetchBody {
     
    6869    String contentType() const { return m_contentType; }
    6970
    70     static FetchBody extract(JSC::ExecState&, JSC::JSValue);
     71    static FetchBody extract(ScriptExecutionContext&, JSC::ExecState&, JSC::JSValue);
    7172    static FetchBody extractFromBody(FetchBody*);
    7273    static FetchBody loadingBody() { return { Type::Loading }; }
     
    7677    void loadingSucceeded();
    7778
    78     RefPtr<FormData> bodyForInternalRequest() const;
     79    RefPtr<FormData> bodyForInternalRequest(ScriptExecutionContext&) const;
    7980
    80     enum class Type { None, ArrayBuffer, Blob, FormData, Text, Loading, Loaded, ReadableStream };
     81    enum class Type { None, ArrayBuffer, ArrayBufferView, Blob, FormData, Text, Loading, Loaded, ReadableStream };
    8182    Type type() const { return m_type; }
    8283
     
    8788private:
    8889    FetchBody(Ref<Blob>&&);
    89     FetchBody(Ref<DOMFormData>&&);
     90    FetchBody(Ref<ArrayBuffer>&&);
     91    FetchBody(Ref<ArrayBufferView>&&);
     92    FetchBody(DOMFormData&, Document&);
    9093    FetchBody(String&&);
    9194    FetchBody(Type type) : m_type(type) { }
     
    9598    Vector<uint8_t> extractFromText() const;
    9699    void consumeArrayBuffer(DeferredWrapper&);
     100    void consumeArrayBufferView(DeferredWrapper&);
    97101    void consumeText(DeferredWrapper&);
    98102    void consumeBlob(FetchBodyOwner&, DeferredWrapper&&);
     
    101105    String m_contentType;
    102106
    103     // FIXME: Add support for BufferSource and URLSearchParams.
     107    // FIXME: Add support for URLSearchParams.
    104108    RefPtr<Blob> m_blob;
    105     RefPtr<DOMFormData> m_formData;
     109    RefPtr<FormData> m_formData;
    106110    RefPtr<ArrayBuffer> m_data;
     111    RefPtr<ArrayBufferView> m_dataView;
    107112    String m_text;
    108113
  • trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp

    r205076 r205115  
    258258{
    259259    if (!body.isNull()) {
    260         m_body = FetchBody::extract(execState, body);
     260        ASSERT(scriptExecutionContext());
     261        m_body = FetchBody::extract(*scriptExecutionContext(), execState, body);
    261262        if (m_body.type() == FetchBody::Type::None) {
    262263            ec = TypeError;
     
    293294ResourceRequest FetchRequest::internalRequest() const
    294295{
     296    ASSERT(scriptExecutionContext());
     297
    295298    ResourceRequest request = m_internalRequest.request;
    296299    request.setHTTPHeaderFields(m_headers->internalHeaders());
    297     request.setHTTPBody(body().bodyForInternalRequest());
     300    request.setHTTPBody(body().bodyForInternalRequest(*scriptExecutionContext()));
    298301
    299302    // FIXME: Support no-referrer and client. Ensure this case-sensitive comparison is ok.
  • trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp

    r205110 r205115  
    8383void FetchResponse::initializeWith(JSC::ExecState& execState, JSC::JSValue body)
    8484{
    85     m_body = FetchBody::extract(execState, body);
     85    ASSERT(scriptExecutionContext());
     86    m_body = FetchBody::extract(*scriptExecutionContext(), execState, body);
    8687    m_body.updateContentType(m_headers);
    8788}
     
    105106    auto response = adoptRef(*new FetchResponse(context, FetchBody::loadingBody(), FetchHeaders::create(FetchHeaders::Guard::Immutable), { }));
    106107
    107     // FIXME: Implement form data upload.
    108     if (request.bodyType() == FetchBody::Type::FormData) {
    109         promise.reject(TypeError, "Uploading FormData is not yet implemented");
    110         return;
    111     }
    112108    // Setting pending activity until BodyLoader didFail or didSucceed callback is called.
    113109    response->setPendingActivity(response.ptr());
Note: See TracChangeset for help on using the changeset viewer.