[Fetch API] Response constructor should be able to take a ReadableStream as body
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Jul 2016 16:03:01 +0000 (16:03 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Jul 2016 16:03:01 +0000 (16:03 +0000)
commitffcb250c12ecb8ae88a49a9d86978de5085adf99
treee17b1d91114a0eaf42834a74bc42273e7172d7de
parent15af2c50cb3511b331a7ccad240fae01825eeb43
[Fetch API] Response constructor should be able to take a ReadableStream as body
https://bugs.webkit.org/show_bug.cgi?id=159804

Patch by Youenn Fablet <youenn@apple.com> on 2016-07-26
Reviewed by Alex Christensen.

LayoutTests/imported/w3c:

* web-platform-tests/fetch/api/response/response-consume-empty-expected.txt:
* web-platform-tests/fetch/api/response/response-consume-expected.txt:
* web-platform-tests/fetch/api/response/response-consume.html: Updating test to exercice Response coonstructor with a ReadableStream.

Source/WebCore:

Covered by existing and updated tests.

Introduced FetchBodyConsumer to encapsulate the code responsible to adapt FetchBody internal data to the requests made by user scripts.
This refactoring eases the handling of internal data coming from ReadableStream.

FetchLoader is now delegating conversion from the data to its m_consumer field.
If m_consumer is null, FetchLoader calls FetchLoaderClient::didReceiveData (streaming reception mode).
Clients of FetchLoader needs to pass a FetchBodyConsumer to the FetchLoader to do the data adaptation at loader creation time.

Added support for body data passed as a ReadableStream to Response.
This requires to set @body internal slot of the Response object in the constructor initialization JS built-in.

To actually use that data, Body accessors are also implemented as JS built-in for Response.
Since there is no need to do so for Request, FetchResponse is no longer marked as implementing FetchBody but all
FetchBody IDL description is inlined in FetchResponse.idl.

For each body accessor (arrayBuffer, blob, json, text), the corresponding JS built-in checks whether @body internal slot is set.
If that is not the case, regular handling is done through a new private method called @consume.
If @body internal slot is set, chunks are pumped from the ReadableStream using ReadableStream internal built-ins functions.
Data handling is done in C++ through the private methods @startConsumingStream, @consumeChunk and @finishConsumingStream.

To support cloning of Response with bodies, clone method is also implemented as a JS built-in.
Main clone is done through @cloneFoJS private method implemented in C++.
JS built-in clone code does the teeing of the ReadableStream using ReadableStream JS built-in internal functions.

Introducing a new ReadableStream type for FetchBody to cope with body being stored in a ReadableStream.

Introducing a new Loaded type for FetchBody to cope with body being stored in the FetchBodyConsumer owned by FetchBody.
This allows removing the conversion of data to JSC::ArrayBuffer which was done by defaut at the end of Fetch loading if user script did not request data before.
At the end of a load, the data remains in FetchBodyConsumer and the body is marked as Loaded.
If the user wants to get the data after data finished being loaded, FetchBodyConsumer will do the required conversions.

Introducing DeferredWrapper::resolveWithNewValue to handle the case of resolving promises with new objects.
This allows directly using toJSNewlyCreated instead of toJS.

* CMakeLists.txt: Adding FetchBodyConsumer.
* Modules/fetch/FetchBody.cpp: Moving data adaptation code to FetchBodyConsumer.
(WebCore::FetchBody::extract):
(WebCore::FetchBody::arrayBuffer):
(WebCore::FetchBody::blob): Setting contentType in FetchBodyConsumer to handle proper creation of blob.
(WebCore::FetchBody::json):
(WebCore::FetchBody::text):
(WebCore::FetchBody::consume): Refactoring and added case of Loaded bodies.
(WebCore::FetchBody::consumeAsStream): Ditto.
(WebCore::FetchBody::consumeArrayBuffer):
(WebCore::FetchBody::consumeText):
(WebCore::FetchBody::consumeBlob):
(WebCore::FetchBody::loadingFailed):
(WebCore::FetchBody::loadingSucceeded):
(WebCore::FetchBody::loadingType): Deleted.
(WebCore::blobFromArrayBuffer): Deleted.
(WebCore::FetchBody::fulfillTextPromise): Deleted.
(WebCore::FetchBody::loadedAsArrayBuffer): Deleted.
(WebCore::FetchBody::loadedAsText): Deleted.
* Modules/fetch/FetchBody.h:
(WebCore::FetchBody::consumer):
* Modules/fetch/FetchBodyConsumer.cpp: Added, responsible of data adaptation.
(WebCore::blobFromData):
(WebCore::FetchBodyConsumer::resolveWithData):
(WebCore::FetchBodyConsumer::resolve):
(WebCore::FetchBodyConsumer::append):
(WebCore::FetchBodyConsumer::takeData):
(WebCore::FetchBodyConsumer::takeAsArrayBuffer):
(WebCore::FetchBodyConsumer::takeAsBlob):
(WebCore::FetchBodyConsumer::takeAsText):
* Modules/fetch/FetchBodyConsumer.h: Added.
(WebCore::FetchBodyConsumer::FetchBodyConsumer):
(WebCore::FetchBodyConsumer::setContentType):
(WebCore::FetchBodyConsumer::setType):
(WebCore::FetchBodyConsumer::type):
(WebCore::FetchBodyConsumer::clean):
(WebCore::FetchBodyConsumer::hasData):
* Modules/fetch/FetchBodyOwner.cpp:
(WebCore::FetchBodyOwner::loadBlob):
(WebCore::FetchBodyOwner::blobLoadingSucceeded):
(WebCore::FetchBodyOwner::loadedBlobAsText): Deleted.
* Modules/fetch/FetchBodyOwner.h:
(WebCore::FetchBodyOwner::loadedBlobAsArrayBuffer): Deleted.
* Modules/fetch/FetchInternals.js:
(consumeStream): Pump ReadableStream data and send it to FetchResponse to be converted according user need.
* Modules/fetch/FetchLoader.cpp:
(WebCore::FetchLoader::FetchLoader): FetchLoader is simplified as it has two nodes: consumer mode in which case
data is sent to the consumer and no-consumer mode in which case data is passed to loader client. The second mode
is used to conveyy data to ReadableStream source.
(WebCore::FetchLoader::stop):
(WebCore::FetchLoader::startStreaming):
(WebCore::FetchLoader::didReceiveData):
(WebCore::FetchLoader::didFinishLoading): Deleted.
* Modules/fetch/FetchLoader.h:
* Modules/fetch/FetchLoaderClient.h:
(WebCore::FetchLoaderClient::didFinishLoadingAsText): Deleted.
(WebCore::FetchLoaderClient::didFinishLoadingAsArrayBuffer): Deleted.
* Modules/fetch/FetchResponse.cpp:
(WebCore::FetchResponse::cloneForJS):
(WebCore::FetchResponse::BodyLoader::didSucceed):
(WebCore::FetchResponse::BodyLoader::start):
(WebCore::FetchResponse::consume): Introduced to consume data stored in body and not in ReadableStream.
(WebCore::FetchResponse::startConsumingStream): Introduced to start process of consuming data stored in the ReadableStream.
(WebCore::FetchResponse::consumeChunk): Reception of ReadableStream data.
(WebCore::FetchResponse::finishConsumingStream): Doing the final conversion.
(WebCore::FetchResponse::clone): Deleted.
(WebCore::FetchResponse::BodyLoader::didFinishLoadingAsArrayBuffer): Deleted.
* Modules/fetch/FetchResponse.h:
* Modules/fetch/FetchResponse.idl: Inlining of FetchBody methods/attributes and adding private methods.
* Modules/fetch/FetchResponse.js:
(initializeFetchResponse):
(clone):
(arrayBuffer):
(blob):
(formData):
(json):
(text):
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMPromise.h:
(WebCore::DeferredWrapper::resolveWithNewValue):
* bindings/js/WebCoreBuiltinNames.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203719 268f45cc-cd09-0410-ab3c-d52691b4dbfc
23 files changed:
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-empty-expected.txt
LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume-expected.txt
LayoutTests/imported/w3c/web-platform-tests/fetch/api/response/response-consume.html
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/fetch/FetchBody.cpp
Source/WebCore/Modules/fetch/FetchBody.h
Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp [new file with mode: 0644]
Source/WebCore/Modules/fetch/FetchBodyConsumer.h [new file with mode: 0644]
Source/WebCore/Modules/fetch/FetchBodyOwner.cpp
Source/WebCore/Modules/fetch/FetchBodyOwner.h
Source/WebCore/Modules/fetch/FetchInternals.js
Source/WebCore/Modules/fetch/FetchLoader.cpp
Source/WebCore/Modules/fetch/FetchLoader.h
Source/WebCore/Modules/fetch/FetchLoaderClient.h
Source/WebCore/Modules/fetch/FetchResponse.cpp
Source/WebCore/Modules/fetch/FetchResponse.h
Source/WebCore/Modules/fetch/FetchResponse.idl
Source/WebCore/Modules/fetch/FetchResponse.js
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSDOMPromise.h
Source/WebCore/bindings/js/WebCoreBuiltinNames.h