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

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, 8 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/V8BindingMacros.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(handle) 83 : UnderlyingSourceBase(scriptState)
84 , m_scriptState(scriptState)
85 , m_handle(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 OwnPtr<FetchDataConsumerHandle> handle = releaseHandle();
145 m_loader = loader; 170 m_loader = loader;
146 loader->start(handle.get(), new LoaderClient(executionContext, this, client) ); 171 loader->start(handle.get(), new LoaderClient(m_scriptState->getExecutionCont ext(), this, client));
haraken 2016/04/21 04:36:28 Don't you need: if (!m_scriptState->contextIsVa
yhirano 2016/04/21 08:14:22 I'd like to assert that the context is valid here.
147 } 172 }
148 173
149 bool BodyStreamBuffer::hasPendingActivity() const 174 bool BodyStreamBuffer::hasPendingActivity() const
150 { 175 {
151 return m_loader || (isStreamLocked() && isStreamReadable()); 176 if (m_loader)
177 return true;
178 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
179 return UnderlyingSourceBase::hasPendingActivity();
180
181 return m_stream->stateInternal() == ReadableStream::Readable && m_stream->is Locked();
152 } 182 }
153 183
154 void BodyStreamBuffer::stop() 184 void BodyStreamBuffer::stop()
155 { 185 {
156 m_reader = nullptr; 186 m_reader = nullptr;
157 m_handle = nullptr; 187 m_handle = nullptr;
158 } 188 }
159 189
160 void BodyStreamBuffer::pullSource() 190 void BodyStreamBuffer::pullSource()
161 { 191 {
162 ASSERT(!m_streamNeedsMore); 192 ASSERT(!m_streamNeedsMore);
163 m_streamNeedsMore = true; 193 m_streamNeedsMore = true;
164 processData(); 194 processData();
165 } 195 }
166 196
167 ScriptPromise BodyStreamBuffer::cancelSource(ScriptState* scriptState, ScriptVal ue) 197 ScriptPromise BodyStreamBuffer::cancelSource(ScriptState* scriptState, ScriptVal ue)
168 { 198 {
199 ASSERT(scriptState == m_scriptState.get());
169 close(); 200 close();
170 return ScriptPromise::castUndefined(scriptState); 201 return ScriptPromise::castUndefined(scriptState);
171 } 202 }
203
204 ScriptPromise BodyStreamBuffer::pull(ScriptState* scriptState)
205 {
206 ASSERT(!m_streamNeedsMore);
207 ASSERT(scriptState == m_scriptState.get());
208 m_streamNeedsMore = true;
209 processData();
210 return ScriptPromise::castUndefined(scriptState);
211 }
212
213 ScriptPromise BodyStreamBuffer::cancel(ScriptState* scriptState, ScriptValue rea son)
214 {
215 ASSERT(scriptState == m_scriptState.get());
216 close();
217 return ScriptPromise::castUndefined(scriptState);
218 }
172 219
173 void BodyStreamBuffer::didGetReadable() 220 void BodyStreamBuffer::didGetReadable()
174 { 221 {
175 if (!m_reader) 222 if (!m_reader)
176 return; 223 return;
177 224
178 if (!m_streamNeedsMore) { 225 if (!m_streamNeedsMore) {
179 // Perform zero-length read to call close()/error() early. 226 // Perform zero-length read to call close()/error() early.
180 size_t readSize; 227 size_t readSize;
181 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDat aConsumerHandle::FlagNone, &readSize); 228 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDat aConsumerHandle::FlagNone, &readSize);
182 switch (result) { 229 switch (result) {
183 case WebDataConsumerHandle::Ok: 230 case WebDataConsumerHandle::Ok:
184 case WebDataConsumerHandle::ShouldWait: 231 case WebDataConsumerHandle::ShouldWait:
185 return; 232 return;
186 case WebDataConsumerHandle::Done: 233 case WebDataConsumerHandle::Done:
187 close(); 234 close();
188 return; 235 return;
189 case WebDataConsumerHandle::Busy: 236 case WebDataConsumerHandle::Busy:
190 case WebDataConsumerHandle::ResourceExhausted: 237 case WebDataConsumerHandle::ResourceExhausted:
191 case WebDataConsumerHandle::UnexpectedError: 238 case WebDataConsumerHandle::UnexpectedError:
192 error(); 239 error();
193 return; 240 return;
194 } 241 }
195 return; 242 return;
196 } 243 }
197 processData(); 244 processData();
198 } 245 }
199 246
200 bool BodyStreamBuffer::isStreamReadable() const 247 bool BodyStreamBuffer::isStreamReadable()
201 { 248 {
249 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
250 ScriptState::Scope scope(m_scriptState.get());
haraken 2016/04/21 04:36:28 Ditto. I guess you need to check m_scriptState->co
yhirano 2016/04/21 08:14:22 I'd like to assert that the context is valid here,
251 return ReadableStreamOperations::isReadable(m_scriptState.get(), stream( ));
252 }
202 return m_stream->stateInternal() == ReadableStream::Readable; 253 return m_stream->stateInternal() == ReadableStream::Readable;
203 } 254 }
204 255
205 bool BodyStreamBuffer::isStreamClosed() const 256 bool BodyStreamBuffer::isStreamClosed()
206 { 257 {
258 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
259 ScriptState::Scope scope(m_scriptState.get());
260 return ReadableStreamOperations::isClosed(m_scriptState.get(), stream()) ;
261 }
207 return m_stream->stateInternal() == ReadableStream::Closed; 262 return m_stream->stateInternal() == ReadableStream::Closed;
208 } 263 }
209 264
210 bool BodyStreamBuffer::isStreamErrored() const 265 bool BodyStreamBuffer::isStreamErrored()
211 { 266 {
267 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
268 ScriptState::Scope scope(m_scriptState.get());
269 return ReadableStreamOperations::isErrored(m_scriptState.get(), stream() );
270 }
212 return m_stream->stateInternal() == ReadableStream::Errored; 271 return m_stream->stateInternal() == ReadableStream::Errored;
213 } 272 }
214 273
215 bool BodyStreamBuffer::isStreamLocked() const 274 bool BodyStreamBuffer::isStreamLocked()
216 { 275 {
276 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
277 ScriptState::Scope scope(m_scriptState.get());
278 return ReadableStreamOperations::isLocked(m_scriptState.get(), stream()) ;
279 }
217 return m_stream->isLocked(); 280 return m_stream->isLocked();
218 } 281 }
219 282
220 bool BodyStreamBuffer::isStreamDisturbed() const 283 bool BodyStreamBuffer::isStreamDisturbed()
221 { 284 {
285 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
286 ScriptState::Scope scope(m_scriptState.get());
287 return ReadableStreamOperations::isDisturbed(m_scriptState.get(), stream ());
288 }
222 return m_stream->isDisturbed(); 289 return m_stream->isDisturbed();
223 } 290 }
224 291
292 void BodyStreamBuffer::setDisturbed()
293 {
294 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
295 ScriptState::Scope scope(m_scriptState.get());
296 ReadableStreamOperations::setDisturbed(m_scriptState.get(), stream());
297 } else {
298 m_stream->setIsDisturbed();
299 }
300 }
301
302 void BodyStreamBuffer::lockAndDisturb()
303 {
304 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
305 ScriptState::Scope scope(m_scriptState.get());
306 NonThrowableExceptionState exceptionState;
307 ReadableStreamOperations::getReader(m_scriptState.get(), stream(), excep tionState);
308 ReadableStreamOperations::setDisturbed(m_scriptState.get(), stream());
309 } else {
310 NonThrowableExceptionState exceptionState;
311 m_stream->getBytesReader(m_scriptState->getExecutionContext(), exception State);
312 m_stream->setIsDisturbed();
313 }
314 }
315
225 void BodyStreamBuffer::close() 316 void BodyStreamBuffer::close()
226 { 317 {
318 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
319 controller()->close();
320 else
321 m_stream->close();
227 m_reader = nullptr; 322 m_reader = nullptr;
228 m_stream->close(); 323 m_handle = nullptr;
229 m_handle.clear();
230 } 324 }
231 325
232 void BodyStreamBuffer::error() 326 void BodyStreamBuffer::error()
233 { 327 {
328 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
329 controller()->error(DOMException::create(NetworkError, "network error")) ;
330 else
331 m_stream->error(DOMException::create(NetworkError, "network error"));
234 m_reader = nullptr; 332 m_reader = nullptr;
235 m_stream->error(DOMException::create(NetworkError, "network error")); 333 m_handle = nullptr;
236 m_handle.clear();
237 } 334 }
238 335
239 void BodyStreamBuffer::processData() 336 void BodyStreamBuffer::processData()
240 { 337 {
241 ASSERT(m_reader); 338 ASSERT(m_reader);
242 while (m_streamNeedsMore) { 339 while (m_streamNeedsMore) {
243 const void* buffer; 340 const void* buffer;
244 size_t available; 341 size_t available;
245 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebD ataConsumerHandle::FlagNone, &available); 342 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebD ataConsumerHandle::FlagNone, &available);
246 switch (result) { 343 switch (result) {
247 case WebDataConsumerHandle::Ok: 344 case WebDataConsumerHandle::Ok:
248 m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(static_c ast<const unsigned char*>(buffer), available)); 345 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
346 controller()->enqueue(DOMUint8Array::create(static_cast<const un signed char*>(buffer), available));
347 m_streamNeedsMore = controller()->desiredSize() > 0;
348 } else {
349 m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(stat ic_cast<const unsigned char*>(buffer), available));
350 }
249 m_reader->endRead(available); 351 m_reader->endRead(available);
250 break; 352 break;
251 353
252 case WebDataConsumerHandle::Done: 354 case WebDataConsumerHandle::Done:
253 close(); 355 close();
254 return; 356 return;
255 357
256 case WebDataConsumerHandle::ShouldWait: 358 case WebDataConsumerHandle::ShouldWait:
257 return; 359 return;
258 360
(...skipping 14 matching lines...) Expand all
273 375
274 void BodyStreamBuffer::stopLoading() 376 void BodyStreamBuffer::stopLoading()
275 { 377 {
276 if (!m_loader) 378 if (!m_loader)
277 return; 379 return;
278 m_loader->cancel(); 380 m_loader->cancel();
279 m_loader = nullptr; 381 m_loader = nullptr;
280 } 382 }
281 383
282 } // namespace blink 384 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698