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 |