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

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

Powered by Google App Engine
This is Rietveld 408576698