Title: [221504] trunk
Revision
221504
Author
commit-qu...@webkit.org
Date
2017-09-01 15:53:23 -0700 (Fri, 01 Sep 2017)

Log Message

[Fetch API] Add support for consuming a Request ReadableStream body
https://bugs.webkit.org/show_bug.cgi?id=176182

Patch by Youenn Fablet <you...@apple.com> on 2017-09-01
Reviewed by Alex Christensen.

Source/WebCore:

Tests: http/wpt/fetch/request-stream-empty.html
       http/wpt/fetch/request-stream-error.html

Adding a ReadableStreamSink which allows to pipe all ReadableStream data back to C++ code.
This sink only takes BufferSource as the only user is Fetch which has this restriction.
This sink is tied to the readableStreamPipeTo builtin internal function that reads all data from the ReadableStream
and send it to the sink.

Adding a ReadableStreamToSharedBufferSink specialization to get the data as a SharedBuffer.

Use that class in FetchBodyConsumer to get the data back from the ReadableStream and transform it according
the desired body type (text, JSON, ArrayBuffer).

* CMakeLists.txt:
* DerivedSources.make:
* Modules/fetch/FetchBody.cpp:
(WebCore::FetchBody::consume):
(WebCore::FetchBody::loadingSucceeded):
* Modules/fetch/FetchBodyConsumer.cpp:
(WebCore::resolveWithTypeAndData):
(WebCore::FetchBodyConsumer::clean):
(WebCore::FetchBodyConsumer::resolveWithData):
(WebCore::FetchBodyConsumer::resolve):
* Modules/fetch/FetchBodyConsumer.h:
* Modules/fetch/FetchResponse.cpp:
(WebCore::FetchResponse::finishConsumingStream):
* Modules/streams/ReadableStreamInternals.js:
(readableStreamPipeTo):
* Modules/streams/ReadableStreamSink.cpp: Added.
(WebCore::ReadableStreamToSharedBufferSink::ReadableStreamToSharedBufferSink):
(WebCore::ReadableStreamToSharedBufferSink::pipeFrom):
(WebCore::ReadableStreamToSharedBufferSink::enqueue):
(WebCore::ReadableStreamToSharedBufferSink::close):
(WebCore::ReadableStreamToSharedBufferSink::error):
* Modules/streams/ReadableStreamSink.h: Added.
* Modules/streams/ReadableStreamSink.idl: Added.
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/ReadableStream.cpp:
(WebCore::ReadableStream::pipeTo):
* bindings/js/ReadableStream.h:

LayoutTests:

* http/wpt/fetch/request-stream-disturbed-1-expected.txt:
* http/wpt/fetch/request-stream-disturbed-2-expected.txt:
* http/wpt/fetch/request-stream-disturbed-3-expected.txt:
* http/wpt/fetch/request-stream-empty-expected.txt: Added.
* http/wpt/fetch/request-stream-empty.html: Added.
* http/wpt/fetch/request-stream-error-expected.txt: Added.
* http/wpt/fetch/request-stream-error.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (221503 => 221504)


--- trunk/LayoutTests/ChangeLog	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/LayoutTests/ChangeLog	2017-09-01 22:53:23 UTC (rev 221504)
@@ -1,3 +1,18 @@
+2017-09-01  Youenn Fablet  <you...@apple.com>
+
+        [Fetch API] Add support for consuming a Request ReadableStream body
+        https://bugs.webkit.org/show_bug.cgi?id=176182
+
+        Reviewed by Alex Christensen.
+
+        * http/wpt/fetch/request-stream-disturbed-1-expected.txt:
+        * http/wpt/fetch/request-stream-disturbed-2-expected.txt:
+        * http/wpt/fetch/request-stream-disturbed-3-expected.txt:
+        * http/wpt/fetch/request-stream-empty-expected.txt: Added.
+        * http/wpt/fetch/request-stream-empty.html: Added.
+        * http/wpt/fetch/request-stream-error-expected.txt: Added.
+        * http/wpt/fetch/request-stream-error.html: Added.
+
 2017-09-01  Per Arne Vollan  <pvol...@apple.com>
 
         http/tests/misc/slow-loading-animated-image.html is flaky on iOS simulator and Windows.

Modified: trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-1-expected.txt (221503 => 221504)


--- trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-1-expected.txt	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-1-expected.txt	2017-09-01 22:53:23 UTC (rev 221504)
@@ -1,6 +1,6 @@
 
 PASS Getting blob after getting the Request body - not disturbed, not locked 
-FAIL Getting text after getting the Request body - not disturbed, not locked assert_true: expected true got false
-FAIL Getting json after getting the Request body - not disturbed, not locked promise_test: Unhandled rejection with value: object "SyntaxError: The string did not match the expected pattern."
-FAIL Getting arrayBuffer after getting the Request body - not disturbed, not locked assert_true: expected true got false
+PASS Getting text after getting the Request body - not disturbed, not locked 
+PASS Getting json after getting the Request body - not disturbed, not locked 
+PASS Getting arrayBuffer after getting the Request body - not disturbed, not locked 
 

Modified: trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-2-expected.txt (221503 => 221504)


--- trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-2-expected.txt	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-2-expected.txt	2017-09-01 22:53:23 UTC (rev 221504)
@@ -1,6 +1,6 @@
 
-FAIL Getting blob after getting a locked Request body assert_unreached: Should have rejected: undefined Reached unreachable code
-FAIL Getting text after getting a locked Request body assert_unreached: Should have rejected: undefined Reached unreachable code
-FAIL Getting json after getting a locked Request body assert_throws: function "function () { throw e }" threw object "SyntaxError: The string did not match the expected pattern." ("SyntaxError") expected object "TypeError" ("TypeError")
-FAIL Getting arrayBuffer after getting a locked Request body assert_unreached: Should have rejected: undefined Reached unreachable code
+PASS Getting blob after getting a locked Request body 
+PASS Getting text after getting a locked Request body 
+PASS Getting json after getting a locked Request body 
+PASS Getting arrayBuffer after getting a locked Request body 
 

Modified: trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-3-expected.txt (221503 => 221504)


--- trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-3-expected.txt	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/LayoutTests/http/wpt/fetch/request-stream-disturbed-3-expected.txt	2017-09-01 22:53:23 UTC (rev 221504)
@@ -1,6 +1,6 @@
 
-FAIL Getting blob after reading the Request body assert_unreached: Should have rejected: undefined Reached unreachable code
-FAIL Getting text after reading the Request body assert_unreached: Should have rejected: undefined Reached unreachable code
-FAIL Getting json after reading the Request body assert_throws: function "function () { throw e }" threw object "SyntaxError: The string did not match the expected pattern." ("SyntaxError") expected object "TypeError" ("TypeError")
-FAIL Getting arrayBuffer after reading the Request body assert_unreached: Should have rejected: undefined Reached unreachable code
+PASS Getting blob after reading the Request body 
+PASS Getting text after reading the Request body 
+PASS Getting json after reading the Request body 
+PASS Getting arrayBuffer after reading the Request body 
 

Added: trunk/LayoutTests/http/wpt/fetch/request-stream-empty-expected.txt (0 => 221504)


--- trunk/LayoutTests/http/wpt/fetch/request-stream-empty-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/request-stream-empty-expected.txt	2017-09-01 22:53:23 UTC (rev 221504)
@@ -0,0 +1,10 @@
+
+PASS Empty stream body as text 
+PASS Empty stream body as arrayBuffer 
+PASS Empty stream body as JSON 
+PASS Empty stream body as blob 
+PASS Empty chunk stream body as text 
+PASS Empty chunk stream body as arrayBuffer 
+PASS Empty chunk stream body as JSON 
+PASS Empty chunk stream body as blob 
+

Added: trunk/LayoutTests/http/wpt/fetch/request-stream-empty.html (0 => 221504)


--- trunk/LayoutTests/http/wpt/fetch/request-stream-empty.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/request-stream-empty.html	2017-09-01 22:53:23 UTC (rev 221504)
@@ -0,0 +1,89 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Consuming Request body with non BufferSource ReadableStream chunks</title>
+    <script src=""
+    <script src=""
+  </head>
+  <body>
+    <script>
+function createRequestWithEmptyReadableStream()
+{
+    var stream = new ReadableStream({start: controller => {
+        controller.close();
+    }});
+    return new Request("", {body: stream, method: "POST"});
+}
+
+function createRequestWithEmptyChunkReadableStream()
+{
+    var stream = new ReadableStream({start: controller => {
+        controller.enqueue(new Uint8Array(0));
+        controller.close();
+    }});
+    return new Request("", {body: stream, method: "POST"});
+}
+
+promise_test(test => {
+    return createRequestWithEmptyReadableStream().text().then(text => {
+        assert_equals(text, "");
+    });
+}, "Empty stream body as text");
+
+promise_test(test => {
+    return createRequestWithEmptyReadableStream().arrayBuffer().then(buffer => {
+        assert_equals(buffer.byteLength, 0, "Resolved value should be empty");
+    });
+}, "Empty stream body as arrayBuffer");
+
+promise_test(test => {
+    return promise_rejects(test, "SyntaxError", createRequestWithEmptyReadableStream().json());
+}, "Empty stream body as JSON");
+
+promise_test(test => {
+    return createRequestWithEmptyReadableStream().blob().then(function(bodyAsBlob) {
+        var promise = new Promise(function(resolve, reject) {
+            var reader = new FileReader();
+            reader._onload_ = () => { resolve(reader.result) };
+            reader._onerror_ = () => { reject("Blob's reader failed"); };
+            reader.readAsText(bodyAsBlob);
+        });
+        return promise.then(function(body) {
+            assert_equals(body, "", "Resolved value should be empty");
+        });
+  });
+}, "Empty stream body as blob");
+
+promise_test(test => {
+    return createRequestWithEmptyChunkReadableStream().text().then(text => {
+        assert_equals(text, "");
+    });
+}, "Empty chunk stream body as text");
+
+promise_test(test => {
+    return createRequestWithEmptyChunkReadableStream().arrayBuffer().then(buffer => {
+        assert_equals(buffer.byteLength, 0, "Resolved value should be empty");
+    });
+}, "Empty chunk stream body as arrayBuffer");
+
+promise_test(test => {
+    return promise_rejects(test, "SyntaxError", createRequestWithEmptyReadableStream().json());
+}, "Empty chunk stream body as JSON");
+
+promise_test(test => {
+    return createRequestWithEmptyChunkReadableStream().blob().then(function(bodyAsBlob) {
+        var promise = new Promise(function(resolve, reject) {
+            var reader = new FileReader();
+            reader._onload_ = () => { resolve(reader.result) };
+            reader._onerror_ = () => { reject("Blob's reader failed"); };
+            reader.readAsText(bodyAsBlob);
+        });
+        return promise.then(function(body) {
+            assert_equals(body, "", "Resolved value should be empty");
+        });
+  });
+}, "Empty chunk stream body as blob");
+    </script>
+  </body>
+</html>

Added: trunk/LayoutTests/http/wpt/fetch/request-stream-error-expected.txt (0 => 221504)


--- trunk/LayoutTests/http/wpt/fetch/request-stream-error-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/request-stream-error-expected.txt	2017-09-01 22:53:23 UTC (rev 221504)
@@ -0,0 +1,3 @@
+
+PASS Request body should only contain BufferSource chunks 
+

Added: trunk/LayoutTests/http/wpt/fetch/request-stream-error.html (0 => 221504)


--- trunk/LayoutTests/http/wpt/fetch/request-stream-error.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/request-stream-error.html	2017-09-01 22:53:23 UTC (rev 221504)
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Consuming Request body with non BufferSource ReadableStream chunks</title>
+    <script src=""
+    <script src=""
+  </head>
+  <body>
+    <script>
+promise_test(test => {
+    var stream = new ReadableStream({start: controller => {
+        controller.enqueue("This is not a buffer");
+        controller.close();
+    }});
+    var request = new Request("", {body: stream, method: "POST"});
+    return promise_rejects(test, new TypeError, request.text());
+}, "Request body should only contain BufferSource chunks");
+    </script>
+  </body>
+</html>

Modified: trunk/Source/WebCore/CMakeLists.txt (221503 => 221504)


--- trunk/Source/WebCore/CMakeLists.txt	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/CMakeLists.txt	2017-09-01 22:53:23 UTC (rev 221504)
@@ -325,6 +325,7 @@
     Modules/streams/ReadableStreamBYOBRequest.idl
     Modules/streams/ReadableStreamDefaultController.idl
     Modules/streams/ReadableStreamDefaultReader.idl
+    Modules/streams/ReadableStreamSink.idl
     Modules/streams/ReadableStreamSource.idl
     Modules/streams/WritableStream.idl
 
@@ -1070,6 +1071,8 @@
     Modules/speech/SpeechSynthesisUtterance.cpp
     Modules/speech/SpeechSynthesisVoice.cpp
 
+    Modules/streams/ReadableStreamSink.cpp
+
     Modules/webaudio/AnalyserNode.cpp
     Modules/webaudio/AsyncAudioDecoder.cpp
     Modules/webaudio/AudioBasicInspectorNode.cpp

Modified: trunk/Source/WebCore/ChangeLog (221503 => 221504)


--- trunk/Source/WebCore/ChangeLog	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/ChangeLog	2017-09-01 22:53:23 UTC (rev 221504)
@@ -1,3 +1,51 @@
+2017-09-01  Youenn Fablet  <you...@apple.com>
+
+        [Fetch API] Add support for consuming a Request ReadableStream body
+        https://bugs.webkit.org/show_bug.cgi?id=176182
+
+        Reviewed by Alex Christensen.
+
+        Tests: http/wpt/fetch/request-stream-empty.html
+               http/wpt/fetch/request-stream-error.html
+
+        Adding a ReadableStreamSink which allows to pipe all ReadableStream data back to C++ code.
+        This sink only takes BufferSource as the only user is Fetch which has this restriction.
+        This sink is tied to the readableStreamPipeTo builtin internal function that reads all data from the ReadableStream
+        and send it to the sink.
+
+        Adding a ReadableStreamToSharedBufferSink specialization to get the data as a SharedBuffer.
+
+        Use that class in FetchBodyConsumer to get the data back from the ReadableStream and transform it according
+        the desired body type (text, JSON, ArrayBuffer).
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * Modules/fetch/FetchBody.cpp:
+        (WebCore::FetchBody::consume):
+        (WebCore::FetchBody::loadingSucceeded):
+        * Modules/fetch/FetchBodyConsumer.cpp:
+        (WebCore::resolveWithTypeAndData):
+        (WebCore::FetchBodyConsumer::clean):
+        (WebCore::FetchBodyConsumer::resolveWithData):
+        (WebCore::FetchBodyConsumer::resolve):
+        * Modules/fetch/FetchBodyConsumer.h:
+        * Modules/fetch/FetchResponse.cpp:
+        (WebCore::FetchResponse::finishConsumingStream):
+        * Modules/streams/ReadableStreamInternals.js:
+        (readableStreamPipeTo):
+        * Modules/streams/ReadableStreamSink.cpp: Added.
+        (WebCore::ReadableStreamToSharedBufferSink::ReadableStreamToSharedBufferSink):
+        (WebCore::ReadableStreamToSharedBufferSink::pipeFrom):
+        (WebCore::ReadableStreamToSharedBufferSink::enqueue):
+        (WebCore::ReadableStreamToSharedBufferSink::close):
+        (WebCore::ReadableStreamToSharedBufferSink::error):
+        * Modules/streams/ReadableStreamSink.h: Added.
+        * Modules/streams/ReadableStreamSink.idl: Added.
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/ReadableStream.cpp:
+        (WebCore::ReadableStream::pipeTo):
+        * bindings/js/ReadableStream.h:
+
 2017-09-01  Emilio Cobos Álvarez  <emi...@crisal.io>
 
         Wrong getComputedStyle behavior for pseudo-elements for layout-dependent properties.

Modified: trunk/Source/WebCore/DerivedSources.make (221503 => 221504)


--- trunk/Source/WebCore/DerivedSources.make	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/DerivedSources.make	2017-09-01 22:53:23 UTC (rev 221504)
@@ -276,6 +276,7 @@
     $(WebCore)/Modules/streams/ReadableStreamBYOBRequest.idl \
     $(WebCore)/Modules/streams/ReadableStreamDefaultController.idl \
     $(WebCore)/Modules/streams/ReadableStreamDefaultReader.idl \
+    $(WebCore)/Modules/streams/ReadableStreamSink.idl \
     $(WebCore)/Modules/streams/ReadableStreamSource.idl \
     $(WebCore)/Modules/streams/WritableStream.idl \
     $(WebCore)/Modules/webaudio/AnalyserNode.idl \

Modified: trunk/Source/WebCore/Modules/fetch/FetchBody.cpp (221503 => 221504)


--- trunk/Source/WebCore/Modules/fetch/FetchBody.cpp	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/Modules/fetch/FetchBody.cpp	2017-09-01 22:53:23 UTC (rev 221504)
@@ -138,7 +138,7 @@
         return;
     }
 
-    m_consumer.resolve(WTFMove(promise));
+    m_consumer.resolve(WTFMove(promise), m_readableStream.get());
 }
 
 #if ENABLE(STREAMS_API)

Modified: trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp (221503 => 221504)


--- trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp	2017-09-01 22:53:23 UTC (rev 221504)
@@ -56,29 +56,60 @@
     return decoder->decodeAndFlush(reinterpret_cast<const char*>(data), length);
 }
 
-void FetchBodyConsumer::resolveWithData(Ref<DeferredPromise>&& promise, const unsigned char* data, unsigned length)
+static void resolveWithTypeAndData(Ref<DeferredPromise>&& promise, FetchBodyConsumer::Type type, const String& contentType, const unsigned char* data, unsigned length)
 {
-    switch (m_type) {
-    case Type::ArrayBuffer:
+    switch (type) {
+    case FetchBodyConsumer::Type::ArrayBuffer:
         fulfillPromiseWithArrayBuffer(WTFMove(promise), data, length);
         return;
-    case Type::Blob:
-        promise->resolveWithNewlyCreated<IDLInterface<Blob>>(blobFromData(data, length, m_contentType).get());
+    case FetchBodyConsumer::Type::Blob:
+        promise->resolveWithNewlyCreated<IDLInterface<Blob>>(blobFromData(data, length, contentType).get());
         return;
-    case Type::JSON:
+    case FetchBodyConsumer::Type::JSON:
         fulfillPromiseWithJSON(WTFMove(promise), textFromUTF8(data, length));
         return;
-    case Type::Text:
+    case FetchBodyConsumer::Type::Text:
         promise->resolve<IDLDOMString>(textFromUTF8(data, length));
         return;
-    case Type::None:
+    case FetchBodyConsumer::Type::None:
         ASSERT_NOT_REACHED();
         return;
     }
 }
 
-void FetchBodyConsumer::resolve(Ref<DeferredPromise>&& promise)
+void FetchBodyConsumer::clean()
 {
+    m_buffer = nullptr;
+    m_consumePromise = nullptr;
+    if (m_sink) {
+        m_sink->clearCallback();
+        return;
+    }
+}
+
+void FetchBodyConsumer::resolveWithData(Ref<DeferredPromise>&& promise, const unsigned char* data, unsigned length)
+{
+    resolveWithTypeAndData(WTFMove(promise), m_type, m_contentType, data, length);
+}
+
+void FetchBodyConsumer::resolve(Ref<DeferredPromise>&& promise, ReadableStream* stream)
+{
+    if (stream) {
+        ASSERT(!m_sink);
+        m_sink = ReadableStreamToSharedBufferSink::create([promise = WTFMove(promise), type = m_type, contentType = m_contentType](ExceptionOr<RefPtr<SharedBuffer>>&& result) mutable {
+            if (result.hasException()) {
+                promise->reject(result.releaseException());
+                return;
+            }
+
+            auto* data = "" && result.returnValue()->data() ? reinterpret_cast<const unsigned char*>(result.returnValue()->data()) : nullptr;
+            auto size = data ? result.returnValue()->size() : 0;
+            resolveWithTypeAndData(WTFMove(promise), type, contentType, data, size);
+        });
+        m_sink->pipeFrom(*stream);
+        return;
+    }
+
     ASSERT(m_type != Type::None);
     switch (m_type) {
     case Type::ArrayBuffer:
@@ -99,18 +130,22 @@
     }
 }
 
-void FetchBodyConsumer::append(const char* data, unsigned length)
+void FetchBodyConsumer::append(const char* data, unsigned size)
 {
+    if (m_source) {
+        m_source->enqueue(ArrayBuffer::tryCreate(data, size));
+        return;
+    }
     if (!m_buffer) {
-        m_buffer = SharedBuffer::create(data, length);
+        m_buffer = SharedBuffer::create(data, size);
         return;
     }
-    m_buffer->append(data, length);
+    m_buffer->append(data, size);
 }
 
-void FetchBodyConsumer::append(const unsigned char* data, unsigned length)
+void FetchBodyConsumer::append(const unsigned char* data, unsigned size)
 {
-    append(reinterpret_cast<const char*>(data), length);
+    append(reinterpret_cast<const char*>(data), size);
 }
 
 RefPtr<SharedBuffer> FetchBodyConsumer::takeData()
@@ -154,6 +189,15 @@
     m_consumePromise = WTFMove(promise);
 }
 
+void FetchBodyConsumer::setSource(Ref<FetchBodySource>&& source)
+{
+    m_source = WTFMove(source);
+    if (m_buffer) {
+        m_source->enqueue(m_buffer->tryCreateArrayBuffer());
+        m_buffer = nullptr;
+    }
+}
+
 void FetchBodyConsumer::loadingFailed()
 {
     if (m_consumePromise) {
@@ -160,18 +204,20 @@
         m_consumePromise->reject();
         m_consumePromise = nullptr;
     }
+    if (m_source) {
+        m_source->error(ASCIILiteral("Loading failed"));
+        m_source = nullptr;
+    }
 }
 
 void FetchBodyConsumer::loadingSucceeded()
 {
     if (m_consumePromise)
-        resolve(m_consumePromise.releaseNonNull());
+        resolve(m_consumePromise.releaseNonNull(), nullptr);
+    if (m_source) {
+        m_source->close();
+        m_source = nullptr;
+    }
 }
 
-void FetchBodyConsumer::clean()
-{
-    m_buffer = nullptr;
-    m_consumePromise = nullptr;
-}
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.h (221503 => 221504)


--- trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.h	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.h	2017-09-01 22:53:23 UTC (rev 221504)
@@ -28,12 +28,16 @@
 
 #pragma once
 
+#include "FetchBodySource.h"
 #include "JSDOMPromiseDeferred.h"
+#include "ReadableStreamSink.h"
 #include "SharedBuffer.h"
 
 namespace WebCore {
 
 class Blob;
+class FetchBodySource;
+class ReadableStream;
 
 class FetchBodyConsumer {
 public:
@@ -57,7 +61,7 @@
 
     void clean();
 
-    void resolve(Ref<DeferredPromise>&&);
+    void resolve(Ref<DeferredPromise>&&, ReadableStream*);
     void resolveWithData(Ref<DeferredPromise>&&, const unsigned char*, unsigned);
 
     bool hasData() const { return !!m_buffer; }
@@ -66,6 +70,7 @@
     void loadingSucceeded();
 
     void setConsumePromise(Ref<DeferredPromise>&&);
+    void setSource(Ref<FetchBodySource>&&);
 
 private:
     Type m_type;
@@ -72,6 +77,8 @@
     String m_contentType;
     RefPtr<SharedBuffer> m_buffer;
     RefPtr<DeferredPromise> m_consumePromise;
+    RefPtr<ReadableStreamToSharedBufferSink> m_sink;
+    RefPtr<FetchBodySource> m_source;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp (221503 => 221504)


--- trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp	2017-09-01 22:53:23 UTC (rev 221504)
@@ -317,7 +317,7 @@
 
 void FetchResponse::finishConsumingStream(Ref<DeferredPromise>&& promise)
 {
-    m_consumer.resolve(WTFMove(promise));
+    m_consumer.resolve(WTFMove(promise), nullptr);
 }
 
 void FetchResponse::consumeBodyAsStream()

Modified: trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js (221503 => 221504)


--- trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js	2017-09-01 22:53:23 UTC (rev 221504)
@@ -106,6 +106,33 @@
     @readableStreamError(stream, error);
 }
 
+function readableStreamPipeTo(stream, sink)
+{
+    "use strict";
+    @assert(@isReadableStream(stream));
+
+    const reader = new @ReadableStreamDefaultReader(stream);
+
+    reader.@closedPromiseCapability.@promise.@then(() => { }, (e) => { sink.error(e); });
+
+    function doPipe() {
+        @readableStreamDefaultReaderRead(reader).@then(function(result) {
+            if (result.done) {
+                sink.close();
+                return;
+            }
+            try {
+                sink.enqueue(result.value);
+            } catch (e) {
+                sink.error("ReadableStream chunk enqueueing in the sink failed");
+                return;
+            }
+            doPipe();
+        });
+    }
+    doPipe();
+}
+
 function readableStreamTee(stream, shouldClone)
 {
     "use strict";

Added: trunk/Source/WebCore/Modules/streams/ReadableStreamSink.cpp (0 => 221504)


--- trunk/Source/WebCore/Modules/streams/ReadableStreamSink.cpp	                        (rev 0)
+++ trunk/Source/WebCore/Modules/streams/ReadableStreamSink.cpp	2017-09-01 22:53:23 UTC (rev 221504)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "ReadableStreamSink.h"
+
+#include "BufferSource.h"
+#include "DOMException.h"
+#include "ReadableStream.h"
+#include "SharedBuffer.h"
+
+#if ENABLE(STREAMS_API)
+
+namespace WebCore {
+
+ReadableStreamToSharedBufferSink::ReadableStreamToSharedBufferSink(Callback&& callback)
+    : m_callback { WTFMove(callback) }
+{
+}
+
+void ReadableStreamToSharedBufferSink::pipeFrom(ReadableStream& stream)
+{
+    stream.pipeTo(*this);
+}
+
+void ReadableStreamToSharedBufferSink::enqueue(const BufferSource& buffer)
+{
+    if (!m_data) {
+        m_data = SharedBuffer::create(buffer.data(), buffer.length());
+        return;
+    }
+    m_data->append(reinterpret_cast<const char*>(buffer.data()), buffer.length());
+}
+
+void ReadableStreamToSharedBufferSink::close()
+{
+    if (auto callback = WTFMove(m_callback))
+        callback(WTFMove(m_data));
+}
+
+void ReadableStreamToSharedBufferSink::error(String&& message)
+{
+    if (auto callback = WTFMove(m_callback))
+        callback(Exception { TypeError, WTFMove(message) });
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(STREAMS_API)

Added: trunk/Source/WebCore/Modules/streams/ReadableStreamSink.h (0 => 221504)


--- trunk/Source/WebCore/Modules/streams/ReadableStreamSink.h	                        (rev 0)
+++ trunk/Source/WebCore/Modules/streams/ReadableStreamSink.h	2017-09-01 22:53:23 UTC (rev 221504)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#pragma once
+
+#if ENABLE(STREAMS_API)
+
+#include "ExceptionOr.h"
+#include <wtf/Function.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class BufferSource;
+class ReadableStream;
+class SharedBuffer;
+
+class ReadableStreamSink : public RefCounted<ReadableStreamSink> {
+public:
+    virtual ~ReadableStreamSink() = default;
+
+    virtual void enqueue(const BufferSource&) = 0;
+    virtual void close() = 0;
+    virtual void error(String&&) = 0;
+};
+
+class ReadableStreamToSharedBufferSink final : public ReadableStreamSink {
+public:
+    using Callback = WTF::Function<void(ExceptionOr<RefPtr<SharedBuffer>>&&)>;
+    static Ref<ReadableStreamToSharedBufferSink> create(Callback&& callback) { return adoptRef(*new ReadableStreamToSharedBufferSink(WTFMove(callback))); }
+    void pipeFrom(ReadableStream&);
+    void clearCallback() { m_callback = { }; }
+
+private:
+    ReadableStreamToSharedBufferSink(Callback&&);
+
+    void enqueue(const BufferSource&) final;
+    void close() final;
+    void error(String&&) final;
+
+    Callback m_callback;
+    RefPtr<SharedBuffer> m_data;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(STREAMS_API)

Added: trunk/Source/WebCore/Modules/streams/ReadableStreamSink.idl (0 => 221504)


--- trunk/Source/WebCore/Modules/streams/ReadableStreamSink.idl	                        (rev 0)
+++ trunk/Source/WebCore/Modules/streams/ReadableStreamSink.idl	2017-09-01 22:53:23 UTC (rev 221504)
@@ -0,0 +1,35 @@
+/*
+* Copyright (C) 2017 Apple Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+[
+    NoInterfaceObject,
+    Conditional=STREAMS_API,
+    SkipVTableValidation
+] interface ReadableStreamSink {
+    void enqueue(BufferSource chunk);
+    void close();
+    void error(DOMString message);
+};

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (221503 => 221504)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-09-01 22:53:23 UTC (rev 221504)
@@ -1673,6 +1673,11 @@
 		4123081B138C429700BCCFCA /* WebCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93F19B1A08245E5A001E9ABC /* WebCore.framework */; };
 		41230913138C42FF00BCCFCA /* _javascript_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8216299029F4FB501000131 /* _javascript_Core.framework */; };
 		4127D5370F8AAB1D00E424F5 /* ScriptState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4127D5360F8AAB1D00E424F5 /* ScriptState.cpp */; };
+		4129C98A1F587FEB009D7403 /* ReadableStreamSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4129C9871F58662D009D7403 /* ReadableStreamSink.cpp */; };
+		4129C9971F59B963009D7403 /* FetchBodySource.h in Headers */ = {isa = PBXBuildFile; fileRef = 413015D61C7B570400091C6F /* FetchBodySource.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		4129C9A91F59C56B009D7403 /* ReadableStreamDefaultController.h in Headers */ = {isa = PBXBuildFile; fileRef = 418C395F1C8F0AAB0051C8A3 /* ReadableStreamDefaultController.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		4129C9AB1F59C573009D7403 /* ReadableStreamSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 418C395B1C8F0A610051C8A3 /* ReadableStreamSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		4129C9AF1F59CF5B009D7403 /* ReadableStreamSink.h in Headers */ = {isa = PBXBuildFile; fileRef = 4129C9801F5861C7009D7403 /* ReadableStreamSink.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		4129DF851BB5B80700322A16 /* JSReadableStreamPrivateConstructors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4129DF831BB5B7F700322A16 /* JSReadableStreamPrivateConstructors.cpp */; };
 		4129DF861BB5B80C00322A16 /* JSReadableStreamPrivateConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 4129DF841BB5B7F700322A16 /* JSReadableStreamPrivateConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		413015D91C7B571400091C6E /* FetchResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 413015D51C7B570400091C6E /* FetchResponse.cpp */; };
@@ -2899,7 +2904,7 @@
 		6C4C96DE1AD4483500365A50 /* JSReadableStreamDefaultController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6C4C96DA1AD4483500365A50 /* JSReadableStreamDefaultController.cpp */; };
 		6C4C96DF1AD4483500363F64 /* JSReadableByteStreamController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C4C96DB1AD4483500363F64 /* JSReadableByteStreamController.h */; };
 		6C4C96DF1AD4483500365672 /* JSReadableStreamBYOBRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C4C96DB1AD4483500365672 /* JSReadableStreamBYOBRequest.h */; };
-		6C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C4C96DB1AD4483500365A50 /* JSReadableStreamDefaultController.h */; };
+		6C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C4C96DB1AD4483500365A50 /* JSReadableStreamDefaultController.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6C638895A96CCEE50C8C946C /* CachedResourceRequestInitiators.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C638893A96CCEE50C8C946C /* CachedResourceRequestInitiators.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6C638896A96CCEE50C8C946C /* CachedResourceRequestInitiators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6C638894A96CCEE50C8C946C /* CachedResourceRequestInitiators.cpp */; };
 		6CDDE8D01770BB220016E072 /* RegionOversetState.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C70A81417707C49009A446E /* RegionOversetState.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3401,7 +3406,9 @@
 		7EE6847112D26E3800E79415 /* ResourceResponseCFNet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7EE6845E12D26E3800E79415 /* ResourceResponseCFNet.cpp */; };
 		7EE6847512D26E7000E79415 /* ResourceLoaderCFNet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7EE6847412D26E7000E79415 /* ResourceLoaderCFNet.cpp */; };
 		7F4C96DC1AD4483500365A50 /* JSFetchBody.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F4C96D81AD4483500365A50 /* JSFetchBody.cpp */; };
+		7F4C96DC1AD4483500365A51 /* JSReadableStreamSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F4C96D81AD4483500365A51 /* JSReadableStreamSink.cpp */; };
 		7F4C96DD1AD4483500365A50 /* JSFetchBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F4C96D91AD4483500365A50 /* JSFetchBody.h */; };
+		7F4C96DD1AD4483500365A51 /* JSReadableStreamSink.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F4C96D91AD4483500365A51 /* JSReadableStreamSink.h */; };
 		8102C5881325BB1100DDE67A /* StringCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8102C5871325BB1100DDE67A /* StringCallback.cpp */; };
 		81AC5999131636E60009A7E0 /* DataTransferItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 81AC5997131636E60009A7E0 /* DataTransferItem.h */; };
 		81AC599A131636E60009A7E0 /* DataTransferItemList.h in Headers */ = {isa = PBXBuildFile; fileRef = 81AC5998131636E60009A7E0 /* DataTransferItemList.h */; };
@@ -9386,6 +9393,9 @@
 		41189EF71AD8232800B93F64 /* ReadableByteStreamController.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadableByteStreamController.idl; sourceTree = "<group>"; };
 		41189EF71AD8232800B95672 /* ReadableStreamBYOBRequest.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadableStreamBYOBRequest.idl; sourceTree = "<group>"; };
 		4127D5360F8AAB1D00E424F5 /* ScriptState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptState.cpp; sourceTree = "<group>"; };
+		4129C9801F5861C7009D7403 /* ReadableStreamSink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadableStreamSink.h; sourceTree = "<group>"; };
+		4129C9811F5861C7009D7403 /* ReadableStreamSink.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadableStreamSink.idl; sourceTree = "<group>"; };
+		4129C9871F58662D009D7403 /* ReadableStreamSink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReadableStreamSink.cpp; sourceTree = "<group>"; };
 		4129DF831BB5B7F700322A16 /* JSReadableStreamPrivateConstructors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSReadableStreamPrivateConstructors.cpp; sourceTree = "<group>"; };
 		4129DF841BB5B7F700322A16 /* JSReadableStreamPrivateConstructors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSReadableStreamPrivateConstructors.h; sourceTree = "<group>"; };
 		413015D51C7B570400091C6E /* FetchResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FetchResponse.cpp; sourceTree = "<group>"; };
@@ -11569,7 +11579,9 @@
 		7EE6845E12D26E3800E79415 /* ResourceResponseCFNet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceResponseCFNet.cpp; sourceTree = "<group>"; };
 		7EE6847412D26E7000E79415 /* ResourceLoaderCFNet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoaderCFNet.cpp; sourceTree = "<group>"; };
 		7F4C96D81AD4483500365A50 /* JSFetchBody.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFetchBody.cpp; sourceTree = "<group>"; };
+		7F4C96D81AD4483500365A51 /* JSReadableStreamSink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSReadableStreamSink.cpp; sourceTree = "<group>"; };
 		7F4C96D91AD4483500365A50 /* JSFetchBody.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFetchBody.h; sourceTree = "<group>"; };
+		7F4C96D91AD4483500365A51 /* JSReadableStreamSink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSReadableStreamSink.h; sourceTree = "<group>"; };
 		8102C5871325BB1100DDE67A /* StringCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringCallback.cpp; sourceTree = "<group>"; };
 		81AC5997131636E60009A7E0 /* DataTransferItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataTransferItem.h; sourceTree = "<group>"; };
 		81AC5998131636E60009A7E0 /* DataTransferItemList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataTransferItemList.h; sourceTree = "<group>"; };
@@ -17999,6 +18011,9 @@
 				419FAFAD1ABABCD5005B828B /* ReadableStreamDefaultReader.idl */,
 				9908B0F21BCACF9100ED0F65 /* ReadableStreamDefaultReader.js */,
 				9908B0F11BCACF9100ED0F65 /* ReadableStreamInternals.js */,
+				4129C9871F58662D009D7403 /* ReadableStreamSink.cpp */,
+				4129C9801F5861C7009D7403 /* ReadableStreamSink.h */,
+				4129C9811F5861C7009D7403 /* ReadableStreamSink.idl */,
 				418C395B1C8F0A610051C8A3 /* ReadableStreamSource.h */,
 				418C395C1C8F0A610051C8A3 /* ReadableStreamSource.idl */,
 				9908B0F11BCACF9100ED0F55 /* StreamInternals.js */,
@@ -18113,6 +18128,8 @@
 				7CE1916A1F2AB70600272F78 /* JSFetchRequestRedirect.h */,
 				8E4C96D81AD4483500365A50 /* JSFetchResponse.cpp */,
 				8E4C96D91AD4483500365A50 /* JSFetchResponse.h */,
+				7F4C96D81AD4483500365A51 /* JSReadableStreamSink.cpp */,
+				7F4C96D91AD4483500365A51 /* JSReadableStreamSink.h */,
 				7E4C96D81AD4483500365A51 /* JSReadableStreamSource.cpp */,
 				7E4C96D91AD4483500365A51 /* JSReadableStreamSource.h */,
 			);
@@ -27586,6 +27603,7 @@
 				84730D871248F0B300D3A9C9 /* FEOffset.h in Headers */,
 				84730D891248F0B300D3A9C9 /* FESpecularLighting.h in Headers */,
 				517A535B1F588A4C00DCDC0A /* FetchBodyConsumer.h in Headers */,
+				4129C9971F59B963009D7403 /* FetchBodySource.h in Headers */,
 				41D129DB1F3D143800D15E47 /* FetchHeaders.h in Headers */,
 				416E6FE81BBD12DF000A6023 /* FetchInternalsBuiltins.h in Headers */,
 				517A535A1F5889EF00DCDC0A /* FetchLoader.h in Headers */,
@@ -28553,6 +28571,7 @@
 				6C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultController.h in Headers */,
 				7C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultReader.h in Headers */,
 				4129DF861BB5B80C00322A16 /* JSReadableStreamPrivateConstructors.h in Headers */,
+				7F4C96DD1AD4483500365A51 /* JSReadableStreamSink.h in Headers */,
 				7E4C96DD1AD4483500365A51 /* JSReadableStreamSource.h in Headers */,
 				4998AECE13F9D6C90090B1AA /* JSRequestAnimationFrameCallback.h in Headers */,
 				57E233711DCD468F00F28D01 /* JSRsaHashedImportParams.h in Headers */,
@@ -29384,7 +29403,9 @@
 				A84D827C11D333ED00972990 /* RawDataDocumentParser.h in Headers */,
 				416E6FE81BBD12DF000A6043 /* ReadableByteStreamInternalsBuiltins.h in Headers */,
 				416E6FE91BBD12E5000A6043 /* ReadableStreamBuiltins.h in Headers */,
+				4129C9A91F59C56B009D7403 /* ReadableStreamDefaultController.h in Headers */,
 				416E6FE81BBD12DF000A3F64 /* ReadableStreamInternalsBuiltins.h in Headers */,
+				4129C9AB1F59C573009D7403 /* ReadableStreamSource.h in Headers */,
 				FD31603C12B0267600C1A359 /* RealtimeAnalyser.h in Headers */,
 				41103AAD1E39791000769F03 /* RealtimeIncomingAudioSource.h in Headers */,
 				4A4F65711AA997F100E38CDD /* RealtimeMediaSource.h in Headers */,
@@ -29883,6 +29904,7 @@
 				E46C794B1F13E82B00F371E1 /* StyleInvalidationFunctions.h in Headers */,
 				E47127CB163438AE00ED6F5A /* StyleInvalidator.h in Headers */,
 				BC5EB72A0E81DE8100B25965 /* StyleMarqueeData.h in Headers */,
+				4129C9AF1F59CF5B009D7403 /* ReadableStreamSink.h in Headers */,
 				0FF50272102BA96A0066F39A /* StyleMedia.h in Headers */,
 				BC5EB74E0E81E06700B25965 /* StyleMultiColData.h in Headers */,
 				E4DACE6A1D12E10B0075980F /* StylePendingResources.h in Headers */,
@@ -32580,6 +32602,7 @@
 				6C4C96DE1AD4483500365A50 /* JSReadableStreamDefaultController.cpp in Sources */,
 				7C4C96DE1AD4483500365A50 /* JSReadableStreamDefaultReader.cpp in Sources */,
 				4129DF851BB5B80700322A16 /* JSReadableStreamPrivateConstructors.cpp in Sources */,
+				7F4C96DC1AD4483500365A51 /* JSReadableStreamSink.cpp in Sources */,
 				7E4C96DC1AD4483500365A51 /* JSReadableStreamSource.cpp in Sources */,
 				418C39601C8F0AAE0051C8A3 /* JSReadableStreamSourceCustom.cpp in Sources */,
 				4998AECD13F9D6C90090B1AA /* JSRequestAnimationFrameCallback.cpp in Sources */,
@@ -33341,6 +33364,7 @@
 				6E84E9E017668BEE00815B68 /* RasterShape.cpp in Sources */,
 				41B459EF1F55EBD10000F6FD /* ReadableStream.cpp in Sources */,
 				418C39611C8F0AB10051C8A3 /* ReadableStreamDefaultController.cpp in Sources */,
+				4129C98A1F587FEB009D7403 /* ReadableStreamSink.cpp in Sources */,
 				FD31603B12B0267600C1A359 /* RealtimeAnalyser.cpp in Sources */,
 				41103AAE1E39791000769F03 /* RealtimeIncomingAudioSource.cpp in Sources */,
 				5CDD833E1E4324DC00621E92 /* RealtimeIncomingVideoSource.cpp in Sources */,

Modified: trunk/Source/WebCore/bindings/js/ReadableStream.cpp (221503 => 221504)


--- trunk/Source/WebCore/bindings/js/ReadableStream.cpp	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/bindings/js/ReadableStream.cpp	2017-09-01 22:53:23 UTC (rev 221504)
@@ -27,6 +27,7 @@
 #include "ReadableStream.h"
 
 #include "JSDOMConvertSequences.h"
+#include "JSReadableStreamSink.h"
 #include "JSReadableStreamSource.h"
 #include "WebCoreJSClientData.h"
 
@@ -54,6 +55,24 @@
     return create(globalObject, *newReadableStream);
 }
 
+void ReadableStream::pipeTo(ReadableStreamSink& sink)
+{
+    auto& state = *m_globalObject->globalExec();
+    JSVMClientData* clientData = static_cast<JSVMClientData*>(state.vm().clientData);
+    const Identifier& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamPipeToPrivateName();
+
+    auto readableStreamPipeTo = m_globalObject->get(&state, privateName);
+    ASSERT(readableStreamPipeTo.isFunction());
+
+    CallData callData;
+    CallType callType = getCallData(readableStreamPipeTo, callData);
+    ASSERT(callType != JSC::CallType::None);
+    MarkedArgumentBuffer arguments;
+    arguments.append(readableStream());
+    arguments.append(toJS(&state, m_globalObject.get(), sink));
+    JSC::call(&state, readableStreamPipeTo, callType, callData, JSC::jsUndefined(), arguments);
+}
+
 std::pair<Ref<ReadableStream>, Ref<ReadableStream>> ReadableStream::tee()
 {
     auto& state = *m_globalObject->globalExec();

Modified: trunk/Source/WebCore/bindings/js/ReadableStream.h (221503 => 221504)


--- trunk/Source/WebCore/bindings/js/ReadableStream.h	2017-09-01 22:25:20 UTC (rev 221503)
+++ trunk/Source/WebCore/bindings/js/ReadableStream.h	2017-09-01 22:53:23 UTC (rev 221504)
@@ -32,6 +32,7 @@
 
 namespace WebCore {
 
+class ReadableStreamSink;
 class ReadableStreamSource;
 
 class ReadableStream final : public DOMGuarded<JSReadableStream> {
@@ -42,6 +43,8 @@
 
     std::pair<Ref<ReadableStream>, Ref<ReadableStream>> tee();
 
+    void pipeTo(ReadableStreamSink&);
+
     JSReadableStream* readableStream() { return guarded(); }
 
 protected:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to