Index: Source/modules/fetch/Body.cpp |
diff --git a/Source/modules/fetch/Body.cpp b/Source/modules/fetch/Body.cpp |
index f80644561fcbefd072de728387f62a7356355637..37a33350f94458f6b112c22eedea308dd485806b 100644 |
--- a/Source/modules/fetch/Body.cpp |
+++ b/Source/modules/fetch/Body.cpp |
@@ -273,19 +273,54 @@ ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type) |
if (!executionContext) |
return ScriptPromise(); |
- lockBody(PassBody); |
+ lockBody(); |
m_responseType = type; |
ASSERT(!m_resolver); |
m_resolver = ScriptPromiseResolver::create(scriptState); |
ScriptPromise promise = m_resolver->promise(); |
- if (streamAccessed()) { |
- m_streamSource->createDrainingStream()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver(this)); |
- } else if (buffer()) { |
- buffer()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver(this)); |
+ 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(); |
+ } else if (m_stream->stateInternal() == ReadableStream::Errored) { |
+ m_resolver->reject(m_stream->storedException()); |
+ m_resolver.clear(); |
} 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.
|
- readAsyncFromBlob(blobDataHandle()); |
+ if (isBodyConsumed()) { |
+ m_streamSource->createDrainingStream()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver(this)); |
+ } else if (buffer()) { |
+ buffer()->readAllAndCreateBlobHandle(mimeType(), new BlobHandleReceiver(this)); |
+ } else { |
+ readAsyncFromBlob(blobDataHandle()); |
+ } |
} |
return promise; |
} |
@@ -384,9 +419,22 @@ void Body::lockBody(LockBodyOption option) |
ASSERT(!exceptionState.hadException()); |
} |
-bool Body::streamAccessed() const |
+bool Body::isBodyConsumed() const |
{ |
- return m_streamSource->state() != m_streamSource->Initial; |
+ 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::refreshBody() |