Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "FetchManager.h" | 6 #include "FetchManager.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
| 9 #include "bindings/core/v8/ScriptPromiseResolver.h" | 9 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 10 #include "bindings/core/v8/ScriptState.h" | 10 #include "bindings/core/v8/ScriptState.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 virtual void didFail(const ResourceError&); | 33 virtual void didFail(const ResourceError&); |
| 34 virtual void didFailAccessControlCheck(const ResourceError&); | 34 virtual void didFailAccessControlCheck(const ResourceError&); |
| 35 virtual void didFailRedirectCheck(); | 35 virtual void didFailRedirectCheck(); |
| 36 virtual void didDownloadData(int); | 36 virtual void didDownloadData(int); |
| 37 | 37 |
| 38 void start(); | 38 void start(); |
| 39 void cleanup(); | 39 void cleanup(); |
| 40 | 40 |
| 41 private: | 41 private: |
| 42 void performBasicFetch(); | 42 void performBasicFetch(); |
| 43 void performNetworkError(); | 43 void performNetworkError(const String& message); |
| 44 void performHTTPFetch(); | 44 void performHTTPFetch(); |
| 45 void failed(); | 45 void failed(const String& message); |
| 46 void notifyFinished(); | 46 void notifyFinished(); |
| 47 | 47 |
| 48 ExecutionContext* m_executionContext; | 48 ExecutionContext* m_executionContext; |
| 49 FetchManager* m_fetchManager; | 49 FetchManager* m_fetchManager; |
| 50 RefPtr<ScriptPromiseResolver> m_resolver; | 50 RefPtr<ScriptPromiseResolver> m_resolver; |
| 51 Persistent<FetchRequestData> m_request; | 51 Persistent<FetchRequestData> m_request; |
| 52 RefPtr<ThreadableLoader> m_loader; | 52 RefPtr<ThreadableLoader> m_loader; |
| 53 ResourceResponse m_response; | 53 ResourceResponse m_response; |
| 54 long long m_downloadedBlobLength; | 54 long long m_downloadedBlobLength; |
| 55 bool m_corsFlag; | 55 bool m_corsFlag; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 case FetchRequestData::OpaqueTainting: | 113 case FetchRequestData::OpaqueTainting: |
| 114 response = response->createOpaqueFilteredResponse(); | 114 response = response->createOpaqueFilteredResponse(); |
| 115 break; | 115 break; |
| 116 } | 116 } |
| 117 m_resolver->resolve(Response::create(m_resolver->executionContext(), respons e)); | 117 m_resolver->resolve(Response::create(m_resolver->executionContext(), respons e)); |
| 118 notifyFinished(); | 118 notifyFinished(); |
| 119 } | 119 } |
| 120 | 120 |
| 121 void FetchManager::Loader::didFail(const ResourceError& error) | 121 void FetchManager::Loader::didFail(const ResourceError& error) |
| 122 { | 122 { |
| 123 failed(); | 123 failed("Fetch API cannot load " + error.failingURL() + ". " + error.localize dDescription()); |
| 124 } | 124 } |
| 125 | 125 |
| 126 void FetchManager::Loader::didFailAccessControlCheck(const ResourceError& error) | 126 void FetchManager::Loader::didFailAccessControlCheck(const ResourceError& error) |
| 127 { | 127 { |
| 128 failed(); | 128 failed("Fetch API cannot load " + error.failingURL() + ". " + error.localize dDescription()); |
| 129 } | 129 } |
| 130 | 130 |
| 131 void FetchManager::Loader::didFailRedirectCheck() | 131 void FetchManager::Loader::didFailRedirectCheck() |
| 132 { | 132 { |
| 133 failed(); | 133 failed("Fetch API cannot load " + m_request->url().string() + ". Unsupported redirection."); |
|
falken
2014/11/17 02:14:46
This message suggests there is a class of unsuppor
horo
2014/11/17 03:25:35
Done.
| |
| 134 } | 134 } |
| 135 | 135 |
| 136 void FetchManager::Loader::didDownloadData(int dataLength) | 136 void FetchManager::Loader::didDownloadData(int dataLength) |
| 137 { | 137 { |
| 138 m_downloadedBlobLength += dataLength; | 138 m_downloadedBlobLength += dataLength; |
| 139 } | 139 } |
| 140 | 140 |
| 141 void FetchManager::Loader::start() | 141 void FetchManager::Loader::start() |
| 142 { | 142 { |
| 143 // "1. If |request|'s url contains a Known HSTS Host, modify it per the | 143 // "1. If |request|'s url contains a Known HSTS Host, modify it per the |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 172 || (m_request->url().protocolIsData() && m_request->sameOriginDataURLFla g()) | 172 || (m_request->url().protocolIsData() && m_request->sameOriginDataURLFla g()) |
| 173 || (m_request->url().protocolIsAbout())) { | 173 || (m_request->url().protocolIsAbout())) { |
| 174 // "The result of performing a basic fetch using request." | 174 // "The result of performing a basic fetch using request." |
| 175 performBasicFetch(); | 175 performBasicFetch(); |
| 176 return; | 176 return; |
| 177 } | 177 } |
| 178 | 178 |
| 179 // "- |request|'s mode is |same-origin|" | 179 // "- |request|'s mode is |same-origin|" |
| 180 if (m_request->mode() == WebURLRequest::FetchRequestModeSameOrigin) { | 180 if (m_request->mode() == WebURLRequest::FetchRequestModeSameOrigin) { |
| 181 // "A network error." | 181 // "A network error." |
| 182 performNetworkError(); | 182 performNetworkError("Fetch API cannot load " + m_request->url().string() + ". Request mode is \"same-origin\" but the URL is not same origin."); |
|
falken
2014/11/17 02:14:46
not the same origin as what?
horo
2014/11/17 03:25:35
Done.
| |
| 183 return; | 183 return; |
| 184 } | 184 } |
| 185 | 185 |
| 186 // "- |request|'s mode is |no CORS|" | 186 // "- |request|'s mode is |no CORS|" |
| 187 if (m_request->mode() == WebURLRequest::FetchRequestModeNoCORS) { | 187 if (m_request->mode() == WebURLRequest::FetchRequestModeNoCORS) { |
| 188 // "Set |request|'s response tainting to |opaque|." | 188 // "Set |request|'s response tainting to |opaque|." |
| 189 m_request->setResponseTainting(FetchRequestData::OpaqueTainting); | 189 m_request->setResponseTainting(FetchRequestData::OpaqueTainting); |
| 190 // "The result of performing a basic fetch using |request|." | 190 // "The result of performing a basic fetch using |request|." |
| 191 performBasicFetch(); | 191 performBasicFetch(); |
| 192 return; | 192 return; |
| 193 } | 193 } |
| 194 | 194 |
| 195 // "- |request|'s url's scheme is not one of 'http' and 'https'" | 195 // "- |request|'s url's scheme is not one of 'http' and 'https'" |
| 196 if (!m_request->url().protocolIsInHTTPFamily()) { | 196 if (!m_request->url().protocolIsInHTTPFamily()) { |
| 197 // "A network error." | 197 // "A network error." |
| 198 performNetworkError(); | 198 performNetworkError("Fetch API cannot load " + m_request->url().string() + ". URL scheme must be \"http\" or \"https\" for CORS request."); |
| 199 return; | 199 return; |
| 200 } | 200 } |
| 201 | 201 |
| 202 // "- |request|'s mode is |CORS-with-forced-preflight|. | 202 // "- |request|'s mode is |CORS-with-forced-preflight|. |
| 203 // "- |request|'s unsafe request flag is set and either |request|'s method | 203 // "- |request|'s unsafe request flag is set and either |request|'s method |
| 204 // is not a simple method or a header in |request|'s header list is not a | 204 // is not a simple method or a header in |request|'s header list is not a |
| 205 // simple header" | 205 // simple header" |
| 206 if (m_request->mode() == WebURLRequest::FetchRequestModeCORSWithForcedPrefli ght | 206 if (m_request->mode() == WebURLRequest::FetchRequestModeCORSWithForcedPrefli ght |
| 207 || (m_request->unsafeRequestFlag() | 207 || (m_request->unsafeRequestFlag() |
| 208 && (!FetchUtils::isSimpleMethod(m_request->method()) | 208 && (!FetchUtils::isSimpleMethod(m_request->method()) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 242 { | 242 { |
| 243 // "To perform a basic fetch using |request|, switch on |request|'s url's | 243 // "To perform a basic fetch using |request|, switch on |request|'s url's |
| 244 // scheme, and run the associated steps:" | 244 // scheme, and run the associated steps:" |
| 245 if (m_request->url().protocolIsInHTTPFamily()) { | 245 if (m_request->url().protocolIsInHTTPFamily()) { |
| 246 // "Return the result of performing an HTTP fetch using |request|." | 246 // "Return the result of performing an HTTP fetch using |request|." |
| 247 m_corsFlag = false; | 247 m_corsFlag = false; |
| 248 m_corsPreflightFlag = false; | 248 m_corsPreflightFlag = false; |
| 249 performHTTPFetch(); | 249 performHTTPFetch(); |
| 250 } else { | 250 } else { |
| 251 // FIXME: implement other protocols. | 251 // FIXME: implement other protocols. |
| 252 performNetworkError(); | 252 performNetworkError("Fetch API cannot load " + m_request->url().string() + ". URL scheme \"" + m_request->url().protocol() + "\" is not supported."); |
| 253 } | 253 } |
| 254 } | 254 } |
| 255 | 255 |
| 256 void FetchManager::Loader::performNetworkError() | 256 void FetchManager::Loader::performNetworkError(const String& message) |
| 257 { | 257 { |
| 258 failed(); | 258 failed(message); |
| 259 } | 259 } |
| 260 | 260 |
| 261 void FetchManager::Loader::performHTTPFetch() | 261 void FetchManager::Loader::performHTTPFetch() |
| 262 { | 262 { |
| 263 ASSERT(m_request->url().protocolIsInHTTPFamily()); | 263 ASSERT(m_request->url().protocolIsInHTTPFamily()); |
| 264 // CORS preflight fetch procedure is implemented inside DocumentThreadableLo ader. | 264 // CORS preflight fetch procedure is implemented inside DocumentThreadableLo ader. |
| 265 | 265 |
| 266 // "1. Let |HTTPRequest| be a copy of |request|, except that |HTTPRequest|'s | 266 // "1. Let |HTTPRequest| be a copy of |request|, except that |HTTPRequest|'s |
| 267 // body is a tee of |request|'s body." | 267 // body is a tee of |request|'s body." |
| 268 // We use ResourceRequest class for HTTPRequest. | 268 // We use ResourceRequest class for HTTPRequest. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 threadableLoaderOptions.preflightPolicy = ForcePreflight; | 315 threadableLoaderOptions.preflightPolicy = ForcePreflight; |
| 316 if (m_corsFlag) | 316 if (m_corsFlag) |
| 317 threadableLoaderOptions.crossOriginRequestPolicy = UseAccessControl; | 317 threadableLoaderOptions.crossOriginRequestPolicy = UseAccessControl; |
| 318 else | 318 else |
| 319 threadableLoaderOptions.crossOriginRequestPolicy = AllowCrossOriginReque sts; | 319 threadableLoaderOptions.crossOriginRequestPolicy = AllowCrossOriginReque sts; |
| 320 | 320 |
| 321 | 321 |
| 322 m_loader = ThreadableLoader::create(*m_executionContext, this, request, thre adableLoaderOptions, resourceLoaderOptions); | 322 m_loader = ThreadableLoader::create(*m_executionContext, this, request, thre adableLoaderOptions, resourceLoaderOptions); |
| 323 } | 323 } |
| 324 | 324 |
| 325 void FetchManager::Loader::failed() | 325 void FetchManager::Loader::failed(const String& message) |
| 326 { | 326 { |
| 327 if (m_failed) | 327 if (m_failed) |
| 328 return; | 328 return; |
| 329 if (!m_resolver->executionContext() || m_resolver->executionContext()->activ eDOMObjectsAreStopped()) | 329 if (!m_resolver->executionContext() || m_resolver->executionContext()->activ eDOMObjectsAreStopped()) |
| 330 return; | 330 return; |
| 331 m_failed = true; | 331 m_failed = true; |
| 332 ScriptState* state = m_resolver->scriptState(); | 332 ScriptState* state = m_resolver->scriptState(); |
| 333 ScriptState::Scope scope(state); | 333 ScriptState::Scope scope(state); |
| 334 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), "Fail ed to fetch")); | 334 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), messa ge)); |
| 335 notifyFinished(); | 335 notifyFinished(); |
| 336 } | 336 } |
| 337 | 337 |
| 338 void FetchManager::Loader::notifyFinished() | 338 void FetchManager::Loader::notifyFinished() |
| 339 { | 339 { |
| 340 if (m_fetchManager) | 340 if (m_fetchManager) |
| 341 m_fetchManager->onLoaderFinished(this); | 341 m_fetchManager->onLoaderFinished(this); |
| 342 } | 342 } |
| 343 | 343 |
| 344 FetchManager::FetchManager(ExecutionContext* executionContext) | 344 FetchManager::FetchManager(ExecutionContext* executionContext) |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 363 loader->start(); | 363 loader->start(); |
| 364 return promise; | 364 return promise; |
| 365 } | 365 } |
| 366 | 366 |
| 367 void FetchManager::onLoaderFinished(Loader* loader) | 367 void FetchManager::onLoaderFinished(Loader* loader) |
| 368 { | 368 { |
| 369 m_loaders.remove(loader); | 369 m_loaders.remove(loader); |
| 370 } | 370 } |
| 371 | 371 |
| 372 } // namespace blink | 372 } // namespace blink |
| OLD | NEW |