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

Unified Diff: Source/modules/serviceworkers/Body.cpp

Issue 795323003: Move Fetch API releted code to modules/fetch. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/modules/serviceworkers/Body.h ('k') | Source/modules/serviceworkers/Body.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « Source/modules/serviceworkers/Body.h ('k') | Source/modules/serviceworkers/Body.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698