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

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

Issue 318393002: Initial implementation of ServiceWorkerGlobalScope.fetch() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: incoroporated dominicc's comment Created 6 years, 6 months 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/Request.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
new file mode 100644
index 0000000000000000000000000000000000000000..ef174005747d04978014feac15ecc2a8dc808417
--- /dev/null
+++ b/Source/modules/serviceworkers/FetchManager.cpp
@@ -0,0 +1,172 @@
+// 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/v8/ScriptPromiseResolverWithContext.h"
+#include "bindings/v8/ScriptState.h"
+#include "bindings/v8/V8ThrowException.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/fileapi/Blob.h"
+#include "core/loader/ThreadableLoader.h"
+#include "core/loader/ThreadableLoaderClient.h"
+#include "modules/serviceworkers/Response.h"
+#include "platform/network/ResourceRequest.h"
+#include "wtf/HashSet.h"
+
+namespace WebCore {
+
+class FetchManager::Loader : public ThreadableLoaderClient {
+public:
+ Loader(ExecutionContext*, FetchManager*, PassRefPtr<ScriptPromiseResolverWithContext>, PassOwnPtr<ResourceRequest>);
+ ~Loader();
+ virtual void didReceiveResponse(unsigned long, const ResourceResponse&);
+ virtual void didFinishLoading(unsigned long, double);
+ virtual void didFail(const ResourceError&);
+ virtual void didFailAccessControlCheck(const ResourceError&);
+ virtual void didFailRedirectCheck();
+ virtual void didDownloadData(int);
+
+ void start();
+ void cleanup();
+
+private:
+ void failed();
+ void notifyFinished();
+
+ ExecutionContext* m_executionContext;
+ FetchManager* m_fetchManager;
+ RefPtr<ScriptPromiseResolverWithContext> m_resolver;
+ OwnPtr<ResourceRequest> m_request;
+ RefPtr<ThreadableLoader> m_loader;
+ ResourceResponse m_response;
+ long long m_downloadedBlobLength;
+ bool m_failed;
+};
+
+FetchManager::Loader::Loader(ExecutionContext* executionContext, FetchManager* fetchManager, PassRefPtr<ScriptPromiseResolverWithContext> resolver, PassOwnPtr<ResourceRequest> request)
+ : m_executionContext(executionContext)
+ , m_fetchManager(fetchManager)
+ , m_resolver(resolver)
+ , m_request(request)
+ , m_downloadedBlobLength(0)
+ , m_failed(false)
+{
+}
+
+FetchManager::Loader::~Loader()
+{
+ if (m_loader)
+ m_loader->cancel();
+}
+
+void FetchManager::Loader::didReceiveResponse(unsigned long, const ResourceResponse& response)
+{
+ m_response = response;
+}
+
+void FetchManager::Loader::didFinishLoading(unsigned long, double)
+{
+ OwnPtr<BlobData> blobData = BlobData::create();
+ String filePath = m_response.downloadedFilePath();
+ if (!filePath.isEmpty() && m_downloadedBlobLength) {
+ blobData->appendFile(filePath);
+ // FIXME: Set the ContentType correctly.
+ }
+ Dictionary options;
+ // FIXME: fill options.
+ RefPtrWillBeRawPtr<Blob> blob = Blob::create(BlobDataHandle::create(blobData.release(), m_downloadedBlobLength));
+ // FIXME: Handle response status correctly.
+ m_resolver->resolve(Response::create(blob.get(), options));
+ notifyFinished();
+}
+
+void FetchManager::Loader::didFail(const ResourceError& error)
+{
+ failed();
+}
+
+void FetchManager::Loader::didFailAccessControlCheck(const ResourceError& error)
+{
+ failed();
+}
+
+void FetchManager::Loader::didFailRedirectCheck()
+{
+ failed();
+}
+
+void FetchManager::Loader::didDownloadData(int dataLength)
+{
+ m_downloadedBlobLength += dataLength;
+}
+
+void FetchManager::Loader::start()
+{
+ m_request->setDownloadToFile(true);
+ ThreadableLoaderOptions options;
+ // FIXME: Fill options.
+ ResourceLoaderOptions resourceLoaderOptions;
+ resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
+ // FIXME: Fill resourceLoaderOptions.
+ m_loader = ThreadableLoader::create(*m_executionContext, this, *m_request, options, resourceLoaderOptions);
+}
+
+void FetchManager::Loader::cleanup()
+{
+ // Prevent notification
+ m_fetchManager = 0;
+
+ if (m_loader) {
+ m_loader->cancel();
+ m_loader.clear();
+ }
+}
+
+void FetchManager::Loader::failed()
+{
+ if (m_failed)
+ return;
+ m_failed = true;
+ ScriptState* state = m_resolver->scriptState();
+ ScriptState::Scope scope(state);
+ m_resolver->reject(V8ThrowException::createTypeError("Failed to fetch", state->isolate()));
+ notifyFinished();
+}
+
+void FetchManager::Loader::notifyFinished()
+{
+ if (m_fetchManager)
+ m_fetchManager->onLoaderFinished(this);
+}
+
+FetchManager::FetchManager(ExecutionContext* executionContext)
+ : m_executionContext(executionContext)
+{
+}
+
+FetchManager::~FetchManager()
+{
+ for (HashSet<OwnPtr<Loader> >::iterator it = m_loaders.begin(); it != m_loaders.end(); ++it) {
+ (*it)->cleanup();
+ }
+}
+
+ScriptPromise FetchManager::fetch(ScriptState* scriptState, PassOwnPtr<ResourceRequest> request)
+{
+ RefPtr<ScriptPromiseResolverWithContext> resolver = ScriptPromiseResolverWithContext::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+
+ OwnPtr<Loader> loader(adoptPtr(new Loader(m_executionContext, this, resolver.release(), request)));
+ (*m_loaders.add(loader.release()).storedValue)->start();
+ return promise;
+}
+
+void FetchManager::onLoaderFinished(Loader* loader)
+{
+ m_loaders.remove(loader);
+}
+
+} // namespace WebCore
« no previous file with comments | « Source/modules/serviceworkers/FetchManager.h ('k') | Source/modules/serviceworkers/Request.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698