| Index: Source/modules/serviceworkers/Body.cpp
|
| diff --git a/Source/modules/serviceworkers/Body.cpp b/Source/modules/serviceworkers/Body.cpp
|
| deleted file mode 100644
|
| index d85d09772d62d365ab0717c8934ed37f6d3bd1c0..0000000000000000000000000000000000000000
|
| --- a/Source/modules/serviceworkers/Body.cpp
|
| +++ /dev/null
|
| @@ -1,439 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "config.h"
|
| -#include "modules/serviceworkers/Body.h"
|
| -
|
| -#include "bindings/core/v8/ExceptionState.h"
|
| -#include "bindings/core/v8/ScriptPromiseResolver.h"
|
| -#include "bindings/core/v8/ScriptState.h"
|
| -#include "bindings/core/v8/V8ArrayBuffer.h"
|
| -#include "bindings/core/v8/V8ThrowException.h"
|
| -#include "core/dom/DOMArrayBuffer.h"
|
| -#include "core/fileapi/Blob.h"
|
| -#include "core/fileapi/FileReaderLoader.h"
|
| -#include "core/fileapi/FileReaderLoaderClient.h"
|
| -#include "core/streams/UnderlyingSource.h"
|
| -#include "modules/serviceworkers/BodyStreamBuffer.h"
|
| -
|
| -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(PassRefPtrWillBeRawPtr<DOMException> exception) override
|
| - {
|
| - ASSERT(m_body);
|
| - m_body->didBlobHandleReceiveError(exception);
|
| - m_body = nullptr;
|
| - }
|
| - void trace(Visitor* visitor) override
|
| - {
|
| - BodyStreamBuffer::BlobHandleCreatorClient::trace(visitor);
|
| - visitor->trace(m_body);
|
| - }
|
| -private:
|
| - Member<Body> m_body;
|
| -};
|
| -
|
| -class Body::ReadableStreamSource : public GarbageCollectedFinalized<ReadableStreamSource>, public UnderlyingSource {
|
| - USING_GARBAGE_COLLECTED_MIXIN(ReadableStreamSource);
|
| -public:
|
| - ReadableStreamSource(Body* body) : m_body(body) { }
|
| - ~ReadableStreamSource() override { }
|
| - void pullSource() override { m_body->pullSource(); }
|
| -
|
| - ScriptPromise cancelSource(ScriptState* scriptState, ScriptValue reason) override
|
| - {
|
| - return ScriptPromise();
|
| - }
|
| -
|
| - void trace(Visitor* visitor) override
|
| - {
|
| - visitor->trace(m_body);
|
| - UnderlyingSource::trace(visitor);
|
| - }
|
| -
|
| -private:
|
| - Member<Body> m_body;
|
| -};
|
| -
|
| -void Body::pullSource()
|
| -{
|
| - if (!m_streamAccessed) {
|
| - // We do not download data unless the user explicitly uses the
|
| - // ReadableStream object in order to avoid performance regression,
|
| - // because currently Chrome cannot handle Streams efficiently
|
| - // especially with ServiceWorker or Blob.
|
| - return;
|
| - }
|
| - if (m_bodyUsed) {
|
| - m_stream->error(DOMException::create(InvalidStateError, "The stream is locked."));
|
| - return;
|
| - }
|
| - ASSERT(!m_loader);
|
| - if (buffer()) {
|
| - // If the body has a body buffer, we read all data from the buffer and
|
| - // create a blob and then put the data from the blob to |m_stream|.
|
| - // FIXME: Put the data directry from the buffer.
|
| - buffer()->readAllAndCreateBlobHandle(contentTypeForBuffer(), new BlobHandleReceiver(this));
|
| - return;
|
| - }
|
| - RefPtr<BlobDataHandle> blobHandle = blobDataHandle();
|
| - if (!blobHandle.get()) {
|
| - blobHandle = BlobDataHandle::create(BlobData::create(), 0);
|
| - }
|
| - readAsyncFromBlob(blobHandle);
|
| -}
|
| -
|
| -ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type)
|
| -{
|
| - if (m_bodyUsed)
|
| - return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Already read"));
|
| -
|
| - // When the main thread sends a V8::TerminateExecution() signal to a worker
|
| - // thread, any V8 API on the worker thread starts returning an empty
|
| - // handle. This can happen in Body::readAsync. To avoid the situation, we
|
| - // first check the ExecutionContext and return immediately if it's already
|
| - // gone (which means that the V8::TerminateExecution() signal has been sent
|
| - // to this worker thread).
|
| - ExecutionContext* executionContext = scriptState->executionContext();
|
| - if (!executionContext)
|
| - return ScriptPromise();
|
| -
|
| - m_bodyUsed = true;
|
| - m_responseType = type;
|
| -
|
| - ASSERT(!m_resolver);
|
| - m_resolver = ScriptPromiseResolver::create(scriptState);
|
| - ScriptPromise promise = m_resolver->promise();
|
| -
|
| - if (m_streamAccessed) {
|
| - // 'body' attribute was accessed and the stream source started pulling.
|
| - switch (m_stream->state()) {
|
| - case ReadableStream::Readable:
|
| - readAllFromStream(scriptState);
|
| - return promise;
|
| - case ReadableStream::Waiting:
|
| - // m_loader is working and m_resolver will be resolved when it
|
| - // ends.
|
| - return promise;
|
| - case ReadableStream::Closed:
|
| - case ReadableStream::Errored:
|
| - m_resolver->resolve(m_stream->closed(scriptState).v8Value());
|
| - return promise;
|
| - break;
|
| - }
|
| - ASSERT_NOT_REACHED();
|
| - return promise;
|
| - }
|
| -
|
| - if (buffer()) {
|
| - buffer()->readAllAndCreateBlobHandle(contentTypeForBuffer(), new BlobHandleReceiver(this));
|
| - return promise;
|
| - }
|
| - readAsyncFromBlob(blobDataHandle());
|
| - return promise;
|
| -}
|
| -
|
| -void Body::readAsyncFromBlob(PassRefPtr<BlobDataHandle> handle)
|
| -{
|
| - if (m_streamAccessed) {
|
| - FileReaderLoader::ReadType readType = FileReaderLoader::ReadAsArrayBuffer;
|
| - m_loader = adoptPtr(new FileReaderLoader(readType, this));
|
| - m_loader->start(executionContext(), handle);
|
| - return;
|
| - }
|
| - FileReaderLoader::ReadType readType = FileReaderLoader::ReadAsText;
|
| - RefPtr<BlobDataHandle> blobHandle = handle;
|
| - if (!blobHandle.get()) {
|
| - blobHandle = BlobDataHandle::create(BlobData::create(), 0);
|
| - }
|
| - switch (m_responseType) {
|
| - case ResponseAsArrayBuffer:
|
| - readType = FileReaderLoader::ReadAsArrayBuffer;
|
| - break;
|
| - case ResponseAsBlob:
|
| - if (blobHandle->size() != kuint64max) {
|
| - // If the size of |blobHandle| is set correctly, creates Blob from
|
| - // it.
|
| - m_resolver->resolve(Blob::create(blobHandle));
|
| - m_resolver.clear();
|
| - return;
|
| - }
|
| - // If the size is not set, read as ArrayBuffer and create a new blob to
|
| - // get the size.
|
| - // FIXME: This workaround is not good for performance.
|
| - // When we will stop using Blob as a base system of Body to support
|
| - // stream, this problem should be solved.
|
| - readType = FileReaderLoader::ReadAsArrayBuffer;
|
| - break;
|
| - case ResponseAsFormData:
|
| - // FIXME: Implement this.
|
| - ASSERT_NOT_REACHED();
|
| - break;
|
| - case ResponseAsJSON:
|
| - case ResponseAsText:
|
| - break;
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - }
|
| -
|
| - m_loader = adoptPtr(new FileReaderLoader(readType, this));
|
| - m_loader->start(m_resolver->scriptState()->executionContext(), blobHandle);
|
| -
|
| - return;
|
| -}
|
| -
|
| -void Body::readAllFromStream(ScriptState* scriptState)
|
| -{
|
| - // With the current loading mechanism, the data is loaded atomically.
|
| - ASSERT(m_stream->isDraining());
|
| - TrackExceptionState es;
|
| - // FIXME: Implement and use another |read| method that doesn't
|
| - // need an exception state and V8ArrayBuffer.
|
| - ScriptValue value = m_stream->read(scriptState, es);
|
| - ASSERT(!es.hadException());
|
| - ASSERT(m_stream->state() == ReadableStream::Closed);
|
| - ASSERT(!value.isEmpty() && V8ArrayBuffer::hasInstance(value.v8Value(), scriptState->isolate()));
|
| - DOMArrayBuffer* buffer = V8ArrayBuffer::toImpl(value.v8Value().As<v8::Object>());
|
| - didFinishLoadingViaStream(buffer);
|
| - m_resolver.clear();
|
| - m_stream->close();
|
| -}
|
| -
|
| -ScriptPromise Body::arrayBuffer(ScriptState* scriptState)
|
| -{
|
| - return readAsync(scriptState, ResponseAsArrayBuffer);
|
| -}
|
| -
|
| -ScriptPromise Body::blob(ScriptState* scriptState)
|
| -{
|
| - return readAsync(scriptState, ResponseAsBlob);
|
| -}
|
| -
|
| -ScriptPromise Body::formData(ScriptState* scriptState)
|
| -{
|
| - return readAsync(scriptState, ResponseAsFormData);
|
| -}
|
| -
|
| -ScriptPromise Body::json(ScriptState* scriptState)
|
| -{
|
| - return readAsync(scriptState, ResponseAsJSON);
|
| -}
|
| -
|
| -ScriptPromise Body::text(ScriptState* scriptState)
|
| -{
|
| - return readAsync(scriptState, ResponseAsText);
|
| -}
|
| -
|
| -ReadableStream* Body::body()
|
| -{
|
| - if (!m_streamAccessed) {
|
| - m_streamAccessed = true;
|
| - if (m_stream->isPulling()) {
|
| - // The stream has been pulling, but the source ignored the
|
| - // instruction because it didn't know the user wanted to use the
|
| - // ReadableStream interface. Now it knows the user does, so have
|
| - // the source start pulling.
|
| - m_streamSource->pullSource();
|
| - }
|
| - }
|
| - return m_stream;
|
| -}
|
| -
|
| -bool Body::bodyUsed() const
|
| -{
|
| - return m_bodyUsed;
|
| -}
|
| -
|
| -void Body::setBodyUsed()
|
| -{
|
| - m_bodyUsed = true;
|
| -}
|
| -
|
| -bool Body::streamAccessed() const
|
| -{
|
| - return m_streamAccessed;
|
| -}
|
| -
|
| -void Body::stop()
|
| -{
|
| - // Canceling the load will call didFail which will remove the resolver.
|
| - if (m_loader)
|
| - m_loader->cancel();
|
| -}
|
| -
|
| -bool Body::hasPendingActivity() const
|
| -{
|
| - if (m_resolver)
|
| - return true;
|
| - if (m_streamAccessed && (m_stream->state() == ReadableStream::Readable || m_stream->state() == ReadableStream::Waiting))
|
| - return true;
|
| - return false;
|
| -}
|
| -
|
| -void Body::trace(Visitor* visitor)
|
| -{
|
| - visitor->trace(m_stream);
|
| - visitor->trace(m_streamSource);
|
| -}
|
| -
|
| -Body::Body(ExecutionContext* context)
|
| - : ActiveDOMObject(context)
|
| - , m_bodyUsed(false)
|
| - , m_streamAccessed(false)
|
| - , m_responseType(ResponseType::ResponseUnknown)
|
| - , m_streamSource(new ReadableStreamSource(this))
|
| - , m_stream(new ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArrayBuffer>>(context, m_streamSource))
|
| -{
|
| - m_stream->didSourceStart();
|
| -}
|
| -
|
| -Body::Body(const Body& copy_from)
|
| - : ActiveDOMObject(copy_from.lifecycleContext())
|
| - , m_bodyUsed(copy_from.bodyUsed())
|
| - , m_responseType(ResponseType::ResponseUnknown)
|
| - , m_streamSource(new ReadableStreamSource(this))
|
| - , m_stream(new ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArrayBuffer>>(copy_from.executionContext(), m_streamSource))
|
| -{
|
| - m_stream->didSourceStart();
|
| -}
|
| -
|
| -void Body::resolveJSON(const String& string)
|
| -{
|
| - ASSERT(m_responseType == ResponseAsJSON);
|
| - ScriptState::Scope scope(m_resolver->scriptState());
|
| - v8::Isolate* isolate = m_resolver->scriptState()->isolate();
|
| - v8::Local<v8::String> inputString = v8String(isolate, string);
|
| - v8::TryCatch trycatch;
|
| - v8::Local<v8::Value> parsed = v8::JSON::Parse(inputString);
|
| - if (parsed.IsEmpty()) {
|
| - if (trycatch.HasCaught())
|
| - m_resolver->reject(trycatch.Exception());
|
| - else
|
| - m_resolver->reject(v8::Exception::Error(v8::String::NewFromUtf8(isolate, "JSON parse error")));
|
| - return;
|
| - }
|
| - m_resolver->resolve(parsed);
|
| -}
|
| -
|
| -// FileReaderLoaderClient functions.
|
| -void Body::didStartLoading() { }
|
| -void Body::didReceiveData() { }
|
| -void Body::didFinishLoading()
|
| -{
|
| - if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| -
|
| - if (m_streamAccessed) {
|
| - didFinishLoadingViaStream(m_loader->arrayBufferResult().get());
|
| - m_resolver.clear();
|
| - m_stream->close();
|
| - return;
|
| - }
|
| -
|
| - switch (m_responseType) {
|
| - case ResponseAsArrayBuffer:
|
| - m_resolver->resolve(m_loader->arrayBufferResult());
|
| - break;
|
| - case ResponseAsBlob: {
|
| - ASSERT(blobDataHandle()->size() == kuint64max);
|
| - OwnPtr<BlobData> blobData = BlobData::create();
|
| - RefPtr<DOMArrayBuffer> buffer = m_loader->arrayBufferResult();
|
| - blobData->appendBytes(buffer->data(), buffer->byteLength());
|
| - const size_t length = blobData->length();
|
| - m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release(), length)));
|
| - break;
|
| - }
|
| - case ResponseAsFormData:
|
| - ASSERT_NOT_REACHED();
|
| - break;
|
| - case ResponseAsJSON:
|
| - resolveJSON(m_loader->stringResult());
|
| - break;
|
| - case ResponseAsText:
|
| - m_resolver->resolve(m_loader->stringResult());
|
| - break;
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - }
|
| - m_resolver.clear();
|
| - m_stream->close();
|
| -}
|
| -
|
| -void Body::didFinishLoadingViaStream(DOMArrayBuffer* buffer)
|
| -{
|
| - if (!m_bodyUsed) {
|
| - // |m_stream| is pulling.
|
| - ASSERT(m_streamAccessed);
|
| - m_stream->enqueue(buffer);
|
| - return;
|
| - }
|
| -
|
| - switch (m_responseType) {
|
| - case ResponseAsArrayBuffer:
|
| - m_resolver->resolve(buffer);
|
| - break;
|
| - case ResponseAsBlob: {
|
| - OwnPtr<BlobData> blobData = BlobData::create();
|
| - blobData->appendBytes(buffer->data(), buffer->byteLength());
|
| - m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release(), blobData->length())));
|
| - break;
|
| - }
|
| - case ResponseAsFormData:
|
| - ASSERT_NOT_REACHED();
|
| - break;
|
| - case ResponseAsJSON: {
|
| - String s = String::fromUTF8(static_cast<const char*>(buffer->data()), buffer->byteLength());
|
| - if (s.isNull())
|
| - m_resolver->reject(DOMException::create(NetworkError, "Invalid utf-8 string"));
|
| - else
|
| - resolveJSON(s);
|
| - break;
|
| - }
|
| - case ResponseAsText: {
|
| - String s = String::fromUTF8(static_cast<const char*>(buffer->data()), buffer->byteLength());
|
| - if (s.isNull())
|
| - m_resolver->reject(DOMException::create(NetworkError, "Invalid utf-8 string"));
|
| - else
|
| - m_resolver->resolve(s);
|
| - break;
|
| - }
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - }
|
| -}
|
| -
|
| -void Body::didFail(FileError::ErrorCode code)
|
| -{
|
| - if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
|
| - return;
|
| -
|
| - if (m_resolver) {
|
| - // FIXME: We should reject the promise.
|
| - m_resolver->resolve("");
|
| - m_resolver.clear();
|
| - }
|
| - m_stream->error(DOMException::create(NetworkError, "network error"));
|
| -}
|
| -
|
| -void Body::didBlobHandleReceiveError(PassRefPtrWillBeRawPtr<DOMException> exception)
|
| -{
|
| - if (!m_resolver)
|
| - return;
|
| - m_resolver->reject(exception);
|
| - m_resolver.clear();
|
| -}
|
| -
|
| -} // namespace blink
|
|
|