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

Unified Diff: Source/modules/serviceworkers/FetchManager.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/FetchManager.h ('k') | Source/modules/serviceworkers/FetchRequestData.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/serviceworkers/FetchManager.cpp
diff --git a/Source/modules/serviceworkers/FetchManager.cpp b/Source/modules/serviceworkers/FetchManager.cpp
deleted file mode 100644
index 42d7ab5b54a9c169c422a8aac818cea8313958a3..0000000000000000000000000000000000000000
--- a/Source/modules/serviceworkers/FetchManager.cpp
+++ /dev/null
@@ -1,386 +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 "FetchManager.h"
-
-#include "bindings/core/v8/ExceptionState.h"
-#include "bindings/core/v8/ScriptPromiseResolver.h"
-#include "bindings/core/v8/ScriptState.h"
-#include "bindings/core/v8/V8ThrowException.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/fetch/FetchUtils.h"
-#include "core/fileapi/Blob.h"
-#include "core/frame/csp/ContentSecurityPolicy.h"
-#include "core/loader/ThreadableLoader.h"
-#include "core/loader/ThreadableLoaderClient.h"
-#include "modules/serviceworkers/Body.h"
-#include "modules/serviceworkers/BodyStreamBuffer.h"
-#include "modules/serviceworkers/FetchRequestData.h"
-#include "modules/serviceworkers/Response.h"
-#include "modules/serviceworkers/ResponseInit.h"
-#include "platform/network/ResourceRequest.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "public/platform/WebURLRequest.h"
-#include "wtf/HashSet.h"
-
-namespace blink {
-
-class FetchManager::Loader : public ThreadableLoaderClient {
-public:
- Loader(ExecutionContext*, FetchManager*, PassRefPtr<ScriptPromiseResolver>, const FetchRequestData*);
- ~Loader() override;
- void didReceiveResponse(unsigned long, const ResourceResponse&, PassOwnPtr<WebDataConsumerHandle>) override;
- void didReceiveData(const char*, unsigned) override;
- void didFinishLoading(unsigned long, double) override;
- void didFail(const ResourceError&) override;
- void didFailAccessControlCheck(const ResourceError&) override;
- void didFailRedirectCheck() override;
-
- void start();
- void cleanup();
-
-private:
- void performBasicFetch();
- void performNetworkError(const String& message);
- void performHTTPFetch();
- void failed(const String& message);
- void notifyFinished();
-
- ExecutionContext* m_executionContext;
- FetchManager* m_fetchManager;
- RefPtr<ScriptPromiseResolver> m_resolver;
- Persistent<FetchRequestData> m_request;
- Persistent<BodyStreamBuffer> m_responseBuffer;
- RefPtr<ThreadableLoader> m_loader;
- bool m_corsFlag;
- bool m_corsPreflightFlag;
- bool m_failed;
-};
-
-FetchManager::Loader::Loader(ExecutionContext* executionContext, FetchManager* fetchManager, PassRefPtr<ScriptPromiseResolver> resolver, const FetchRequestData* request)
- : m_executionContext(executionContext)
- , m_fetchManager(fetchManager)
- , m_resolver(resolver)
- , m_request(request->createCopy())
- , m_corsFlag(false)
- , m_corsPreflightFlag(false)
- , m_failed(false)
-{
-}
-
-FetchManager::Loader::~Loader()
-{
- if (m_loader)
- m_loader->cancel();
-}
-
-void FetchManager::Loader::didReceiveResponse(unsigned long, const ResourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle)
-{
- // FIXME: Use |handle|.
- ASSERT_UNUSED(handle, !handle);
- m_responseBuffer = new BodyStreamBuffer();
- FetchResponseData* responseData = FetchResponseData::createWithBuffer(m_responseBuffer);
- responseData->setStatus(response.httpStatusCode());
- responseData->setStatusMessage(response.httpStatusText());
- for (auto& it : response.httpHeaderFields())
- responseData->headerList()->append(it.key, it.value);
- responseData->setURL(m_request->url());
- responseData->setContentTypeForBuffer(response.mimeType());
-
- FetchResponseData* taintedResponse = responseData;
- switch (m_request->tainting()) {
- case FetchRequestData::BasicTainting:
- taintedResponse = responseData->createBasicFilteredResponse();
- break;
- case FetchRequestData::CORSTainting:
- taintedResponse = responseData->createCORSFilteredResponse();
- break;
- case FetchRequestData::OpaqueTainting:
- taintedResponse = responseData->createOpaqueFilteredResponse();
- break;
- }
- m_resolver->resolve(Response::create(m_resolver->executionContext(), taintedResponse));
- m_resolver.clear();
-}
-
-void FetchManager::Loader::didReceiveData(const char* data, unsigned size)
-{
- m_responseBuffer->write(DOMArrayBuffer::create(data, size));
-}
-
-void FetchManager::Loader::didFinishLoading(unsigned long, double)
-{
- ASSERT(m_responseBuffer);
- m_responseBuffer->close();
- m_responseBuffer.clear();
- notifyFinished();
-}
-
-void FetchManager::Loader::didFail(const ResourceError& error)
-{
- failed("Fetch API cannot load " + error.failingURL() + ". " + error.localizedDescription());
-}
-
-void FetchManager::Loader::didFailAccessControlCheck(const ResourceError& error)
-{
- failed("Fetch API cannot load " + error.failingURL() + ". " + error.localizedDescription());
-}
-
-void FetchManager::Loader::didFailRedirectCheck()
-{
- failed("Fetch API cannot load " + m_request->url().string() + ". Redirects are not yet supported.");
-}
-
-void FetchManager::Loader::start()
-{
- // "1. If |request|'s url contains a Known HSTS Host, modify it per the
- // requirements of the 'URI [sic] Loading and Port Mapping' chapter of HTTP
- // Strict Transport Security."
- // FIXME: Implement this.
-
- // "2. If |request|'s referrer is not none, set |request|'s referrer to the
- // result of invoking determine |request|'s referrer."
- // We set the referrer using workerGlobalScope's URL in
- // WorkerThreadableLoader.
-
- // "3. If |request|'s synchronous flag is unset and fetch is not invoked
- // recursively, run the remaining steps asynchronously."
- // We don't support synchronous flag.
-
- // "4. Let response be the value corresponding to the first matching
- // statement:"
-
- // "- should fetching |request| be blocked as mixed content returns blocked"
- // We do mixed content checking in ResourceFetcher.
-
- // "- should fetching |request| be blocked as content security returns
- // blocked"
- if (!ContentSecurityPolicy::shouldBypassMainWorld(m_executionContext) && !m_executionContext->contentSecurityPolicy()->allowConnectToSource(m_request->url())) {
- // "A network error."
- performNetworkError("Refused to connect to '" + m_request->url().elidedString() + "' because it violates the document's Content Security Policy.");
- return;
- }
-
- // "- |request|'s url's origin is |request|'s origin and the |CORS flag| is
- // unset"
- // "- |request|'s url's scheme is 'data' and |request|'s same-origin data
- // URL flag is set"
- // "- |request|'s url's scheme is 'about'"
- if ((SecurityOrigin::create(m_request->url())->isSameSchemeHostPort(m_request->origin().get()) && !m_corsFlag)
- || (m_request->url().protocolIsData() && m_request->sameOriginDataURLFlag())
- || (m_request->url().protocolIsAbout())) {
- // "The result of performing a basic fetch using request."
- performBasicFetch();
- return;
- }
-
- // "- |request|'s mode is |same-origin|"
- if (m_request->mode() == WebURLRequest::FetchRequestModeSameOrigin) {
- // "A network error."
- performNetworkError("Fetch API cannot load " + m_request->url().string() + ". Request mode is \"same-origin\" but the URL\'s origin is not same as the request origin " + m_request->origin()->toString() + ".");
- return;
- }
-
- // "- |request|'s mode is |no CORS|"
- if (m_request->mode() == WebURLRequest::FetchRequestModeNoCORS) {
- // "Set |request|'s response tainting to |opaque|."
- m_request->setResponseTainting(FetchRequestData::OpaqueTainting);
- // "The result of performing a basic fetch using |request|."
- performBasicFetch();
- return;
- }
-
- // "- |request|'s url's scheme is not one of 'http' and 'https'"
- if (!m_request->url().protocolIsInHTTPFamily()) {
- // "A network error."
- performNetworkError("Fetch API cannot load " + m_request->url().string() + ". URL scheme must be \"http\" or \"https\" for CORS request.");
- return;
- }
-
- // "- |request|'s mode is |CORS-with-forced-preflight|.
- // "- |request|'s unsafe request flag is set and either |request|'s method
- // is not a simple method or a header in |request|'s header list is not a
- // simple header"
- if (m_request->mode() == WebURLRequest::FetchRequestModeCORSWithForcedPreflight
- || (m_request->unsafeRequestFlag()
- && (!FetchUtils::isSimpleMethod(m_request->method())
- || m_request->headerList()->containsNonSimpleHeader()))) {
- // "Set |request|'s response tainting to |CORS|."
- m_request->setResponseTainting(FetchRequestData::CORSTainting);
- // "The result of performing an HTTP fetch using |request| with the
- // |CORS flag| and |CORS preflight flag| set."
- m_corsFlag = true;
- m_corsPreflightFlag = true;
- performHTTPFetch();
- return;
- }
-
- // "- Otherwise
- // Set |request|'s response tainting to |CORS|."
- m_request->setResponseTainting(FetchRequestData::CORSTainting);
- // "The result of performing an HTTP fetch using |request| with the
- // |CORS flag| set."
- m_corsFlag = true;
- m_corsPreflightFlag = false;
- performHTTPFetch();
-}
-
-void FetchManager::Loader::cleanup()
-{
- // Prevent notification
- m_fetchManager = 0;
-
- if (m_loader) {
- m_loader->cancel();
- m_loader.clear();
- }
-}
-
-void FetchManager::Loader::performBasicFetch()
-{
- // "To perform a basic fetch using |request|, switch on |request|'s url's
- // scheme, and run the associated steps:"
- if (m_request->url().protocolIsInHTTPFamily()) {
- // "Return the result of performing an HTTP fetch using |request|."
- m_corsFlag = false;
- m_corsPreflightFlag = false;
- performHTTPFetch();
- } else {
- // FIXME: implement other protocols.
- performNetworkError("Fetch API cannot load " + m_request->url().string() + ". URL scheme \"" + m_request->url().protocol() + "\" is not supported.");
- }
-}
-
-void FetchManager::Loader::performNetworkError(const String& message)
-{
- failed(message);
-}
-
-void FetchManager::Loader::performHTTPFetch()
-{
- ASSERT(m_request->url().protocolIsInHTTPFamily());
- // CORS preflight fetch procedure is implemented inside DocumentThreadableLoader.
-
- // "1. Let |HTTPRequest| be a copy of |request|, except that |HTTPRequest|'s
- // body is a tee of |request|'s body."
- // We use ResourceRequest class for HTTPRequest.
- // FIXME: Support body.
- ResourceRequest request(m_request->url());
- request.setRequestContext(WebURLRequest::RequestContextFetch);
- request.setHTTPMethod(m_request->method());
- const Vector<OwnPtr<FetchHeaderList::Header> >& list = m_request->headerList()->list();
- for (size_t i = 0; i < list.size(); ++i) {
- request.addHTTPHeaderField(AtomicString(list[i]->first), AtomicString(list[i]->second));
- }
-
- if (m_request->method() != "GET" && m_request->method() != "HEAD") {
- RefPtr<BlobDataHandle> blobDataHandle = m_request->blobDataHandle();
- if (blobDataHandle.get()) {
- RefPtr<FormData> httpBody(FormData::create());
- httpBody->appendBlob(blobDataHandle->uuid(), blobDataHandle);
- request.setHTTPBody(httpBody);
- }
- }
-
- // "2. Append `Referer`/empty byte sequence, if |HTTPRequest|'s |referrer|
- // is none, and `Referer`/|HTTPRequest|'s referrer, serialized and utf-8
- // encoded, otherwise, to HTTPRequest's header list.
- // We set the referrer using workerGlobalScope's URL in
- // WorkerThreadableLoader.
-
- // "3. Append `Host`, ..."
- // FIXME: Implement this when the spec is fixed.
-
- // "4.If |HTTPRequest|'s force Origin header flag is set, append `Origin`/
- // |HTTPRequest|'s origin, serialized and utf-8 encoded, to |HTTPRequest|'s
- // header list."
- // We set Origin header in updateRequestForAccessControl() called from
- // DocumentThreadableLoader::makeCrossOriginAccessRequest
-
- // "5. Let |credentials flag| be set if either |HTTPRequest|'s credentials
- // mode is |include|, or |HTTPRequest|'s credentials mode is |same-origin|
- // and the |CORS flag| is unset, and unset otherwise.
- ResourceLoaderOptions resourceLoaderOptions;
- resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
- if (m_request->credentials() == WebURLRequest::FetchCredentialsModeInclude
- || (m_request->credentials() == WebURLRequest::FetchCredentialsModeSameOrigin && !m_corsFlag)) {
- resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
- }
-
- ThreadableLoaderOptions threadableLoaderOptions;
- threadableLoaderOptions.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypassMainWorld(m_executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConnectSrcDirective;
- if (m_corsPreflightFlag)
- threadableLoaderOptions.preflightPolicy = ForcePreflight;
- if (m_corsFlag)
- threadableLoaderOptions.crossOriginRequestPolicy = UseAccessControl;
- else
- threadableLoaderOptions.crossOriginRequestPolicy = AllowCrossOriginRequests;
-
- m_loader = ThreadableLoader::create(*m_executionContext, this, request, threadableLoaderOptions, resourceLoaderOptions);
-}
-
-void FetchManager::Loader::failed(const String& message)
-{
- if (m_failed)
- return;
- m_failed = true;
- if (m_responseBuffer) {
- m_responseBuffer->error(DOMException::create(NetworkError, message));
- m_responseBuffer.clear();
- } else if (m_resolver) {
- if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped())
- return;
- ScriptState* state = m_resolver->scriptState();
- ScriptState::Scope scope(state);
- m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), message));
- }
- notifyFinished();
-}
-
-void FetchManager::Loader::notifyFinished()
-{
- if (m_fetchManager)
- m_fetchManager->onLoaderFinished(this);
-}
-
-FetchManager::FetchManager(ExecutionContext* executionContext)
- : m_executionContext(executionContext)
- , m_isStopped(false)
-{
-}
-
-FetchManager::~FetchManager()
-{
- if (!m_isStopped)
- stop();
-}
-
-ScriptPromise FetchManager::fetch(ScriptState* scriptState, const FetchRequestData* request)
-{
- RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
- ScriptPromise promise = resolver->promise();
-
- OwnPtr<Loader> ownLoader(adoptPtr(new Loader(m_executionContext, this, resolver.release(), request)));
- Loader* loader = m_loaders.add(ownLoader.release()).storedValue->get();
- loader->start();
- return promise;
-}
-
-void FetchManager::stop()
-{
- ASSERT(!m_isStopped);
- m_isStopped = true;
- for (auto& loader : m_loaders) {
- loader->cleanup();
- }
-}
-
-void FetchManager::onLoaderFinished(Loader* loader)
-{
- // We don't use remove here, becuase it may cause recursive deletion.
- OwnPtr<Loader> p = m_loaders.take(loader);
-}
-
-} // namespace blink
« no previous file with comments | « Source/modules/serviceworkers/FetchManager.h ('k') | Source/modules/serviceworkers/FetchRequestData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698