Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Unified Diff: third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp

Issue 1969333002: [Fetch API] |(new Response(stream)).body| should return |stream| (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
diff --git a/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp b/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
index 24194dc9a4fd0609d1a729f05e1b49d5e7ddcf50..af366abdcace41ae2e762def5b7d7d84a7ce1154 100644
--- a/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
+++ b/third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp
@@ -13,6 +13,8 @@
#include "core/streams/ReadableStreamOperations.h"
#include "modules/fetch/Body.h"
#include "modules/fetch/DataConsumerHandleUtil.h"
+#include "modules/fetch/DataConsumerTee.h"
+#include "modules/fetch/ReadableStreamDataConsumerHandle.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/blob/BlobData.h"
#include "platform/network/EncodedFormData.h"
@@ -84,6 +86,7 @@ BodyStreamBuffer::BodyStreamBuffer(ScriptState* scriptState, PassOwnPtr<FetchDat
, m_scriptState(scriptState)
, m_handle(std::move(handle))
, m_reader(m_handle->obtainReader(this))
+ , m_madeFromReadableStream(false)
{
if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
ScriptState::Scope scope(scriptState);
@@ -101,6 +104,22 @@ BodyStreamBuffer::BodyStreamBuffer(ScriptState* scriptState, PassOwnPtr<FetchDat
}
}
+BodyStreamBuffer::BodyStreamBuffer(ScriptState* scriptState, ScriptValue stream)
+ : UnderlyingSourceBase(scriptState)
+ , m_scriptState(scriptState)
+ , m_madeFromReadableStream(true)
+{
+ ScriptState::Scope scope(scriptState);
+ DCHECK(RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled());
+ DCHECK(ReadableStreamOperations::isReadableStream(scriptState, stream));
+ v8::Local<v8::Value> bodyValue = toV8(this, scriptState);
+ DCHECK(!bodyValue.IsEmpty());
+ DCHECK(bodyValue->IsObject());
+ v8::Local<v8::Object> body = bodyValue.As<v8::Object>();
+
+ V8HiddenValue::setHiddenValue(scriptState, body, V8HiddenValue::internalBodyStream(scriptState->isolate()), stream.v8Value());
+}
+
ScriptValue BodyStreamBuffer::stream()
{
ScriptState::Scope scope(m_scriptState.get());
@@ -121,6 +140,9 @@ PassRefPtr<BlobDataHandle> BodyStreamBuffer::drainAsBlobDataHandle(FetchDataCons
if (isStreamClosed() || isStreamErrored())
return nullptr;
+ if (m_madeFromReadableStream)
+ return nullptr;
+
RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle(policy);
if (blobDataHandle) {
closeAndLockAndDisturb();
@@ -136,6 +158,9 @@ PassRefPtr<EncodedFormData> BodyStreamBuffer::drainAsFormData()
if (isStreamClosed() || isStreamErrored())
return nullptr;
+ if (m_madeFromReadableStream)
+ return nullptr;
+
RefPtr<EncodedFormData> formData = m_reader->drainAsFormData();
if (formData) {
closeAndLockAndDisturb();
@@ -144,29 +169,6 @@ PassRefPtr<EncodedFormData> BodyStreamBuffer::drainAsFormData()
return nullptr;
}
-PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle()
-{
- ASSERT(!isStreamLocked());
- ASSERT(!isStreamDisturbed());
- // We need to call these before calling closeAndLockAndDisturb.
- const bool isClosed = isStreamClosed();
- const bool isErrored = isStreamErrored();
- OwnPtr<FetchDataConsumerHandle> handle = std::move(m_handle);
-
- closeAndLockAndDisturb();
-
- if (isClosed) {
- // Note that the stream cannot be "draining", because it doesn't have
- // the internal buffer.
- return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle());
- }
- if (isErrored)
- return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle());
-
- ASSERT(handle);
- return handle;
-}
-
void BodyStreamBuffer::startLoading(FetchDataLoader* loader, FetchDataLoader::Client* client)
{
ASSERT(!m_loader);
@@ -176,6 +178,28 @@ void BodyStreamBuffer::startLoading(FetchDataLoader* loader, FetchDataLoader::Cl
loader->start(handle.get(), new LoaderClient(m_scriptState->getExecutionContext(), this, client));
}
+void BodyStreamBuffer::tee(BodyStreamBuffer** branch1, BodyStreamBuffer** branch2)
+{
+ DCHECK(!isStreamLocked());
+ DCHECK(!isStreamDisturbed());
+ *branch1 = nullptr;
+ *branch2 = nullptr;
+
+ if (m_madeFromReadableStream) {
+ ScriptState::Scope scope(m_scriptState.get());
+ ScriptValue stream1, stream2;
+ ReadableStreamOperations::tee(m_scriptState.get(), stream(), &stream1, &stream2);
+ *branch1 = new BodyStreamBuffer(m_scriptState.get(), stream1);
+ *branch2 = new BodyStreamBuffer(m_scriptState.get(), stream2);
+ return;
+ }
+ OwnPtr<FetchDataConsumerHandle> handle = releaseHandle();
+ OwnPtr<FetchDataConsumerHandle> handle1, handle2;
+ DataConsumerTee::create(m_scriptState->getExecutionContext(), std::move(handle), &handle1, &handle2);
+ *branch1 = new BodyStreamBuffer(m_scriptState.get(), std::move(handle1));
+ *branch2 = new BodyStreamBuffer(m_scriptState.get(), std::move(handle2));
+}
+
void BodyStreamBuffer::pullSource()
{
ASSERT(!m_streamNeedsMore);
@@ -384,4 +408,40 @@ void BodyStreamBuffer::stopLoading()
m_loader = nullptr;
}
+PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle()
+{
+ DCHECK(!isStreamLocked());
+ DCHECK(!isStreamDisturbed());
+
+ if (m_madeFromReadableStream) {
+ ScriptState::Scope scope(m_scriptState.get());
+ // We need to have |reader| alive by some means (as written in
+ // ReadableStreamDataConsumerHandle). Based on the following facts
+ // - This function is used only from tee and startLoading.
+ // - This branch cannot be taken when called from tee.
+ // - startLoading makes hasPendingActivity return true while loading.
+ // , we don't need to keep the reader explicitly.
+ NonThrowableExceptionState exceptionState;
+ ScriptValue reader = ReadableStreamOperations::getReader(m_scriptState.get(), stream(), exceptionState);
+ return ReadableStreamDataConsumerHandle::create(m_scriptState.get(), reader);
+ }
+ // We need to call these before calling closeAndLockAndDisturb.
+ const bool isClosed = isStreamClosed();
+ const bool isErrored = isStreamErrored();
+ OwnPtr<FetchDataConsumerHandle> handle = m_handle.release();
+
+ closeAndLockAndDisturb();
+
+ if (isClosed) {
+ // Note that the stream cannot be "draining", because it doesn't have
+ // the internal buffer.
+ return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumerHandle());
+ }
+ if (isErrored)
+ return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle());
+
+ DCHECK(handle);
+ return handle;
+}
+
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698