OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 #include "FetchManager.h" |
| 7 |
| 8 #include "bindings/v8/ScriptPromiseResolverWithContext.h" |
| 9 #include "bindings/v8/ScriptState.h" |
| 10 #include "bindings/v8/V8ThrowException.h" |
| 11 #include "core/dom/ExceptionCode.h" |
| 12 #include "core/fileapi/Blob.h" |
| 13 #include "core/loader/ThreadableLoader.h" |
| 14 #include "core/loader/ThreadableLoaderClient.h" |
| 15 #include "modules/serviceworkers/Response.h" |
| 16 #include "platform/network/ResourceRequest.h" |
| 17 #include "wtf/HashSet.h" |
| 18 |
| 19 namespace WebCore { |
| 20 |
| 21 class FetchManager::Loader : public ThreadableLoaderClient { |
| 22 public: |
| 23 Loader(ExecutionContext*, FetchManager*, PassRefPtr<ScriptPromiseResolverWit
hContext>, PassOwnPtr<ResourceRequest>); |
| 24 ~Loader(); |
| 25 virtual void didReceiveResponse(unsigned long, const ResourceResponse&); |
| 26 virtual void didFinishLoading(unsigned long, double); |
| 27 virtual void didFail(const ResourceError&); |
| 28 virtual void didFailAccessControlCheck(const ResourceError&); |
| 29 virtual void didFailRedirectCheck(); |
| 30 virtual void didDownloadData(int); |
| 31 |
| 32 void start(); |
| 33 void cleanup(); |
| 34 |
| 35 private: |
| 36 void failed(); |
| 37 void notifyFinished(); |
| 38 |
| 39 ExecutionContext* m_executionContext; |
| 40 FetchManager* m_fetchManager; |
| 41 RefPtr<ScriptPromiseResolverWithContext> m_resolver; |
| 42 OwnPtr<ResourceRequest> m_request; |
| 43 RefPtr<ThreadableLoader> m_loader; |
| 44 ResourceResponse m_response; |
| 45 long long m_downloadedBlobLength; |
| 46 bool m_failed; |
| 47 }; |
| 48 |
| 49 FetchManager::Loader::Loader(ExecutionContext* executionContext, FetchManager* f
etchManager, PassRefPtr<ScriptPromiseResolverWithContext> resolver, PassOwnPtr<R
esourceRequest> request) |
| 50 : m_executionContext(executionContext) |
| 51 , m_fetchManager(fetchManager) |
| 52 , m_resolver(resolver) |
| 53 , m_request(request) |
| 54 , m_downloadedBlobLength(0) |
| 55 , m_failed(false) |
| 56 { |
| 57 } |
| 58 |
| 59 FetchManager::Loader::~Loader() |
| 60 { |
| 61 if (m_loader) |
| 62 m_loader->cancel(); |
| 63 } |
| 64 |
| 65 void FetchManager::Loader::didReceiveResponse(unsigned long, const ResourceRespo
nse& response) |
| 66 { |
| 67 m_response = response; |
| 68 } |
| 69 |
| 70 void FetchManager::Loader::didFinishLoading(unsigned long, double) |
| 71 { |
| 72 OwnPtr<BlobData> blobData = BlobData::create(); |
| 73 String filePath = m_response.downloadedFilePath(); |
| 74 if (!filePath.isEmpty() && m_downloadedBlobLength) { |
| 75 blobData->appendFile(filePath); |
| 76 // FIXME: Set the ContentType correctly. |
| 77 } |
| 78 Dictionary options; |
| 79 // FIXME: fill options. |
| 80 RefPtrWillBeRawPtr<Blob> blob = Blob::create(BlobDataHandle::create(blobData
.release(), m_downloadedBlobLength)); |
| 81 // FIXME: Handle response status correctly. |
| 82 m_resolver->resolve(Response::create(blob.get(), options)); |
| 83 notifyFinished(); |
| 84 } |
| 85 |
| 86 void FetchManager::Loader::didFail(const ResourceError& error) |
| 87 { |
| 88 failed(); |
| 89 } |
| 90 |
| 91 void FetchManager::Loader::didFailAccessControlCheck(const ResourceError& error) |
| 92 { |
| 93 failed(); |
| 94 } |
| 95 |
| 96 void FetchManager::Loader::didFailRedirectCheck() |
| 97 { |
| 98 failed(); |
| 99 } |
| 100 |
| 101 void FetchManager::Loader::didDownloadData(int dataLength) |
| 102 { |
| 103 m_downloadedBlobLength += dataLength; |
| 104 } |
| 105 |
| 106 void FetchManager::Loader::start() |
| 107 { |
| 108 m_request->setDownloadToFile(true); |
| 109 ThreadableLoaderOptions options; |
| 110 // FIXME: Fill options. |
| 111 ResourceLoaderOptions resourceLoaderOptions; |
| 112 resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData; |
| 113 // FIXME: Fill resourceLoaderOptions. |
| 114 m_loader = ThreadableLoader::create(*m_executionContext, this, *m_request, o
ptions, resourceLoaderOptions); |
| 115 } |
| 116 |
| 117 void FetchManager::Loader::cleanup() |
| 118 { |
| 119 // Prevent notification |
| 120 m_fetchManager = 0; |
| 121 |
| 122 if (m_loader) { |
| 123 m_loader->cancel(); |
| 124 m_loader.clear(); |
| 125 } |
| 126 } |
| 127 |
| 128 void FetchManager::Loader::failed() |
| 129 { |
| 130 if (m_failed) |
| 131 return; |
| 132 m_failed = true; |
| 133 ScriptState* state = m_resolver->scriptState(); |
| 134 ScriptState::Scope scope(state); |
| 135 m_resolver->reject(V8ThrowException::createTypeError("Failed to fetch", stat
e->isolate())); |
| 136 notifyFinished(); |
| 137 } |
| 138 |
| 139 void FetchManager::Loader::notifyFinished() |
| 140 { |
| 141 if (m_fetchManager) |
| 142 m_fetchManager->onLoaderFinished(this); |
| 143 } |
| 144 |
| 145 FetchManager::FetchManager(ExecutionContext* executionContext) |
| 146 : m_executionContext(executionContext) |
| 147 { |
| 148 } |
| 149 |
| 150 FetchManager::~FetchManager() |
| 151 { |
| 152 for (HashSet<OwnPtr<Loader> >::iterator it = m_loaders.begin(); it != m_load
ers.end(); ++it) { |
| 153 (*it)->cleanup(); |
| 154 } |
| 155 } |
| 156 |
| 157 ScriptPromise FetchManager::fetch(ScriptState* scriptState, PassOwnPtr<ResourceR
equest> request) |
| 158 { |
| 159 RefPtr<ScriptPromiseResolverWithContext> resolver = ScriptPromiseResolverWit
hContext::create(scriptState); |
| 160 ScriptPromise promise = resolver->promise(); |
| 161 |
| 162 OwnPtr<Loader> loader(adoptPtr(new Loader(m_executionContext, this, resolver
.release(), request))); |
| 163 (*m_loaders.add(loader.release()).storedValue)->start(); |
| 164 return promise; |
| 165 } |
| 166 |
| 167 void FetchManager::onLoaderFinished(Loader* loader) |
| 168 { |
| 169 m_loaders.remove(loader); |
| 170 } |
| 171 |
| 172 } // namespace WebCore |
OLD | NEW |