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

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::Object> body = toV8(this, scriptState).As<v8::Object>();
91 ASSERT(!body.IsEmpty());
Yuki 2016/04/20 12:15:26 This check looks a bit weird. toV8() may return no
yhirano 2016/04/21 03:41:42 Done.
92
93 ScriptValue readableStream = ReadableStreamOperations::createReadableStr eam(
94 scriptState, this, ReadableStreamOperations::createCountQueuingStrat egy(scriptState, 0));
95 V8HiddenValue::setHiddenValue(scriptState, body, V8HiddenValue::internal BodyStream(scriptState->isolate()), readableStream.v8Value());
96 } else {
97 m_stream = new ReadableByteStream(this, new ReadableByteStream::StrictSt rategy);
98 m_stream->didSourceStart();
99 }
83 } 100 }
84 101
85 PassRefPtr<BlobDataHandle> BodyStreamBuffer::drainAsBlobDataHandle(ExecutionCont ext* executionContext, FetchDataConsumerHandle::Reader::BlobSizePolicy policy) 102 ScriptValue BodyStreamBuffer::stream()
103 {
104 ScriptState::Scope scope(m_scriptState.get());
105 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
106 v8::Local<v8::Object> body = toV8(this, m_scriptState.get()).As<v8::Obje ct>();
107 ASSERT(!body.IsEmpty());
Yuki 2016/04/20 12:15:26 Ditto.
yhirano 2016/04/21 03:41:42 Done.
108 return ScriptValue(m_scriptState.get(), V8HiddenValue::getHiddenValue(m_ scriptState.get(), body, V8HiddenValue::internalBodyStream(m_scriptState->isolat e())));
109 }
110 return ScriptValue(m_scriptState.get(), toV8(m_stream, m_scriptState.get())) ;
111 }
112
113 PassRefPtr<BlobDataHandle> BodyStreamBuffer::drainAsBlobDataHandle(FetchDataCons umerHandle::Reader::BlobSizePolicy policy)
86 { 114 {
87 ASSERT(!isStreamLocked()); 115 ASSERT(!isStreamLocked());
88 ASSERT(!isStreamDisturbed()); 116 ASSERT(!isStreamDisturbed());
89 if (isStreamClosed() || isStreamErrored()) 117 if (isStreamClosed() || isStreamErrored())
90 return nullptr; 118 return nullptr;
91 119
92 RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle(poli cy); 120 RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle(poli cy);
93 if (blobDataHandle) { 121 if (blobDataHandle) {
94 NonThrowableExceptionState exceptionState; 122 lockAndDisturb();
95 m_stream->getBytesReader(executionContext, exceptionState);
96 m_stream->setIsDisturbed();
97 close(); 123 close();
98 return blobDataHandle.release(); 124 return blobDataHandle.release();
99 } 125 }
100 return nullptr; 126 return nullptr;
101 } 127 }
102 128
103 PassRefPtr<EncodedFormData> BodyStreamBuffer::drainAsFormData(ExecutionContext* executionContext) 129 PassRefPtr<EncodedFormData> BodyStreamBuffer::drainAsFormData()
104 { 130 {
105 ASSERT(!isStreamLocked()); 131 ASSERT(!isStreamLocked());
106 ASSERT(!isStreamDisturbed()); 132 ASSERT(!isStreamDisturbed());
107 if (isStreamClosed() || isStreamErrored()) 133 if (isStreamClosed() || isStreamErrored())
108 return nullptr; 134 return nullptr;
109 135
110 RefPtr<EncodedFormData> formData = m_reader->drainAsFormData(); 136 RefPtr<EncodedFormData> formData = m_reader->drainAsFormData();
111 if (formData) { 137 if (formData) {
112 NonThrowableExceptionState exceptionState; 138 lockAndDisturb();
113 m_stream->getBytesReader(executionContext, exceptionState);
114 m_stream->setIsDisturbed();
115 close(); 139 close();
116 return formData.release(); 140 return formData.release();
117 } 141 }
118 return nullptr; 142 return nullptr;
119 } 143 }
120 144
121 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle(ExecutionCon text* executionContext) 145 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle()
122 { 146 {
123 ASSERT(!isStreamLocked()); 147 ASSERT(!isStreamLocked());
124 ASSERT(!isStreamDisturbed()); 148 ASSERT(!isStreamDisturbed());
125 m_reader = nullptr; 149 lockAndDisturb();
126 m_stream->setIsDisturbed();
127 NonThrowableExceptionState exceptionState;
128 m_stream->getBytesReader(executionContext, exceptionState);
129 150
130 if (isStreamClosed()) 151 if (isStreamClosed())
131 return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumer Handle()); 152 return createFetchDataConsumerHandleFromWebHandle(createDoneDataConsumer Handle());
132 if (isStreamErrored()) 153 if (isStreamErrored())
133 return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorD ataConsumerHandle()); 154 return createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorD ataConsumerHandle());
134 155
135 ASSERT(m_handle); 156 ASSERT(m_handle);
136 OwnPtr<FetchDataConsumerHandle> handle = m_handle.release(); 157 OwnPtr<FetchDataConsumerHandle> handle = m_handle.release();
137 close(); 158 close();
138 return handle.release(); 159 return handle.release();
139 } 160 }
140 161
141 void BodyStreamBuffer::startLoading(ExecutionContext* executionContext, FetchDat aLoader* loader, FetchDataLoader::Client* client) 162 void BodyStreamBuffer::startLoading(FetchDataLoader* loader, FetchDataLoader::Cl ient* client)
142 { 163 {
143 ASSERT(!m_loader); 164 ASSERT(!m_loader);
144 OwnPtr<FetchDataConsumerHandle> handle = releaseHandle(executionContext); 165 OwnPtr<FetchDataConsumerHandle> handle = releaseHandle();
145 m_loader = loader; 166 m_loader = loader;
146 loader->start(handle.get(), new LoaderClient(executionContext, this, client) ); 167 loader->start(handle.get(), new LoaderClient(m_scriptState->getExecutionCont ext(), this, client));
147 } 168 }
148 169
149 bool BodyStreamBuffer::hasPendingActivity() const 170 bool BodyStreamBuffer::hasPendingActivity() const
150 { 171 {
151 return m_loader || (isStreamLocked() && isStreamReadable()); 172 if (m_loader)
173 return true;
174 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
175 return UnderlyingSourceBase::hasPendingActivity();
176
177 return m_stream->stateInternal() == ReadableStream::Readable && m_stream->is Locked();
152 } 178 }
153 179
154 void BodyStreamBuffer::stop() 180 void BodyStreamBuffer::stop()
155 { 181 {
156 m_reader = nullptr; 182 m_reader = nullptr;
157 m_handle = nullptr; 183 m_handle = nullptr;
158 } 184 }
159 185
160 void BodyStreamBuffer::pullSource() 186 void BodyStreamBuffer::pullSource()
161 { 187 {
162 ASSERT(!m_streamNeedsMore); 188 ASSERT(!m_streamNeedsMore);
163 m_streamNeedsMore = true; 189 m_streamNeedsMore = true;
164 processData(); 190 processData();
165 } 191 }
166 192
167 ScriptPromise BodyStreamBuffer::cancelSource(ScriptState* scriptState, ScriptVal ue) 193 ScriptPromise BodyStreamBuffer::cancelSource(ScriptState* scriptState, ScriptVal ue)
168 { 194 {
195 ASSERT(scriptState == m_scriptState.get());
169 close(); 196 close();
170 return ScriptPromise::castUndefined(scriptState); 197 return ScriptPromise::castUndefined(scriptState);
171 } 198 }
199
200 ScriptPromise BodyStreamBuffer::pull(ScriptState* scriptState)
201 {
202 ASSERT(!m_streamNeedsMore);
203 ASSERT(scriptState == m_scriptState.get());
204 m_streamNeedsMore = true;
205 processData();
206 return ScriptPromise::castUndefined(scriptState);
207 }
208
209 ScriptPromise BodyStreamBuffer::cancel(ScriptState* scriptState, ScriptValue rea son)
210 {
211 ASSERT(scriptState == m_scriptState.get());
212 close();
213 return ScriptPromise::castUndefined(scriptState);
214 }
172 215
173 void BodyStreamBuffer::didGetReadable() 216 void BodyStreamBuffer::didGetReadable()
174 { 217 {
175 if (!m_reader) 218 if (!m_reader)
176 return; 219 return;
177 220
178 if (!m_streamNeedsMore) { 221 if (!m_streamNeedsMore) {
179 // Perform zero-length read to call close()/error() early. 222 // Perform zero-length read to call close()/error() early.
180 size_t readSize; 223 size_t readSize;
181 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDat aConsumerHandle::FlagNone, &readSize); 224 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDat aConsumerHandle::FlagNone, &readSize);
182 switch (result) { 225 switch (result) {
183 case WebDataConsumerHandle::Ok: 226 case WebDataConsumerHandle::Ok:
184 case WebDataConsumerHandle::ShouldWait: 227 case WebDataConsumerHandle::ShouldWait:
185 return; 228 return;
186 case WebDataConsumerHandle::Done: 229 case WebDataConsumerHandle::Done:
187 close(); 230 close();
188 return; 231 return;
189 case WebDataConsumerHandle::Busy: 232 case WebDataConsumerHandle::Busy:
190 case WebDataConsumerHandle::ResourceExhausted: 233 case WebDataConsumerHandle::ResourceExhausted:
191 case WebDataConsumerHandle::UnexpectedError: 234 case WebDataConsumerHandle::UnexpectedError:
192 error(); 235 error();
193 return; 236 return;
194 } 237 }
195 return; 238 return;
196 } 239 }
197 processData(); 240 processData();
198 } 241 }
199 242
200 bool BodyStreamBuffer::isStreamReadable() const 243 bool BodyStreamBuffer::isStreamReadable()
201 { 244 {
245 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
246 ScriptState::Scope scope(m_scriptState.get());
247 return ReadableStreamOperations::isReadable(m_scriptState.get(), stream( ));
248 }
202 return m_stream->stateInternal() == ReadableStream::Readable; 249 return m_stream->stateInternal() == ReadableStream::Readable;
203 } 250 }
204 251
205 bool BodyStreamBuffer::isStreamClosed() const 252 bool BodyStreamBuffer::isStreamClosed()
206 { 253 {
254 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
255 ScriptState::Scope scope(m_scriptState.get());
256 return ReadableStreamOperations::isClosed(m_scriptState.get(), stream()) ;
257 }
207 return m_stream->stateInternal() == ReadableStream::Closed; 258 return m_stream->stateInternal() == ReadableStream::Closed;
208 } 259 }
209 260
210 bool BodyStreamBuffer::isStreamErrored() const 261 bool BodyStreamBuffer::isStreamErrored()
211 { 262 {
263 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
264 ScriptState::Scope scope(m_scriptState.get());
265 return ReadableStreamOperations::isErrored(m_scriptState.get(), stream() );
266 }
212 return m_stream->stateInternal() == ReadableStream::Errored; 267 return m_stream->stateInternal() == ReadableStream::Errored;
213 } 268 }
214 269
215 bool BodyStreamBuffer::isStreamLocked() const 270 bool BodyStreamBuffer::isStreamLocked()
216 { 271 {
272 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
273 ScriptState::Scope scope(m_scriptState.get());
274 return ReadableStreamOperations::isLocked(m_scriptState.get(), stream()) ;
275 }
217 return m_stream->isLocked(); 276 return m_stream->isLocked();
218 } 277 }
219 278
220 bool BodyStreamBuffer::isStreamDisturbed() const 279 bool BodyStreamBuffer::isStreamDisturbed()
221 { 280 {
281 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
282 ScriptState::Scope scope(m_scriptState.get());
283 return ReadableStreamOperations::isDisturbed(m_scriptState.get(), stream ());
284 }
222 return m_stream->isDisturbed(); 285 return m_stream->isDisturbed();
223 } 286 }
224 287
288 void BodyStreamBuffer::setDisturbed()
289 {
290 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
291 ScriptState::Scope scope(m_scriptState.get());
292 ReadableStreamOperations::setDisturbed(m_scriptState.get(), stream());
293 } else {
294 m_stream->setIsDisturbed();
295 }
296 }
297
298 void BodyStreamBuffer::lockAndDisturb()
299 {
300 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
301 ScriptState::Scope scope(m_scriptState.get());
302 NonThrowableExceptionState exceptionState;
303 ReadableStreamOperations::getReader(m_scriptState.get(), stream(), excep tionState);
304 ReadableStreamOperations::setDisturbed(m_scriptState.get(), stream());
305 } else {
306 NonThrowableExceptionState exceptionState;
307 m_stream->getBytesReader(m_scriptState->getExecutionContext(), exception State);
308 m_stream->setIsDisturbed();
309 }
310 }
311
225 void BodyStreamBuffer::close() 312 void BodyStreamBuffer::close()
226 { 313 {
314 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
315 controller()->close();
316 else
317 m_stream->close();
227 m_reader = nullptr; 318 m_reader = nullptr;
228 m_stream->close(); 319 m_handle = nullptr;
229 m_handle.clear();
230 } 320 }
231 321
232 void BodyStreamBuffer::error() 322 void BodyStreamBuffer::error()
233 { 323 {
324 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled())
325 controller()->error(DOMException::create(NetworkError, "network error")) ;
326 else
327 m_stream->error(DOMException::create(NetworkError, "network error"));
234 m_reader = nullptr; 328 m_reader = nullptr;
235 m_stream->error(DOMException::create(NetworkError, "network error")); 329 m_handle = nullptr;
236 m_handle.clear();
237 } 330 }
238 331
239 void BodyStreamBuffer::processData() 332 void BodyStreamBuffer::processData()
240 { 333 {
241 ASSERT(m_reader); 334 ASSERT(m_reader);
242 while (m_streamNeedsMore) { 335 while (m_streamNeedsMore) {
243 const void* buffer; 336 const void* buffer;
244 size_t available; 337 size_t available;
245 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebD ataConsumerHandle::FlagNone, &available); 338 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebD ataConsumerHandle::FlagNone, &available);
246 switch (result) { 339 switch (result) {
247 case WebDataConsumerHandle::Ok: 340 case WebDataConsumerHandle::Ok:
248 m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(static_c ast<const unsigned char*>(buffer), available)); 341 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) {
342 controller()->enqueue(DOMUint8Array::create(static_cast<const un signed char*>(buffer), available));
343 m_streamNeedsMore = controller()->desiredSize() > 0;
344 } else {
345 m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(stat ic_cast<const unsigned char*>(buffer), available));
346 }
249 m_reader->endRead(available); 347 m_reader->endRead(available);
250 break; 348 break;
251 349
252 case WebDataConsumerHandle::Done: 350 case WebDataConsumerHandle::Done:
253 close(); 351 close();
254 return; 352 return;
255 353
256 case WebDataConsumerHandle::ShouldWait: 354 case WebDataConsumerHandle::ShouldWait:
257 return; 355 return;
258 356
(...skipping 14 matching lines...) Expand all
273 371
274 void BodyStreamBuffer::stopLoading() 372 void BodyStreamBuffer::stopLoading()
275 { 373 {
276 if (!m_loader) 374 if (!m_loader)
277 return; 375 return;
278 m_loader->cancel(); 376 m_loader->cancel();
279 m_loader = nullptr; 377 m_loader = nullptr;
280 } 378 }
281 379
282 } // namespace blink 380 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698