Index: Source/modules/fetch/Body.cpp |
diff --git a/Source/modules/fetch/Body.cpp b/Source/modules/fetch/Body.cpp |
index bb1b547738f4e56448dabf06f924c1361674af1f..b764e88602be84c6c472915698be67d1eec0784f 100644 |
--- a/Source/modules/fetch/Body.cpp |
+++ b/Source/modules/fetch/Body.cpp |
@@ -12,9 +12,8 @@ |
#include "bindings/core/v8/V8ThrowException.h" |
#include "core/dom/DOMArrayBuffer.h" |
#include "core/dom/DOMTypedArray.h" |
+#include "core/dom/ExceptionCode.h" |
#include "core/fileapi/Blob.h" |
-#include "core/fileapi/FileReaderLoader.h" |
-#include "core/fileapi/FileReaderLoaderClient.h" |
#include "core/frame/UseCounter.h" |
#include "core/streams/ReadableByteStream.h" |
#include "core/streams/ReadableByteStreamReader.h" |
@@ -25,265 +24,178 @@ |
namespace blink { |
-class Body::BlobHandleReceiver final : public BodyStreamBuffer::BlobHandleCreatorClient { |
-public: |
- explicit BlobHandleReceiver(Body* body) |
- : m_body(body) |
- { |
- } |
- void didCreateBlobHandle(PassRefPtr<BlobDataHandle> handle) override |
- { |
- ASSERT(m_body); |
- m_body->readAsyncFromBlob(handle); |
- m_body = nullptr; |
- } |
- void didFail(DOMException* exception) override |
- { |
- ASSERT(m_body); |
- m_body->didBlobHandleReceiveError(exception); |
- m_body = nullptr; |
- } |
- DEFINE_INLINE_VIRTUAL_TRACE() |
- { |
- BodyStreamBuffer::BlobHandleCreatorClient::trace(visitor); |
- visitor->trace(m_body); |
- } |
-private: |
- Member<Body> m_body; |
-}; |
- |
-// This class is an ActiveDOMObject subclass only for holding the |
-// ExecutionContext used in |pullSource|. |
-class Body::ReadableStreamSource : public BodyStreamBuffer::Observer, public UnderlyingSource, public FileReaderLoaderClient, public ActiveDOMObject { |
+class Body::ReadableStreamSource : public GarbageCollectedFinalized<Body::ReadableStreamSource>, public UnderlyingSource, public WebDataConsumerHandle::Client, public BodyStreamBuffer::DrainingStreamNotificationClient { |
USING_GARBAGE_COLLECTED_MIXIN(ReadableStreamSource); |
public: |
- enum State { |
- Initial, |
- Streaming, |
- Closed, |
- Errored, |
- }; |
- ReadableStreamSource(ExecutionContext* executionContext, PassRefPtr<BlobDataHandle> handle) |
- : ActiveDOMObject(executionContext) |
- , m_blobDataHandle(handle ? handle : BlobDataHandle::create(BlobData::create(), 0)) |
- , m_state(Initial) |
- { |
- suspendIfNeeded(); |
- } |
- |
ReadableStreamSource(ExecutionContext* executionContext, BodyStreamBuffer* buffer) |
- : ActiveDOMObject(executionContext) |
- , m_bodyStreamBuffer(buffer) |
- , m_state(Initial) |
+ : m_bodyStreamBuffer(buffer) |
+ , m_streamNeedsMore(false) |
+#if ENABLE(ASSERT) |
+ , m_drained(false) |
+ , m_isCloseCalled(false) |
+ , m_isErrorCalled(false) |
+#endif |
{ |
- suspendIfNeeded(); |
- } |
- |
- explicit ReadableStreamSource(ExecutionContext* executionContext) |
- : ActiveDOMObject(executionContext) |
- , m_blobDataHandle(BlobDataHandle::create(BlobData::create(), 0)) |
- , m_state(Initial) |
- { |
- suspendIfNeeded(); |
+ if (m_bodyStreamBuffer) |
+ obtainReader(); |
} |
~ReadableStreamSource() override { } |
- State state() const { return m_state; } |
- |
void startStream(ReadableByteStream* stream) |
{ |
m_stream = stream; |
stream->didSourceStart(); |
} |
// Creates a new BodyStreamBuffer to drain the data. |
- BodyStreamBuffer* createDrainingStream() |
+ PassOwnPtr<DrainingBodyStreamBuffer> createDrainingStream() |
{ |
- ASSERT(m_state != Initial); |
+ if (!m_bodyStreamBuffer) |
+ return nullptr; |
- auto drainingStreamBuffer = new BodyStreamBuffer(new Canceller(this)); |
- if (m_stream->stateInternal() == ReadableByteStream::Closed) { |
- drainingStreamBuffer->close(); |
- return drainingStreamBuffer; |
- } |
- if (m_stream->stateInternal() == ReadableByteStream::Errored) { |
- drainingStreamBuffer->error(exception()); |
- return drainingStreamBuffer; |
- } |
+#if ENABLE(ASSERT) |
+ ASSERT(!m_drained); |
+ m_drained = true; |
+ ASSERT(!(m_stream->stateInternal() == ReadableByteStream::Closed && !m_isCloseCalled)); |
+ ASSERT(!(m_stream->stateInternal() == ReadableByteStream::Errored && !m_isErrorCalled)); |
+#endif |
- ASSERT(!m_drainingStreamBuffer); |
- // Take back the data in |m_stream|. |
- Deque<std::pair<RefPtr<DOMArrayBufferView>, size_t>> tmp_queue; |
- ASSERT(m_stream->stateInternal() == ReadableStream::Readable); |
- m_stream->readInternal(tmp_queue); |
- while (!tmp_queue.isEmpty()) { |
- std::pair<RefPtr<DOMArrayBufferView>, size_t> data = tmp_queue.takeFirst(); |
- drainingStreamBuffer->write(data.first->buffer()); |
- } |
- if (m_state == Closed) |
- drainingStreamBuffer->close(); |
- |
- m_drainingStreamBuffer = drainingStreamBuffer; |
- return m_drainingStreamBuffer; |
+ m_reader.clear(); |
+ return DrainingBodyStreamBuffer::create(m_bodyStreamBuffer, this); |
} |
+ |
DEFINE_INLINE_VIRTUAL_TRACE() |
{ |
visitor->trace(m_bodyStreamBuffer); |
- visitor->trace(m_drainingStreamBuffer); |
visitor->trace(m_stream); |
- BodyStreamBuffer::Observer::trace(visitor); |
UnderlyingSource::trace(visitor); |
- ActiveDOMObject::trace(visitor); |
+ DrainingStreamNotificationClient::trace(visitor); |
} |
void close() |
{ |
- if (m_state == Closed) { |
- // It is possible to call |close| from the source side (such |
- // as blob loading finish) and from the consumer side (such as |
- // calling |cancel|). Thus we should ignore it here. |
- return; |
- } |
- m_state = Closed; |
- if (m_drainingStreamBuffer) |
- m_drainingStreamBuffer->close(); |
+ m_reader.clear(); |
m_stream->close(); |
+ m_bodyStreamBuffer = BodyStreamBuffer::createEmpty(); |
+#if ENABLE(ASSERT) |
+ m_isCloseCalled = true; |
+#endif |
} |
+ |
void error() |
{ |
- m_state = Errored; |
- if (m_drainingStreamBuffer) |
- m_drainingStreamBuffer->error(exception()); |
- m_stream->error(exception()); |
+ m_reader.clear(); |
+ m_stream->error(DOMException::create(NetworkError, "network error")); |
+ m_bodyStreamBuffer = BodyStreamBuffer::create(createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle())); |
+#if ENABLE(ASSERT) |
+ m_isErrorCalled = true; |
+#endif |
} |
private: |
- class Canceller : public BodyStreamBuffer::Canceller { |
- public: |
- Canceller(ReadableStreamSource* source) : m_source(source) { } |
- void cancel() override |
- { |
- m_source->cancel(); |
- } |
- |
- DEFINE_INLINE_VIRTUAL_TRACE() |
- { |
- visitor->trace(m_source); |
- BodyStreamBuffer::Canceller::trace(visitor); |
- } |
- |
- private: |
- Member<ReadableStreamSource> m_source; |
- }; |
- |
- // UnderlyingSource functions. |
- void pullSource() override |
+ void obtainReader() |
{ |
- // Note that one |pull| is called only when |read| is called on the |
- // associated ReadableByteStreamReader because we create a stream with |
- // StrictStrategy. |
- if (m_state == Initial) { |
- m_state = Streaming; |
- if (m_bodyStreamBuffer) { |
- m_bodyStreamBuffer->registerObserver(this); |
- onWrite(); |
- if (m_bodyStreamBuffer->hasError()) |
- return onError(); |
- if (m_bodyStreamBuffer->isClosed()) |
- return onClose(); |
- } else { |
- FileReaderLoader::ReadType readType = FileReaderLoader::ReadAsArrayBuffer; |
- m_loader = FileReaderLoader::create(readType, this); |
- m_loader->start(executionContext(), m_blobDataHandle); |
- } |
- } |
+ m_reader = m_bodyStreamBuffer->handle()->obtainReader(this); |
} |
- ScriptPromise cancelSource(ScriptState* scriptState, ScriptValue reason) override |
+ void didFetchDataLoadFinishedFromDrainingStream() |
{ |
- cancel(); |
- return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
+ ASSERT(m_bodyStreamBuffer); |
+ ASSERT(m_drained); |
+ |
+#if ENABLE(ASSERT) |
+ m_drained = false; |
+#endif |
+ obtainReader(); |
+ // We have to call didGetReadable() now to call close()/error() if |
+ // necessary. |
+ // didGetReadable() would be called asynchronously, but it is too late. |
+ didGetReadable(); |
} |
- // BodyStreamBuffer::Observer functions. |
- void onWrite() override |
+ void didGetReadable() override |
{ |
- ASSERT(m_state == Streaming); |
- while (RefPtr<DOMArrayBuffer> buf = m_bodyStreamBuffer->read()) { |
- write(buf); |
+ if (!m_streamNeedsMore) { |
+ // Perform zero-length read to call close()/error() early. |
+ size_t readSize; |
+ WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDataConsumerHandle::FlagNone, &readSize); |
+ switch (result) { |
+ case WebDataConsumerHandle::Ok: |
+ case WebDataConsumerHandle::ShouldWait: |
+ return; |
+ case WebDataConsumerHandle::Done: |
+ close(); |
+ return; |
+ case WebDataConsumerHandle::Busy: |
+ case WebDataConsumerHandle::ResourceExhausted: |
+ case WebDataConsumerHandle::UnexpectedError: |
+ error(); |
+ return; |
+ } |
} |
- } |
- void onClose() override |
- { |
- ASSERT(m_state == Streaming); |
- close(); |
- m_bodyStreamBuffer->unregisterObserver(); |
- } |
- void onError() override |
- { |
- ASSERT(m_state == Streaming); |
- error(); |
- m_bodyStreamBuffer->unregisterObserver(); |
- } |
- // FileReaderLoaderClient functions. |
- void didStartLoading() override { } |
- void didReceiveData() override { } |
- void didFinishLoading() override |
- { |
- ASSERT(m_state == Streaming); |
- write(m_loader->arrayBufferResult()); |
- close(); |
- } |
- void didFail(FileError::ErrorCode) override |
- { |
- ASSERT(m_state == Streaming); |
- error(); |
+ processData(); |
} |
- void write(PassRefPtr<DOMArrayBuffer> buf) |
+ // UnderlyingSource functions. |
+ void pullSource() override |
{ |
- if (m_drainingStreamBuffer) { |
- m_drainingStreamBuffer->write(buf); |
- } else { |
- auto size = buf->byteLength(); |
- m_stream->enqueue(DOMUint8Array::create(buf, 0, size)); |
- } |
+ ASSERT(!m_streamNeedsMore); |
+ m_streamNeedsMore = true; |
+ |
+ ASSERT(!m_drained); |
+ |
+ processData(); |
} |
- void cancel() |
+ |
+ ScriptPromise cancelSource(ScriptState* scriptState, ScriptValue reason) override |
{ |
- if (m_bodyStreamBuffer) { |
- m_bodyStreamBuffer->cancel(); |
- // We should not close the stream here, because it is canceller's |
- // responsibility. |
- } else { |
- if (m_loader) |
- m_loader->cancel(); |
- close(); |
- } |
+ close(); |
+ return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); |
} |
- DOMException* exception() |
+ // Reads data and writes the data to |m_stream|, as long as data are |
+ // available and the stream has pending reads. |
+ void processData() |
{ |
- if (m_state != Errored) |
- return nullptr; |
- if (m_bodyStreamBuffer) { |
- ASSERT(m_bodyStreamBuffer->exception()); |
- return m_bodyStreamBuffer->exception(); |
+ ASSERT(m_reader); |
+ while (m_streamNeedsMore) { |
+ const void* buffer; |
+ size_t available; |
+ WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); |
+ switch (result) { |
+ case WebDataConsumerHandle::Ok: |
+ m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(static_cast<const unsigned char*>(buffer), available)); |
+ m_reader->endRead(available); |
+ break; |
+ |
+ case WebDataConsumerHandle::Done: |
+ close(); |
+ return; |
+ |
+ case WebDataConsumerHandle::ShouldWait: |
+ return; |
+ |
+ case WebDataConsumerHandle::Busy: |
+ case WebDataConsumerHandle::ResourceExhausted: |
+ case WebDataConsumerHandle::UnexpectedError: |
+ error(); |
+ return; |
+ } |
} |
- return DOMException::create(NetworkError, "network error"); |
} |
- // Set when the data container of the Body is a BodyStreamBuffer. |
+ // Source of data. |
Member<BodyStreamBuffer> m_bodyStreamBuffer; |
- // Set when the data container of the Body is a BlobDataHandle. |
- RefPtr<BlobDataHandle> m_blobDataHandle; |
- // Used to read the data from BlobDataHandle. |
- OwnPtr<FileReaderLoader> m_loader; |
- // Created when createDrainingStream is called to drain the data. |
- Member<BodyStreamBuffer> m_drainingStreamBuffer; |
+ OwnPtr<FetchDataConsumerHandle::Reader> m_reader; |
+ |
Member<ReadableByteStream> m_stream; |
- State m_state; |
+ bool m_streamNeedsMore; |
+#if ENABLE(ASSERT) |
+ bool m_drained; |
+ bool m_isCloseCalled; |
+ bool m_isErrorCalled; |
+#endif |
}; |
ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type) |
@@ -309,64 +221,71 @@ ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type) |
ScriptPromise promise = m_resolver->promise(); |
if (m_stream->stateInternal() == ReadableStream::Closed) { |
- // We resolve the resolver manually in order not to use member |
- // variables. |
- switch (m_responseType) { |
- case ResponseAsArrayBuffer: |
- m_resolver->resolve(DOMArrayBuffer::create(nullptr, 0)); |
- break; |
- case ResponseAsBlob: { |
- OwnPtr<BlobData> blobData = BlobData::create(); |
- blobData->setContentType(mimeType()); |
- m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release(), 0))); |
- break; |
- } |
- case ResponseAsText: |
- m_resolver->resolve(String()); |
- break; |
- case ResponseAsFormData: |
- // TODO(yhirano): Implement this. |
- ASSERT_NOT_REACHED(); |
- break; |
- case ResponseAsJSON: { |
- ScriptState::Scope scope(m_resolver->scriptState()); |
- m_resolver->reject(V8ThrowException::createSyntaxError(m_resolver->scriptState()->isolate(), "Unexpected end of input")); |
- break; |
- } |
- case ResponseUnknown: |
- ASSERT_NOT_REACHED(); |
- break; |
- } |
- m_resolver.clear(); |
+ resolveWithEmptyDataSynchronously(); |
} else if (m_stream->stateInternal() == ReadableStream::Errored) { |
m_resolver->reject(m_stream->storedException()); |
m_resolver.clear(); |
- } else if (isBodyConsumed()) { |
- m_streamSource->createDrainingStream()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver(this)); |
- } else if (buffer()) { |
- buffer()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver(this)); |
} else { |
- readAsyncFromBlob(blobDataHandle()); |
+ readAsyncFromDrainingBodyStreamBuffer(createDrainingStream(), mimeType()); |
} |
return promise; |
} |
-void Body::readAsyncFromFetchDataConsumerHandle(FetchDataConsumerHandle* handle, const String& mimeType) |
+void Body::resolveWithEmptyDataSynchronously() |
{ |
- ASSERT(!m_fetchDataLoader); |
+ // We resolve the resolver manually in order not to use member |
+ // variables. |
+ switch (m_responseType) { |
+ case ResponseAsArrayBuffer: |
+ m_resolver->resolve(DOMArrayBuffer::create(nullptr, 0)); |
+ break; |
+ case ResponseAsBlob: { |
+ OwnPtr<BlobData> blobData = BlobData::create(); |
+ blobData->setContentType(mimeType()); |
+ m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release(), 0))); |
+ break; |
+ } |
+ case ResponseAsText: |
+ m_resolver->resolve(String()); |
+ break; |
+ case ResponseAsFormData: |
+ // TODO(yhirano): Implement this. |
+ ASSERT_NOT_REACHED(); |
+ break; |
+ case ResponseAsJSON: { |
+ ScriptState::Scope scope(m_resolver->scriptState()); |
+ m_resolver->reject(V8ThrowException::createSyntaxError(m_resolver->scriptState()->isolate(), "Unexpected end of input")); |
+ break; |
+ } |
+ case ResponseUnknown: |
+ ASSERT_NOT_REACHED(); |
+ break; |
+ } |
+ m_resolver.clear(); |
+} |
+ |
+void Body::readAsyncFromDrainingBodyStreamBuffer(PassOwnPtr<DrainingBodyStreamBuffer> buffer, const String& mimeType) |
+{ |
+ if (!buffer) { |
+ resolveWithEmptyDataSynchronously(); |
+ m_streamSource->close(); |
+ return; |
+ } |
+ |
+ FetchDataLoader* fetchDataLoader = nullptr; |
switch (m_responseType) { |
case ResponseAsArrayBuffer: |
- m_fetchDataLoader = FetchDataLoader::createLoaderAsArrayBuffer(); |
+ fetchDataLoader = FetchDataLoader::createLoaderAsArrayBuffer(); |
break; |
case ResponseAsJSON: |
case ResponseAsText: |
- m_fetchDataLoader = FetchDataLoader::createLoaderAsString(); |
+ fetchDataLoader = FetchDataLoader::createLoaderAsString(); |
break; |
case ResponseAsBlob: |
- m_fetchDataLoader = FetchDataLoader::createLoaderAsBlobHandle(mimeType); |
+ fetchDataLoader = FetchDataLoader::createLoaderAsBlobHandle(mimeType); |
break; |
case ResponseAsFormData: |
@@ -379,12 +298,7 @@ void Body::readAsyncFromFetchDataConsumerHandle(FetchDataConsumerHandle* handle, |
return; |
} |
- m_fetchDataLoader->start(handle, this); |
-} |
- |
-void Body::readAsyncFromBlob(PassRefPtr<BlobDataHandle> handle) |
-{ |
- readAsyncFromFetchDataConsumerHandle(FetchBlobDataConsumerHandle::create(executionContext(), handle).get(), mimeType()); |
+ buffer->startLoading(fetchDataLoader, this); |
} |
ScriptPromise Body::arrayBuffer(ScriptState* scriptState) |
@@ -434,44 +348,18 @@ void Body::lockBody(LockBodyOption option) |
ASSERT(!exceptionState.hadException()); |
} |
-bool Body::isBodyConsumed() const |
+void Body::setBody(BodyStreamBuffer* buffer) |
{ |
- if (m_streamSource->state() != m_streamSource->Initial) { |
- // Some data is pulled from the source. |
- return true; |
- } |
- if (m_stream->stateInternal() == ReadableStream::Closed) { |
- // Return true if the blob handle is originally not empty. |
- RefPtr<BlobDataHandle> handle = blobDataHandle(); |
- return handle && handle->size(); |
- } |
- if (m_stream->stateInternal() == ReadableStream::Errored) { |
- // The stream is errored. That means an effort to read data was made. |
- return true; |
- } |
- return false; |
-} |
- |
-void Body::setBody(ReadableStreamSource* source) |
-{ |
- m_streamSource = source; |
+ m_streamSource = new ReadableStreamSource(executionContext(), buffer); |
m_stream = new ReadableByteStream(m_streamSource, new ReadableByteStream::StrictStrategy); |
m_streamSource->startStream(m_stream); |
} |
-BodyStreamBuffer* Body::createDrainingStream() |
+PassOwnPtr<DrainingBodyStreamBuffer> Body::createDrainingStream() |
{ |
return m_streamSource->createDrainingStream(); |
} |
-void Body::stop() |
-{ |
- if (m_fetchDataLoader) { |
- m_fetchDataLoader->cancel(); |
- m_fetchDataLoader.clear(); |
- } |
-} |
- |
bool Body::hasPendingActivity() const |
{ |
if (executionContext()->activeDOMObjectsAreStopped()) |
@@ -483,19 +371,8 @@ bool Body::hasPendingActivity() const |
return false; |
} |
-Body::ReadableStreamSource* Body::createBodySource(PassRefPtr<BlobDataHandle> handle) |
-{ |
- return new ReadableStreamSource(executionContext(), handle); |
-} |
- |
-Body::ReadableStreamSource* Body::createBodySource(BodyStreamBuffer* buffer) |
-{ |
- return new ReadableStreamSource(executionContext(), buffer); |
-} |
- |
DEFINE_TRACE(Body) |
{ |
- visitor->trace(m_fetchDataLoader); |
visitor->trace(m_resolver); |
visitor->trace(m_stream); |
visitor->trace(m_streamSource); |
@@ -507,7 +384,7 @@ Body::Body(ExecutionContext* context) |
: ActiveDOMObject(context) |
, m_bodyUsed(false) |
, m_responseType(ResponseType::ResponseUnknown) |
- , m_streamSource(new ReadableStreamSource(context)) |
+ , m_streamSource(new ReadableStreamSource(context, nullptr)) |
, m_stream(new ReadableByteStream(m_streamSource, new ReadableByteStream::StrictStrategy)) |
{ |
m_streamSource->startStream(m_stream); |
@@ -530,13 +407,9 @@ void Body::resolveJSON(const String& string) |
// FetchDataLoader::Client functions. |
void Body::didFetchDataLoadFailed() |
{ |
- ASSERT(m_fetchDataLoader); |
- m_fetchDataLoader.clear(); |
- |
if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) |
return; |
- m_streamSource->error(); |
if (m_resolver) { |
if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped()) { |
m_resolver.clear(); |
@@ -551,37 +424,26 @@ void Body::didFetchDataLoadFailed() |
void Body::didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) |
{ |
- ASSERT(m_fetchDataLoader); |
- m_fetchDataLoader.clear(); |
- |
if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) |
return; |
ASSERT(m_responseType == ResponseAsBlob); |
m_resolver->resolve(Blob::create(blobDataHandle)); |
- m_streamSource->close(); |
m_resolver.clear(); |
} |
void Body::didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) |
{ |
- ASSERT(m_fetchDataLoader); |
- m_fetchDataLoader.clear(); |
- |
if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) |
return; |
ASSERT(m_responseType == ResponseAsArrayBuffer); |
m_resolver->resolve(arrayBuffer); |
- m_streamSource->close(); |
m_resolver.clear(); |
} |
void Body::didFetchDataLoadedString(const String& str) |
{ |
- ASSERT(m_fetchDataLoader); |
- m_fetchDataLoader.clear(); |
- |
if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) |
return; |
@@ -596,16 +458,6 @@ void Body::didFetchDataLoadedString(const String& str) |
ASSERT_NOT_REACHED(); |
} |
- m_streamSource->close(); |
- m_resolver.clear(); |
-} |
- |
-void Body::didBlobHandleReceiveError(DOMException* exception) |
-{ |
- if (!m_resolver) |
- return; |
- m_streamSource->error(); |
- m_resolver->reject(exception); |
m_resolver.clear(); |
} |