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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/BodyStreamBuffer.cpp

Issue 1899873006: Make Response::body return v8-extra based stream behind flag (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@notify-locked-released
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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/fetch/BodyStreamBuffer.h" 5 #include "modules/fetch/BodyStreamBuffer.h"
6 6
7 #include "bindings/core/v8/ScriptState.h"
8 #include "bindings/core/v8/V8HiddenValue.h"
7 #include "core/dom/DOMArrayBuffer.h" 9 #include "core/dom/DOMArrayBuffer.h"
8 #include "core/dom/DOMTypedArray.h" 10 #include "core/dom/DOMTypedArray.h"
9 #include "core/dom/ExceptionCode.h" 11 #include "core/dom/ExceptionCode.h"
12 #include "core/streams/ReadableStreamController.h"
13 #include "core/streams/ReadableStreamOperations.h"
14 #include "modules/fetch/Body.h"
10 #include "modules/fetch/DataConsumerHandleUtil.h" 15 #include "modules/fetch/DataConsumerHandleUtil.h"
16 #include "platform/RuntimeEnabledFeatures.h"
11 #include "platform/blob/BlobData.h" 17 #include "platform/blob/BlobData.h"
12 #include "platform/network/EncodedFormData.h" 18 #include "platform/network/EncodedFormData.h"
13 19
14 namespace blink { 20 namespace blink {
15 21
16 class BodyStreamBuffer::LoaderClient final : public GarbageCollectedFinalized<Lo aderClient>, public ActiveDOMObject, public FetchDataLoader::Client { 22 class BodyStreamBuffer::LoaderClient final : public GarbageCollectedFinalized<Lo aderClient>, public ActiveDOMObject, public FetchDataLoader::Client {
17 WTF_MAKE_NONCOPYABLE(LoaderClient); 23 WTF_MAKE_NONCOPYABLE(LoaderClient);
18 USING_GARBAGE_COLLECTED_MIXIN(LoaderClient); 24 USING_GARBAGE_COLLECTED_MIXIN(LoaderClient);
19 public: 25 public:
20 LoaderClient(ExecutionContext* executionContext, BodyStreamBuffer* buffer, F etchDataLoader::Client* client) 26 LoaderClient(ExecutionContext* executionContext, BodyStreamBuffer* buffer, F etchDataLoader::Client* client)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 private: 72 private:
67 void stop() override 73 void stop() override
68 { 74 {
69 m_buffer->stopLoading(); 75 m_buffer->stopLoading();
70 } 76 }
71 77
72 Member<BodyStreamBuffer> m_buffer; 78 Member<BodyStreamBuffer> m_buffer;
73 Member<FetchDataLoader::Client> m_client; 79 Member<FetchDataLoader::Client> m_client;
74 }; 80 };
75 81
76 BodyStreamBuffer::BodyStreamBuffer(PassOwnPtr<FetchDataConsumerHandle> handle) 82 BodyStreamBuffer::BodyStreamBuffer(ScriptState* scriptState, PassOwnPtr<FetchDat aConsumerHandle> handle)
77 : m_handle(std::move(handle)) 83 : UnderlyingSourceBase(scriptState)
84 , m_scriptState(scriptState)
85 , m_handle(std::move(handle))
78 , m_reader(m_handle->obtainReader(this)) 86 , m_reader(m_handle->obtainReader(this))
79 , m_stream(new ReadableByteStream(this, new ReadableByteStream::StrictStrate gy))
80 , m_streamNeedsMore(false)
81 { 87 {
82 m_stream->didSourceStart(); 88 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
89 ScriptState::Scope scope(scriptState);
90 v8::Local<v8::Value> bodyValue = toV8(this, scriptState);
91 ASSERT(!bodyValue.IsEmpty());
92 ASSERT(bodyValue->IsObject());
93 v8::Local<v8::Object> body = bodyValue.As<v8::Object>();
94
95 ScriptValue readableStream = ReadableStreamOperations::createReadableStr eam(
96 scriptState, this, ReadableStreamOperations::createCountQueuingStrat egy(scriptState, 0));
97 V8HiddenValue::setHiddenValue(scriptState, body, V8HiddenValue::internal BodyStream(scriptState->isolate()), readableStream.v8Value());
98 } else {
99 m_stream = new ReadableByteStream(this, new ReadableByteStream::StrictSt rategy);
100 m_stream->didSourceStart();
101 }
83 } 102 }
84 103
85 PassRefPtr<BlobDataHandle> BodyStreamBuffer::drainAsBlobDataHandle(ExecutionCont ext* executionContext, FetchDataConsumerHandle::Reader::BlobSizePolicy policy) 104 ScriptValue BodyStreamBuffer::stream()
105 {
106 ScriptState::Scope scope(m_scriptState.get());
107 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
108 v8::Local<v8::Value> bodyValue = toV8(this, m_scriptState.get());
109 ASSERT(!bodyValue.IsEmpty());
110 ASSERT(bodyValue->IsObject());
111 v8::Local<v8::Object> body = bodyValue.As<v8::Object>();
112 return ScriptValue(m_scriptState.get(), V8HiddenValue::getHiddenValue(m_ scriptState.get(), body, V8HiddenValue::internalBodyStream(m_scriptState->isolat e())));
113 }
114 return ScriptValue(m_scriptState.get(), toV8(m_stream, m_scriptState.get())) ;
115 }
116
117 PassRefPtr<BlobDataHandle> BodyStreamBuffer::drainAsBlobDataHandle(FetchDataCons umerHandle::Reader::BlobSizePolicy policy)
86 { 118 {
87 ASSERT(!isStreamLocked()); 119 ASSERT(!isStreamLocked());
88 ASSERT(!isStreamDisturbed()); 120 ASSERT(!isStreamDisturbed());
89 if (isStreamClosed() || isStreamErrored()) 121 if (isStreamClosed() || isStreamErrored())
90 return nullptr; 122 return nullptr;
91 123
92 RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle(poli cy); 124 RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle(poli cy);
93 if (blobDataHandle) { 125 if (blobDataHandle) {
94 NonThrowableExceptionState exceptionState; 126 lockAndDisturb();
95 m_stream->getBytesReader(executionContext, exceptionState);
96 m_stream->setIsDisturbed();
97 close(); 127 close();
98 return blobDataHandle.release(); 128 return blobDataHandle.release();
99 } 129 }
100 return nullptr; 130 return nullptr;
101 } 131 }
102 132
103 PassRefPtr<EncodedFormData> BodyStreamBuffer::drainAsFormData(ExecutionContext* executionContext) 133 PassRefPtr<EncodedFormData> BodyStreamBuffer::drainAsFormData()
104 { 134 {
105 ASSERT(!isStreamLocked()); 135 ASSERT(!isStreamLocked());
106 ASSERT(!isStreamDisturbed()); 136 ASSERT(!isStreamDisturbed());
107 if (isStreamClosed() || isStreamErrored()) 137 if (isStreamClosed() || isStreamErrored())
108 return nullptr; 138 return nullptr;
109 139
110 RefPtr<EncodedFormData> formData = m_reader->drainAsFormData(); 140 RefPtr<EncodedFormData> formData = m_reader->drainAsFormData();
111 if (formData) { 141 if (formData) {
112 NonThrowableExceptionState exceptionState; 142 lockAndDisturb();
113 m_stream->getBytesReader(executionContext, exceptionState);
114 m_stream->setIsDisturbed();
115 close(); 143 close();
116 return formData.release(); 144 return formData.release();
117 } 145 }
118 return nullptr; 146 return nullptr;
119 } 147 }
120 148
121 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle(ExecutionCon text* executionContext) 149 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle()
122 { 150 {
123 ASSERT(!isStreamLocked()); 151 ASSERT(!isStreamLocked());
124 ASSERT(!isStreamDisturbed()); 152 ASSERT(!isStreamDisturbed());
125 m_reader = nullptr; 153 lockAndDisturb();
126 m_stream->setIsDisturbed();
127 NonThrowableExceptionState exceptionState;
128 m_stream->getBytesReader(executionContext, exceptionState);
129 154
130 if (isStreamClosed()) 155 if (isStreamClosed())
131 return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumer Handle()); 156 return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumer Handle());
132 if (isStreamErrored()) 157 if (isStreamErrored())
133 return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorD ataConsumerHandle()); 158 return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorD ataConsumerHandle());
134 159
135 ASSERT(m_handle); 160 ASSERT(m_handle);
136 OwnPtr<FetchDataConsumerHandle> handle = m_handle.release(); 161 OwnPtr<FetchDataConsumerHandle> handle = m_handle.release();
137 close(); 162 close();
138 return handle.release(); 163 return handle.release();
139 } 164 }
140 165
141 void BodyStreamBuffer::startLoading(ExecutionContext* executionContext, FetchDat aLoader* loader, FetchDataLoader::Client* client) 166 void BodyStreamBuffer::startLoading(FetchDataLoader* loader, FetchDataLoader::Cl ient* client)
142 { 167 {
143 ASSERT(!m_loader); 168 ASSERT(!m_loader);
144 OwnPtr<FetchDataConsumerHandle> handle = releaseHandle(executionContext); 169 ASSERT(m_scriptState->contextIsValid());
170 OwnPtr<FetchDataConsumerHandle> handle = releaseHandle();
145 m_loader = loader; 171 m_loader = loader;
146 loader->start(handle.get(), new LoaderClient(executionContext, this, client) ); 172 loader->start(handle.get(), new LoaderClient(m_scriptState->getExecutionCont ext(), this, client));
147 }
148
149 bool BodyStreamBuffer::hasPendingActivity() const
150 {
151 return m_loader || (isStreamLocked() && isStreamReadable());
152 }
153
154 void BodyStreamBuffer::stop()
155 {
156 m_reader = nullptr;
157 m_handle = nullptr;
158 } 173 }
159 174
160 void BodyStreamBuffer::pullSource() 175 void BodyStreamBuffer::pullSource()
161 { 176 {
162 ASSERT(!m_streamNeedsMore); 177 ASSERT(!m_streamNeedsMore);
163 m_streamNeedsMore = true; 178 m_streamNeedsMore = true;
164 processData(); 179 processData();
165 } 180 }
166 181
167 ScriptPromise BodyStreamBuffer::cancelSource(ScriptState* scriptState, ScriptVal ue) 182 ScriptPromise BodyStreamBuffer::cancelSource(ScriptState* scriptState, ScriptVal ue)
168 { 183 {
184 ASSERT(scriptState == m_scriptState.get());
169 close(); 185 close();
170 return ScriptPromise::castUndefined(scriptState); 186 return ScriptPromise::castUndefined(scriptState);
171 } 187 }
188
189 ScriptPromise BodyStreamBuffer::pull(ScriptState* scriptState)
190 {
191 ASSERT(!m_streamNeedsMore);
192 ASSERT(scriptState == m_scriptState.get());
193 m_streamNeedsMore = true;
194 processData();
195 return ScriptPromise::castUndefined(scriptState);
196 }
197
198 ScriptPromise BodyStreamBuffer::cancel(ScriptState* scriptState, ScriptValue rea son)
199 {
200 ASSERT(scriptState == m_scriptState.get());
201 close();
202 return ScriptPromise::castUndefined(scriptState);
203 }
172 204
173 void BodyStreamBuffer::didGetReadable() 205 void BodyStreamBuffer::didGetReadable()
174 { 206 {
175 if (!m_reader) 207 if (!m_reader)
176 return; 208 return;
177 209
178 if (!m_streamNeedsMore) { 210 if (!m_streamNeedsMore) {
179 // Perform zero-length read to call close()/error() early. 211 // Perform zero-length read to call close()/error() early.
180 size_t readSize; 212 size_t readSize;
181 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDat aConsumerHandle::FlagNone, &readSize); 213 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDat aConsumerHandle::FlagNone, &readSize);
182 switch (result) { 214 switch (result) {
183 case WebDataConsumerHandle::Ok: 215 case WebDataConsumerHandle::Ok:
184 case WebDataConsumerHandle::ShouldWait: 216 case WebDataConsumerHandle::ShouldWait:
185 return; 217 return;
186 case WebDataConsumerHandle::Done: 218 case WebDataConsumerHandle::Done:
187 close(); 219 close();
188 return; 220 return;
189 case WebDataConsumerHandle::Busy: 221 case WebDataConsumerHandle::Busy:
190 case WebDataConsumerHandle::ResourceExhausted: 222 case WebDataConsumerHandle::ResourceExhausted:
191 case WebDataConsumerHandle::UnexpectedError: 223 case WebDataConsumerHandle::UnexpectedError:
192 error(); 224 error();
193 return; 225 return;
194 } 226 }
195 return; 227 return;
196 } 228 }
197 processData(); 229 processData();
198 } 230 }
199 231
200 bool BodyStreamBuffer::isStreamReadable() const 232 bool BodyStreamBuffer::hasPendingActivity() const
201 { 233 {
234 if (m_loader)
235 return true;
236 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
237 return UnderlyingSourceBase::hasPendingActivity();
238
239 return m_stream->stateInternal() == ReadableStream::Readable && m_stream->is Locked();
240 }
241
242 void BodyStreamBuffer::stop()
243 {
244 m_reader = nullptr;
245 m_handle = nullptr;
246 UnderlyingSourceBase::stop();
247 }
248
249 bool BodyStreamBuffer::isStreamReadable()
250 {
251 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
252 ScriptState::Scope scope(m_scriptState.get());
253 return ReadableStreamOperations::isReadable(m_scriptState.get(), stream( ));
254 }
202 return m_stream->stateInternal() == ReadableStream::Readable; 255 return m_stream->stateInternal() == ReadableStream::Readable;
203 } 256 }
204 257
205 bool BodyStreamBuffer::isStreamClosed() const 258 bool BodyStreamBuffer::isStreamClosed()
206 { 259 {
260 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
261 ScriptState::Scope scope(m_scriptState.get());
262 return ReadableStreamOperations::isClosed(m_scriptState.get(), stream()) ;
263 }
207 return m_stream->stateInternal() == ReadableStream::Closed; 264 return m_stream->stateInternal() == ReadableStream::Closed;
208 } 265 }
209 266
210 bool BodyStreamBuffer::isStreamErrored() const 267 bool BodyStreamBuffer::isStreamErrored()
211 { 268 {
269 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
270 ScriptState::Scope scope(m_scriptState.get());
271 return ReadableStreamOperations::isErrored(m_scriptState.get(), stream() );
272 }
212 return m_stream->stateInternal() == ReadableStream::Errored; 273 return m_stream->stateInternal() == ReadableStream::Errored;
213 } 274 }
214 275
215 bool BodyStreamBuffer::isStreamLocked() const 276 bool BodyStreamBuffer::isStreamLocked()
216 { 277 {
278 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
279 ScriptState::Scope scope(m_scriptState.get());
280 return ReadableStreamOperations::isLocked(m_scriptState.get(), stream()) ;
281 }
217 return m_stream->isLocked(); 282 return m_stream->isLocked();
218 } 283 }
219 284
220 bool BodyStreamBuffer::isStreamDisturbed() const 285 bool BodyStreamBuffer::isStreamDisturbed()
221 { 286 {
287 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
288 ScriptState::Scope scope(m_scriptState.get());
289 return ReadableStreamOperations::isDisturbed(m_scriptState.get(), stream ());
290 }
222 return m_stream->isDisturbed(); 291 return m_stream->isDisturbed();
223 } 292 }
224 293
294 void BodyStreamBuffer::setDisturbed()
295 {
296 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
297 ScriptState::Scope scope(m_scriptState.get());
298 ReadableStreamOperations::setDisturbed(m_scriptState.get(), stream());
299 } else {
300 m_stream->setIsDisturbed();
301 }
302 }
303
304 void BodyStreamBuffer::lockAndDisturb()
305 {
306 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
307 ScriptState::Scope scope(m_scriptState.get());
308 NonThrowableExceptionState exceptionState;
309 ReadableStreamOperations::getReader(m_scriptState.get(), stream(), excep tionState);
310 ReadableStreamOperations::setDisturbed(m_scriptState.get(), stream());
311 } else {
312 NonThrowableExceptionState exceptionState;
313 m_stream->getBytesReader(m_scriptState->getExecutionContext(), exception State);
314 m_stream->setIsDisturbed();
315 }
316 }
317
225 void BodyStreamBuffer::close() 318 void BodyStreamBuffer::close()
226 { 319 {
320 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
321 controller()->close();
322 else
323 m_stream->close();
227 m_reader = nullptr; 324 m_reader = nullptr;
228 m_stream->close(); 325 m_handle = nullptr;
229 m_handle.clear();
230 } 326 }
231 327
232 void BodyStreamBuffer::error() 328 void BodyStreamBuffer::error()
233 { 329 {
330 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
331 controller()->error(DOMException::create(NetworkError, "network error")) ;
332 else
333 m_stream->error(DOMException::create(NetworkError, "network error"));
234 m_reader = nullptr; 334 m_reader = nullptr;
235 m_stream->error(DOMException::create(NetworkError, "network error")); 335 m_handle = nullptr;
236 m_handle.clear();
237 } 336 }
238 337
239 void BodyStreamBuffer::processData() 338 void BodyStreamBuffer::processData()
240 { 339 {
241 ASSERT(m_reader); 340 ASSERT(m_reader);
242 while (m_streamNeedsMore) { 341 while (m_streamNeedsMore) {
243 const void* buffer; 342 const void* buffer;
244 size_t available; 343 size_t available;
245 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebD ataConsumerHandle::FlagNone, &available); 344 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebD ataConsumerHandle::FlagNone, &available);
246 switch (result) { 345 switch (result) {
247 case WebDataConsumerHandle::Ok: 346 case WebDataConsumerHandle::Ok: {
248 m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(static_c ast<const unsigned char*>(buffer), available)); 347 DOMUint8Array* array = DOMUint8Array::create(static_cast<const unsig ned char*>(buffer), available);
348 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
349 controller()->enqueue(array);
350 m_streamNeedsMore = controller()->desiredSize() > 0;
351 } else {
352 m_streamNeedsMore = m_stream->enqueue(array);
353 }
249 m_reader->endRead(available); 354 m_reader->endRead(available);
250 break; 355 break;
251 356 }
252 case WebDataConsumerHandle::Done: 357 case WebDataConsumerHandle::Done:
253 close(); 358 close();
254 return; 359 return;
255 360
256 case WebDataConsumerHandle::ShouldWait: 361 case WebDataConsumerHandle::ShouldWait:
257 return; 362 return;
258 363
259 case WebDataConsumerHandle::Busy: 364 case WebDataConsumerHandle::Busy:
260 case WebDataConsumerHandle::ResourceExhausted: 365 case WebDataConsumerHandle::ResourceExhausted:
261 case WebDataConsumerHandle::UnexpectedError: 366 case WebDataConsumerHandle::UnexpectedError:
(...skipping 11 matching lines...) Expand all
273 378
274 void BodyStreamBuffer::stopLoading() 379 void BodyStreamBuffer::stopLoading()
275 { 380 {
276 if (!m_loader) 381 if (!m_loader)
277 return; 382 return;
278 m_loader->cancel(); 383 m_loader->cancel();
279 m_loader = nullptr; 384 m_loader = nullptr;
280 } 385 }
281 386
282 } // namespace blink 387 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698