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

Side by Side Diff: Source/modules/fetch/Body.cpp

Issue 1173173006: [2c] Replace Body::readAsyncFromBlob with readAsyncFromFetchDataConsumerHandle (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Add #include to ResponseTest.cpp Created 5 years, 5 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 "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"
11 #include "bindings/core/v8/V8ArrayBuffer.h" 11 #include "bindings/core/v8/V8ArrayBuffer.h"
12 #include "bindings/core/v8/V8ThrowException.h" 12 #include "bindings/core/v8/V8ThrowException.h"
13 #include "core/dom/DOMArrayBuffer.h" 13 #include "core/dom/DOMArrayBuffer.h"
14 #include "core/dom/DOMTypedArray.h" 14 #include "core/dom/DOMTypedArray.h"
15 #include "core/fileapi/Blob.h" 15 #include "core/fileapi/Blob.h"
16 #include "core/fileapi/FileReaderLoader.h" 16 #include "core/fileapi/FileReaderLoader.h"
17 #include "core/fileapi/FileReaderLoaderClient.h" 17 #include "core/fileapi/FileReaderLoaderClient.h"
18 #include "core/frame/UseCounter.h" 18 #include "core/frame/UseCounter.h"
19 #include "core/streams/ReadableByteStream.h" 19 #include "core/streams/ReadableByteStream.h"
20 #include "core/streams/ReadableByteStreamReader.h" 20 #include "core/streams/ReadableByteStreamReader.h"
21 #include "core/streams/UnderlyingSource.h" 21 #include "core/streams/UnderlyingSource.h"
22 #include "modules/fetch/BodyStreamBuffer.h" 22 #include "modules/fetch/BodyStreamBuffer.h"
23 #include "modules/fetch/DataConsumerHandleUtil.h"
24 #include "modules/fetch/FetchBlobDataConsumerHandle.h"
23 25
24 namespace blink { 26 namespace blink {
25 27
26 class Body::BlobHandleReceiver final : public BodyStreamBuffer::BlobHandleCreato rClient { 28 class Body::BlobHandleReceiver final : public BodyStreamBuffer::BlobHandleCreato rClient {
27 public: 29 public:
28 explicit BlobHandleReceiver(Body* body) 30 explicit BlobHandleReceiver(Body* body)
29 : m_body(body) 31 : m_body(body)
30 { 32 {
31 } 33 }
32 void didCreateBlobHandle(PassRefPtr<BlobDataHandle> handle) override 34 void didCreateBlobHandle(PassRefPtr<BlobDataHandle> handle) override
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 } else if (isBodyConsumed()) { 344 } else if (isBodyConsumed()) {
343 m_streamSource->createDrainingStream()->readAllAndCreateBlobHandle(mimeT ype(), new BlobHandleReceiver(this)); 345 m_streamSource->createDrainingStream()->readAllAndCreateBlobHandle(mimeT ype(), new BlobHandleReceiver(this));
344 } else if (buffer()) { 346 } else if (buffer()) {
345 buffer()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver( this)); 347 buffer()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver( this));
346 } else { 348 } else {
347 readAsyncFromBlob(blobDataHandle()); 349 readAsyncFromBlob(blobDataHandle());
348 } 350 }
349 return promise; 351 return promise;
350 } 352 }
351 353
354 void Body::readAsyncFromFetchDataConsumerHandle(FetchDataConsumerHandle* handle, const String& mimeType)
355 {
356 ASSERT(!m_fetchDataLoader);
357
358 switch (m_responseType) {
359 case ResponseAsArrayBuffer:
360 m_fetchDataLoader = FetchDataLoader::createLoaderAsArrayBuffer();
361 break;
362
363 case ResponseAsJSON:
364 case ResponseAsText:
365 m_fetchDataLoader = FetchDataLoader::createLoaderAsString();
366 break;
367
368 case ResponseAsBlob:
369 m_fetchDataLoader = FetchDataLoader::createLoaderAsBlobHandle(mimeType);
370 break;
371
372 case ResponseAsFormData:
373 // FIXME: Implement this.
374 ASSERT_NOT_REACHED();
375 return;
376
377 default:
378 ASSERT_NOT_REACHED();
379 return;
380 }
381
382 m_fetchDataLoader->start(handle, this);
383 }
384
352 void Body::readAsyncFromBlob(PassRefPtr<BlobDataHandle> handle) 385 void Body::readAsyncFromBlob(PassRefPtr<BlobDataHandle> handle)
353 { 386 {
354 FileReaderLoader::ReadType readType = FileReaderLoader::ReadAsText; 387 readAsyncFromFetchDataConsumerHandle(FetchBlobDataConsumerHandle::create(exe cutionContext(), handle).get(), mimeType());
355 RefPtr<BlobDataHandle> blobHandle = handle;
356 if (!blobHandle)
357 blobHandle = BlobDataHandle::create(BlobData::create(), 0);
358 switch (m_responseType) {
359 case ResponseAsArrayBuffer:
360 readType = FileReaderLoader::ReadAsArrayBuffer;
361 break;
362 case ResponseAsBlob:
363 if (blobHandle->size() != kuint64max) {
364 // If the size of |blobHandle| is set correctly, creates Blob from
365 // it.
366 if (blobHandle->type() != mimeType()) {
367 // A new BlobDataHandle is created to override the Blob's type.
368 m_resolver->resolve(Blob::create(BlobDataHandle::create(blobHand le->uuid(), mimeType(), blobHandle->size())));
369 } else {
370 m_resolver->resolve(Blob::create(blobHandle));
371 }
372 m_stream->close();
373 m_resolver.clear();
374 return;
375 }
376 // If the size is not set, read as ArrayBuffer and create a new blob to
377 // get the size.
378 // FIXME: This workaround is not good for performance.
379 // When we will stop using Blob as a base system of Body to support
380 // stream, this problem should be solved.
381 readType = FileReaderLoader::ReadAsArrayBuffer;
382 break;
383 case ResponseAsFormData:
384 // FIXME: Implement this.
385 ASSERT_NOT_REACHED();
386 break;
387 case ResponseAsJSON:
388 case ResponseAsText:
389 break;
390 default:
391 ASSERT_NOT_REACHED();
392 }
393
394 m_loader = FileReaderLoader::create(readType, this);
395 m_loader->start(m_resolver->scriptState()->executionContext(), blobHandle);
396
397 return;
398 } 388 }
399 389
400 ScriptPromise Body::arrayBuffer(ScriptState* scriptState) 390 ScriptPromise Body::arrayBuffer(ScriptState* scriptState)
401 { 391 {
402 return readAsync(scriptState, ResponseAsArrayBuffer); 392 return readAsync(scriptState, ResponseAsArrayBuffer);
403 } 393 }
404 394
405 ScriptPromise Body::blob(ScriptState* scriptState) 395 ScriptPromise Body::blob(ScriptState* scriptState)
406 { 396 {
407 return readAsync(scriptState, ResponseAsBlob); 397 return readAsync(scriptState, ResponseAsBlob);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 m_streamSource->startStream(m_stream); 459 m_streamSource->startStream(m_stream);
470 } 460 }
471 461
472 BodyStreamBuffer* Body::createDrainingStream() 462 BodyStreamBuffer* Body::createDrainingStream()
473 { 463 {
474 return m_streamSource->createDrainingStream(); 464 return m_streamSource->createDrainingStream();
475 } 465 }
476 466
477 void Body::stop() 467 void Body::stop()
478 { 468 {
479 // Canceling the load will call didFail which will remove the resolver. 469 if (m_fetchDataLoader) {
480 if (m_loader) 470 m_fetchDataLoader->cancel();
481 m_loader->cancel(); 471 m_fetchDataLoader.clear();
472 }
482 } 473 }
483 474
484 bool Body::hasPendingActivity() const 475 bool Body::hasPendingActivity() const
485 { 476 {
486 if (executionContext()->activeDOMObjectsAreStopped()) 477 if (executionContext()->activeDOMObjectsAreStopped())
487 return false; 478 return false;
488 if (m_resolver) 479 if (m_resolver)
489 return true; 480 return true;
490 if (m_stream->isLocked()) 481 if (m_stream->isLocked())
491 return true; 482 return true;
492 return false; 483 return false;
493 } 484 }
494 485
495 Body::ReadableStreamSource* Body::createBodySource(PassRefPtr<BlobDataHandle> ha ndle) 486 Body::ReadableStreamSource* Body::createBodySource(PassRefPtr<BlobDataHandle> ha ndle)
496 { 487 {
497 return new ReadableStreamSource(executionContext(), handle); 488 return new ReadableStreamSource(executionContext(), handle);
498 } 489 }
499 490
500 Body::ReadableStreamSource* Body::createBodySource(BodyStreamBuffer* buffer) 491 Body::ReadableStreamSource* Body::createBodySource(BodyStreamBuffer* buffer)
501 { 492 {
502 return new ReadableStreamSource(executionContext(), buffer); 493 return new ReadableStreamSource(executionContext(), buffer);
503 } 494 }
504 495
505 DEFINE_TRACE(Body) 496 DEFINE_TRACE(Body)
506 { 497 {
498 visitor->trace(m_fetchDataLoader);
507 visitor->trace(m_resolver); 499 visitor->trace(m_resolver);
508 visitor->trace(m_stream); 500 visitor->trace(m_stream);
509 visitor->trace(m_streamSource); 501 visitor->trace(m_streamSource);
510 ActiveDOMObject::trace(visitor); 502 ActiveDOMObject::trace(visitor);
503 FetchDataLoader::Client::trace(visitor);
511 } 504 }
512 505
513 Body::Body(ExecutionContext* context) 506 Body::Body(ExecutionContext* context)
514 : ActiveDOMObject(context) 507 : ActiveDOMObject(context)
515 , m_bodyUsed(false) 508 , m_bodyUsed(false)
516 , m_responseType(ResponseType::ResponseUnknown) 509 , m_responseType(ResponseType::ResponseUnknown)
517 , m_streamSource(new ReadableStreamSource(context)) 510 , m_streamSource(new ReadableStreamSource(context))
518 , m_stream(new ReadableByteStream(m_streamSource, new ReadableByteStream::St rictStrategy)) 511 , m_stream(new ReadableByteStream(m_streamSource, new ReadableByteStream::St rictStrategy))
519 { 512 {
520 m_streamSource->startStream(m_stream); 513 m_streamSource->startStream(m_stream);
521 } 514 }
522 515
523 void Body::resolveJSON(const String& string) 516 void Body::resolveJSON(const String& string)
524 { 517 {
525 ASSERT(m_responseType == ResponseAsJSON); 518 ASSERT(m_responseType == ResponseAsJSON);
526 ScriptState::Scope scope(m_resolver->scriptState()); 519 ScriptState::Scope scope(m_resolver->scriptState());
527 v8::Isolate* isolate = m_resolver->scriptState()->isolate(); 520 v8::Isolate* isolate = m_resolver->scriptState()->isolate();
528 v8::Local<v8::String> inputString = v8String(isolate, string); 521 v8::Local<v8::String> inputString = v8String(isolate, string);
529 v8::TryCatch trycatch; 522 v8::TryCatch trycatch;
530 v8::Local<v8::Value> parsed; 523 v8::Local<v8::Value> parsed;
531 if (v8Call(v8::JSON::Parse(isolate, inputString), parsed, trycatch)) 524 if (v8Call(v8::JSON::Parse(isolate, inputString), parsed, trycatch))
532 m_resolver->resolve(parsed); 525 m_resolver->resolve(parsed);
533 else 526 else
534 m_resolver->reject(trycatch.Exception()); 527 m_resolver->reject(trycatch.Exception());
535 } 528 }
536 529
537 // FileReaderLoaderClient functions. 530 // FetchDataLoader::Client functions.
538 void Body::didStartLoading() { } 531 void Body::didFetchDataLoadFailed()
539 void Body::didReceiveData() { }
540 void Body::didFinishLoading()
541 { 532 {
542 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) 533 ASSERT(m_fetchDataLoader);
543 return; 534 m_fetchDataLoader.clear();
544 535
545 switch (m_responseType) {
546 case ResponseAsArrayBuffer:
547 m_resolver->resolve(m_loader->arrayBufferResult());
548 break;
549 case ResponseAsBlob: {
550 ASSERT(blobDataHandle()->size() == kuint64max);
551 OwnPtr<BlobData> blobData = BlobData::create();
552 RefPtr<DOMArrayBuffer> buffer = m_loader->arrayBufferResult();
553 blobData->appendBytes(buffer->data(), buffer->byteLength());
554 blobData->setContentType(mimeType());
555 const size_t length = blobData->length();
556 m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release (), length)));
557 break;
558 }
559 case ResponseAsFormData:
560 ASSERT_NOT_REACHED();
561 break;
562 case ResponseAsJSON:
563 resolveJSON(m_loader->stringResult());
564 break;
565 case ResponseAsText:
566 m_resolver->resolve(m_loader->stringResult());
567 break;
568 default:
569 ASSERT_NOT_REACHED();
570 }
571 m_streamSource->close();
572 m_resolver.clear();
573 }
574
575 void Body::didFail(FileError::ErrorCode code)
576 {
577 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) 536 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
578 return; 537 return;
579 538
580 m_streamSource->error(); 539 m_streamSource->error();
581 if (m_resolver) { 540 if (m_resolver) {
582 // FIXME: We should reject the promise. 541 if (!m_resolver->executionContext() || m_resolver->executionContext()->a ctiveDOMObjectsAreStopped()) {
583 m_resolver->resolve(""); 542 m_resolver.clear();
543 return;
544 }
545 ScriptState* state = m_resolver->scriptState();
546 ScriptState::Scope scope(state);
547 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), " Failed to fetch"));
584 m_resolver.clear(); 548 m_resolver.clear();
585 } 549 }
586 } 550 }
587 551
552 void Body::didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandl e)
553 {
554 ASSERT(m_fetchDataLoader);
555 m_fetchDataLoader.clear();
556
557 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
558 return;
559
560 ASSERT(m_responseType == ResponseAsBlob);
561 m_resolver->resolve(Blob::create(blobDataHandle));
562 m_streamSource->close();
563 m_resolver.clear();
564 }
565
566 void Body::didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer)
567 {
568 ASSERT(m_fetchDataLoader);
569 m_fetchDataLoader.clear();
570
571 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
572 return;
573
574 ASSERT(m_responseType == ResponseAsArrayBuffer);
575 m_resolver->resolve(arrayBuffer);
576 m_streamSource->close();
577 m_resolver.clear();
578 }
579
580 void Body::didFetchDataLoadedString(const String& str)
581 {
582 ASSERT(m_fetchDataLoader);
583 m_fetchDataLoader.clear();
584
585 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
586 return;
587
588 switch (m_responseType) {
589 case ResponseAsJSON:
590 resolveJSON(str);
591 break;
592 case ResponseAsText:
593 m_resolver->resolve(str);
594 break;
595 default:
596 ASSERT_NOT_REACHED();
597 }
598
599 m_streamSource->close();
600 m_resolver.clear();
601 }
602
588 void Body::didBlobHandleReceiveError(DOMException* exception) 603 void Body::didBlobHandleReceiveError(DOMException* exception)
589 { 604 {
590 if (!m_resolver) 605 if (!m_resolver)
591 return; 606 return;
592 m_streamSource->error(); 607 m_streamSource->error();
593 m_resolver->reject(exception); 608 m_resolver->reject(exception);
594 m_resolver.clear(); 609 m_resolver.clear();
595 } 610 }
596 611
597 } // namespace blink 612 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698