OLD | NEW |
---|---|
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 "config.h" | 5 #include "config.h" |
6 #include "modules/fetch/Body.h" | 6 #include "modules/fetch/Body.h" |
7 | 7 |
8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
9 #include "bindings/core/v8/ScriptPromiseResolver.h" | 9 #include "bindings/core/v8/ScriptPromiseResolver.h" |
10 #include "bindings/core/v8/ScriptState.h" | 10 #include "bindings/core/v8/ScriptState.h" |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 // When the main thread sends a V8::TerminateExecution() signal to a worker | 266 // When the main thread sends a V8::TerminateExecution() signal to a worker |
267 // thread, any V8 API on the worker thread starts returning an empty | 267 // thread, any V8 API on the worker thread starts returning an empty |
268 // handle. This can happen in Body::readAsync. To avoid the situation, we | 268 // handle. This can happen in Body::readAsync. To avoid the situation, we |
269 // first check the ExecutionContext and return immediately if it's already | 269 // first check the ExecutionContext and return immediately if it's already |
270 // gone (which means that the V8::TerminateExecution() signal has been sent | 270 // gone (which means that the V8::TerminateExecution() signal has been sent |
271 // to this worker thread). | 271 // to this worker thread). |
272 ExecutionContext* executionContext = scriptState->executionContext(); | 272 ExecutionContext* executionContext = scriptState->executionContext(); |
273 if (!executionContext) | 273 if (!executionContext) |
274 return ScriptPromise(); | 274 return ScriptPromise(); |
275 | 275 |
276 lockBody(PassBody); | 276 lockBody(); |
277 m_responseType = type; | 277 m_responseType = type; |
278 | 278 |
279 ASSERT(!m_resolver); | 279 ASSERT(!m_resolver); |
280 m_resolver = ScriptPromiseResolver::create(scriptState); | 280 m_resolver = ScriptPromiseResolver::create(scriptState); |
281 ScriptPromise promise = m_resolver->promise(); | 281 ScriptPromise promise = m_resolver->promise(); |
282 | 282 |
283 if (streamAccessed()) { | 283 if (m_stream->stateInternal() == ReadableStream::Closed) { |
284 m_streamSource->createDrainingStream()->readAllAndCreateBlobHandle(mimeT ype(), new BlobHandleReceiver(this)); | 284 // We resolve the resolver manually in order not to use member |
285 } else if (buffer()) { | 285 // variables. |
286 buffer()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver( this)); | 286 switch (m_responseType) { |
287 case ResponseAsArrayBuffer: | |
288 m_resolver->resolve(DOMArrayBuffer::create(nullptr, 0)); | |
289 break; | |
290 case ResponseAsBlob: { | |
291 OwnPtr<BlobData> blobData = BlobData::create(); | |
292 blobData->setContentType(mimeType()); | |
293 m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.rel ease(), 0))); | |
294 break; | |
295 } | |
296 case ResponseAsText: | |
297 m_resolver->resolve(String()); | |
298 break; | |
299 case ResponseAsFormData: | |
300 // TODO(yhirano): Implement this. | |
301 ASSERT_NOT_REACHED(); | |
302 break; | |
303 case ResponseAsJSON: { | |
304 ScriptState::Scope scope(m_resolver->scriptState()); | |
305 m_resolver->reject(V8ThrowException::createSyntaxError(m_resolver->s criptState()->isolate(), "Unexpected end of input")); | |
306 break; | |
307 } | |
308 case ResponseUnknown: | |
309 ASSERT_NOT_REACHED(); | |
310 break; | |
311 } | |
312 m_resolver.clear(); | |
313 } else if (m_stream->stateInternal() == ReadableStream::Errored) { | |
314 m_resolver->reject(m_stream->storedException()); | |
315 m_resolver.clear(); | |
287 } else { | 316 } else { |
horo
2015/04/01 12:04:54
nit: Why don't you continue using "else if"?
yhirano
2015/04/01 12:11:55
Done.
| |
288 readAsyncFromBlob(blobDataHandle()); | 317 if (isBodyConsumed()) { |
318 m_streamSource->createDrainingStream()->readAllAndCreateBlobHandle(m imeType(), new BlobHandleReceiver(this)); | |
319 } else if (buffer()) { | |
320 buffer()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleRecei ver(this)); | |
321 } else { | |
322 readAsyncFromBlob(blobDataHandle()); | |
323 } | |
289 } | 324 } |
290 return promise; | 325 return promise; |
291 } | 326 } |
292 | 327 |
293 void Body::readAsyncFromBlob(PassRefPtr<BlobDataHandle> handle) | 328 void Body::readAsyncFromBlob(PassRefPtr<BlobDataHandle> handle) |
294 { | 329 { |
295 FileReaderLoader::ReadType readType = FileReaderLoader::ReadAsText; | 330 FileReaderLoader::ReadType readType = FileReaderLoader::ReadAsText; |
296 RefPtr<BlobDataHandle> blobHandle = handle; | 331 RefPtr<BlobDataHandle> blobHandle = handle; |
297 if (!blobHandle) | 332 if (!blobHandle) |
298 blobHandle = BlobDataHandle::create(BlobData::create(), 0); | 333 blobHandle = BlobDataHandle::create(BlobData::create(), 0); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 { | 412 { |
378 ASSERT(!bodyUsed()); | 413 ASSERT(!bodyUsed()); |
379 if (option == PassBody) | 414 if (option == PassBody) |
380 m_bodyUsed = true; | 415 m_bodyUsed = true; |
381 ASSERT(!m_stream->isLocked()); | 416 ASSERT(!m_stream->isLocked()); |
382 TrackExceptionState exceptionState; | 417 TrackExceptionState exceptionState; |
383 m_stream->getBytesReader(executionContext(), exceptionState); | 418 m_stream->getBytesReader(executionContext(), exceptionState); |
384 ASSERT(!exceptionState.hadException()); | 419 ASSERT(!exceptionState.hadException()); |
385 } | 420 } |
386 | 421 |
387 bool Body::streamAccessed() const | 422 bool Body::isBodyConsumed() const |
388 { | 423 { |
389 return m_streamSource->state() != m_streamSource->Initial; | 424 if (m_streamSource->state() != m_streamSource->Initial) { |
425 // Some data is pulled from the source. | |
426 return true; | |
427 } | |
428 if (m_stream->stateInternal() == ReadableStream::Closed) { | |
429 // Return true if the blob handle is originally not empty. | |
430 RefPtr<BlobDataHandle> handle = blobDataHandle(); | |
431 return handle && handle->size(); | |
432 } | |
433 if (m_stream->stateInternal() == ReadableStream::Errored) { | |
434 // The stream is errored. That means an effort to read data was made. | |
435 return true; | |
436 } | |
437 return false; | |
390 } | 438 } |
391 | 439 |
392 void Body::refreshBody() | 440 void Body::refreshBody() |
393 { | 441 { |
394 m_streamSource = new ReadableStreamSource(this); | 442 m_streamSource = new ReadableStreamSource(this); |
395 m_stream = new ReadableByteStream(m_streamSource, new ReadableByteStream::St rictStrategy); | 443 m_stream = new ReadableByteStream(m_streamSource, new ReadableByteStream::St rictStrategy); |
396 m_streamSource->startStream(m_stream); | 444 m_streamSource->startStream(m_stream); |
397 } | 445 } |
398 | 446 |
399 BodyStreamBuffer* Body::createDrainingStream() | 447 BodyStreamBuffer* Body::createDrainingStream() |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 void Body::didBlobHandleReceiveError(PassRefPtrWillBeRawPtr<DOMException> except ion) | 553 void Body::didBlobHandleReceiveError(PassRefPtrWillBeRawPtr<DOMException> except ion) |
506 { | 554 { |
507 if (!m_resolver) | 555 if (!m_resolver) |
508 return; | 556 return; |
509 m_stream->error(DOMException::create(NetworkError, "network error")); | 557 m_stream->error(DOMException::create(NetworkError, "network error")); |
510 m_resolver->reject(exception); | 558 m_resolver->reject(exception); |
511 m_resolver.clear(); | 559 m_resolver.clear(); |
512 } | 560 } |
513 | 561 |
514 } // namespace blink | 562 } // namespace blink |
OLD | NEW |