OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
3 * Copyright (C) 2013, Intel Corporation | 3 * Copyright (C) 2013, Intel Corporation |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 | 119 |
120 // Max number of CORS redirects handled in DocumentThreadableLoader. | 120 // Max number of CORS redirects handled in DocumentThreadableLoader. |
121 // Same number as net/url_request/url_request.cc, and | 121 // Same number as net/url_request/url_request.cc, and |
122 // same number as https://fetch.spec.whatwg.org/#concept-http-fetch, Step 4. | 122 // same number as https://fetch.spec.whatwg.org/#concept-http-fetch, Step 4. |
123 // FIXME: currently the number of redirects is counted and limited here and in | 123 // FIXME: currently the number of redirects is counted and limited here and in |
124 // net/url_request/url_request.cc separately. | 124 // net/url_request/url_request.cc separately. |
125 static const int kMaxCORSRedirects = 20; | 125 static const int kMaxCORSRedirects = 20; |
126 | 126 |
127 void DocumentThreadableLoader::loadResourceSynchronously(Document& document, con st ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoa derOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) | 127 void DocumentThreadableLoader::loadResourceSynchronously(Document& document, con st ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoa derOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) |
128 { | 128 { |
129 // The loader will be deleted as soon as this function exits. | 129 (new DocumentThreadableLoader(document, &client, LoadSynchronously, options, resourceLoaderOptions))->start(request); |
130 std::unique_ptr<DocumentThreadableLoader> loader = wrapUnique(new DocumentTh readableLoader(document, &client, LoadSynchronously, options, resourceLoaderOpti ons)); | |
131 loader->start(request); | |
132 } | 130 } |
133 | 131 |
134 std::unique_ptr<DocumentThreadableLoader> DocumentThreadableLoader::create(Docum ent& document, ThreadableLoaderClient* client, const ThreadableLoaderOptions& op tions, const ResourceLoaderOptions& resourceLoaderOptions) | 132 DocumentThreadableLoader* DocumentThreadableLoader::create(Document& document, T hreadableLoaderClient* client, const ThreadableLoaderOptions& options, const Res ourceLoaderOptions& resourceLoaderOptions) |
135 { | 133 { |
136 return wrapUnique(new DocumentThreadableLoader(document, client, LoadAsynchr onously, options, resourceLoaderOptions)); | 134 return new DocumentThreadableLoader(document, client, LoadAsynchronously, op tions, resourceLoaderOptions); |
137 } | 135 } |
138 | 136 |
139 DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl eLoaderClient* client, BlockingBehavior blockingBehavior, const ThreadableLoader Options& options, const ResourceLoaderOptions& resourceLoaderOptions) | 137 DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl eLoaderClient* client, BlockingBehavior blockingBehavior, const ThreadableLoader Options& options, const ResourceLoaderOptions& resourceLoaderOptions) |
140 : m_client(client) | 138 : m_client(client) |
141 , m_document(&document) | 139 , m_document(&document) |
142 , m_options(options) | 140 , m_options(options) |
143 , m_resourceLoaderOptions(resourceLoaderOptions) | 141 , m_resourceLoaderOptions(resourceLoaderOptions) |
144 , m_forceDoNotAllowStoredCredentials(false) | 142 , m_forceDoNotAllowStoredCredentials(false) |
145 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) | 143 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) |
146 , m_sameOriginRequest(false) | 144 , m_sameOriginRequest(false) |
(...skipping 18 matching lines...) Expand all Loading... | |
165 | 163 |
166 m_sameOriginRequest = getSecurityOrigin()->canRequestNoSuborigin(request.url ()); | 164 m_sameOriginRequest = getSecurityOrigin()->canRequestNoSuborigin(request.url ()); |
167 m_requestContext = request.requestContext(); | 165 m_requestContext = request.requestContext(); |
168 m_redirectMode = request.fetchRedirectMode(); | 166 m_redirectMode = request.fetchRedirectMode(); |
169 | 167 |
170 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO riginRequests) { | 168 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO riginRequests) { |
171 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadingFo rClient(m_document, m_client); | 169 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadingFo rClient(m_document, m_client); |
172 ThreadableLoaderClient* client = m_client; | 170 ThreadableLoaderClient* client = m_client; |
173 clear(); | 171 clear(); |
174 client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url() .getString(), "Cross origin requests are not supported.")); | 172 client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url() .getString(), "Cross origin requests are not supported.")); |
175 // |this| may be dead here. | |
176 return; | 173 return; |
177 } | 174 } |
178 | 175 |
179 m_requestStartedSeconds = monotonicallyIncreasingTime(); | 176 m_requestStartedSeconds = monotonicallyIncreasingTime(); |
180 | 177 |
181 // Save any CORS simple headers on the request here. If this request redirec ts cross-origin, we cancel the old request | 178 // Save any CORS simple headers on the request here. If this request redirec ts cross-origin, we cancel the old request |
182 // create a new one, and copy these headers. | 179 // create a new one, and copy these headers. |
183 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); | 180 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); |
184 for (const auto& header : headerMap) { | 181 for (const auto& header : headerMap) { |
185 if (FetchUtils::isSimpleHeader(header.key, header.value)) { | 182 if (FetchUtils::isSimpleHeader(header.key, header.value)) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 // m_fallbackRequestForServiceWorker is used when a regular controll ing | 243 // m_fallbackRequestForServiceWorker is used when a regular controll ing |
247 // service worker doesn't handle a cross origin request. When this h appens | 244 // service worker doesn't handle a cross origin request. When this h appens |
248 // we still want to give foreign fetch a chance to handle the reques t, so | 245 // we still want to give foreign fetch a chance to handle the reques t, so |
249 // only skip the controlling service worker for the fallback request . | 246 // only skip the controlling service worker for the fallback request . |
250 // This is currently safe because of http://crbug.com/604084 the | 247 // This is currently safe because of http://crbug.com/604084 the |
251 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch | 248 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch |
252 // handled a request. | 249 // handled a request. |
253 m_fallbackRequestForServiceWorker.setSkipServiceWorker(WebURLRequest ::SkipServiceWorker::Controlling); | 250 m_fallbackRequestForServiceWorker.setSkipServiceWorker(WebURLRequest ::SkipServiceWorker::Controlling); |
254 } | 251 } |
255 loadRequest(newRequest, m_resourceLoaderOptions); | 252 loadRequest(newRequest, m_resourceLoaderOptions); |
256 // |this| may be dead here. | |
257 return; | 253 return; |
258 } | 254 } |
259 | 255 |
260 dispatchInitialRequest(newRequest); | 256 dispatchInitialRequest(newRequest); |
261 // |this| may be dead here in async mode. | |
262 } | 257 } |
263 | 258 |
264 void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req uest) | 259 void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req uest) |
265 { | 260 { |
266 if (!request.isExternalRequest() && (m_sameOriginRequest || m_options.crossO riginRequestPolicy == AllowCrossOriginRequests)) { | 261 if (!request.isExternalRequest() && (m_sameOriginRequest || m_options.crossO riginRequestPolicy == AllowCrossOriginRequests)) { |
267 loadRequest(request, m_resourceLoaderOptions); | 262 loadRequest(request, m_resourceLoaderOptions); |
268 // |this| may be dead here in async mode. | |
269 return; | 263 return; |
270 } | 264 } |
271 | 265 |
272 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isE xternalRequest()); | 266 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isE xternalRequest()); |
273 | 267 |
274 makeCrossOriginAccessRequest(request); | 268 makeCrossOriginAccessRequest(request); |
275 // |this| may be dead here in async mode. | |
276 } | 269 } |
277 | 270 |
278 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request) | 271 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request) |
279 { | 272 { |
280 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isE xternalRequest()); | 273 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isE xternalRequest()); |
281 ASSERT(m_client); | 274 ASSERT(m_client); |
282 ASSERT(!resource()); | 275 ASSERT(!resource()); |
283 | 276 |
284 // Cross-origin requests are only allowed certain registered schemes. | 277 // Cross-origin requests are only allowed certain registered schemes. |
285 // We would catch this when checking response headers later, but there | 278 // We would catch this when checking response headers later, but there |
286 // is no reason to send a request, preflighted or not, that's guaranteed | 279 // is no reason to send a request, preflighted or not, that's guaranteed |
287 // to be denied. | 280 // to be denied. |
288 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) { | 281 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) { |
289 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadingFo rClient(m_document, m_client); | 282 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadingFo rClient(m_document, m_client); |
290 ThreadableLoaderClient* client = m_client; | 283 ThreadableLoaderClient* client = m_client; |
291 clear(); | 284 clear(); |
292 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, request.url().getString(), "Cross origin requests are only supported for pr otocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); | 285 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, request.url().getString(), "Cross origin requests are only supported for pr otocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); |
293 // |this| may be dead here in async mode. | |
294 return; | 286 return; |
295 } | 287 } |
296 | 288 |
297 // Non-secure origins may not make "external requests": https://mikewest.git hub.io/cors-rfc1918/#integration-fetch | 289 // Non-secure origins may not make "external requests": https://mikewest.git hub.io/cors-rfc1918/#integration-fetch |
298 if (!document().isSecureContext() && request.isExternalRequest()) { | 290 if (!document().isSecureContext() && request.isExternalRequest()) { |
299 ThreadableLoaderClient* client = m_client; | 291 ThreadableLoaderClient* client = m_client; |
300 clear(); | 292 clear(); |
301 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, request.url().getString(), "Requests to internal network resources are not allowed from non-secure contexts (see https://goo.gl/Y0ZkNV). This is an experim ental restriction which is part of 'https://mikewest.github.io/cors-rfc1918/'.") ); | 293 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, request.url().getString(), "Requests to internal network resources are not allowed from non-secure contexts (see https://goo.gl/Y0ZkNV). This is an experim ental restriction which is part of 'https://mikewest.github.io/cors-rfc1918/'.") ); |
302 // |this| may be dead here in async mode. | |
303 return; | 294 return; |
304 } | 295 } |
305 | 296 |
306 ResourceRequest crossOriginRequest(request); | 297 ResourceRequest crossOriginRequest(request); |
307 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); | 298 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); |
308 | 299 |
309 // We use isSimpleOrForbiddenRequest() here since |request| may have been | 300 // We use isSimpleOrForbiddenRequest() here since |request| may have been |
310 // modified in the process of loading (not from the user's input). For | 301 // modified in the process of loading (not from the user's input). For |
311 // example, referrer. We need to accept them. For security, we must reject | 302 // example, referrer. We need to accept them. For security, we must reject |
312 // forbidden headers/methods at the point we accept user's input. Not here. | 303 // forbidden headers/methods at the point we accept user's input. Not here. |
313 if (!request.isExternalRequest() && ((m_options.preflightPolicy == ConsiderP reflight && FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), request .httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)) { | 304 if (!request.isExternalRequest() && ((m_options.preflightPolicy == ConsiderP reflight && FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), request .httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)) { |
314 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), e ffectiveAllowCredentials()); | 305 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), e ffectiveAllowCredentials()); |
315 // We update the credentials mode according to effectiveAllowCredentials () here for backward compatibility. But this is not correct. | 306 // We update the credentials mode according to effectiveAllowCredentials () here for backward compatibility. But this is not correct. |
316 // FIXME: We should set it in the caller of DocumentThreadableLoader. | 307 // FIXME: We should set it in the caller of DocumentThreadableLoader. |
317 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() = = AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe quest::FetchCredentialsModeOmit); | 308 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() = = AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe quest::FetchCredentialsModeOmit); |
318 if (m_didRedirect) { | 309 if (m_didRedirect) { |
319 crossOriginRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( m_referrerAfterRedirect.referrerPolicy, crossOriginRequest.url(), m_referrerAfte rRedirect.referrer)); | 310 crossOriginRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( m_referrerAfterRedirect.referrerPolicy, crossOriginRequest.url(), m_referrerAfte rRedirect.referrer)); |
320 } | 311 } |
321 loadRequest(crossOriginRequest, crossOriginOptions); | 312 loadRequest(crossOriginRequest, crossOriginOptions); |
322 // |this| may be dead here in async mode. | |
323 } else { | 313 } else { |
324 m_crossOriginNonSimpleRequest = true; | 314 m_crossOriginNonSimpleRequest = true; |
325 // Do not set the Origin header for preflight requests. | 315 // Do not set the Origin header for preflight requests. |
326 updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCrede ntials()); | 316 updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCrede ntials()); |
327 // We update the credentials mode according to effectiveAllowCredentials () here for backward compatibility. But this is not correct. | 317 // We update the credentials mode according to effectiveAllowCredentials () here for backward compatibility. But this is not correct. |
328 // FIXME: We should set it in the caller of DocumentThreadableLoader. | 318 // FIXME: We should set it in the caller of DocumentThreadableLoader. |
329 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() = = AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe quest::FetchCredentialsModeOmit); | 319 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() = = AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe quest::FetchCredentialsModeOmit); |
330 m_actualRequest = crossOriginRequest; | 320 m_actualRequest = crossOriginRequest; |
331 m_actualOptions = crossOriginOptions; | 321 m_actualOptions = crossOriginOptions; |
332 | 322 |
333 if (m_didRedirect) { | 323 if (m_didRedirect) { |
334 m_actualRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(m_r eferrerAfterRedirect.referrerPolicy, m_actualRequest.url(), m_referrerAfterRedir ect.referrer)); | 324 m_actualRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(m_r eferrerAfterRedirect.referrerPolicy, m_actualRequest.url(), m_referrerAfterRedir ect.referrer)); |
335 } | 325 } |
336 | 326 |
337 bool shouldForcePreflight = request.isExternalRequest() || InspectorInst rumentation::shouldForceCORSPreflight(m_document); | 327 bool shouldForcePreflight = request.isExternalRequest() || InspectorInst rumentation::shouldForceCORSPreflight(m_document); |
338 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki pPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllo wCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields() ); | 328 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki pPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllo wCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields() ); |
339 if (canSkipPreflight && !shouldForcePreflight) { | 329 if (canSkipPreflight && !shouldForcePreflight) { |
340 loadActualRequest(); | 330 loadActualRequest(); |
341 // |this| may be dead here in async mode. | |
342 } else { | 331 } else { |
343 ResourceRequest preflightRequest = createAccessControlPreflightReque st(m_actualRequest, getSecurityOrigin()); | 332 ResourceRequest preflightRequest = createAccessControlPreflightReque st(m_actualRequest, getSecurityOrigin()); |
344 // Create a ResourceLoaderOptions for preflight. | 333 // Create a ResourceLoaderOptions for preflight. |
345 ResourceLoaderOptions preflightOptions = m_actualOptions; | 334 ResourceLoaderOptions preflightOptions = m_actualOptions; |
346 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; | 335 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; |
347 loadRequest(preflightRequest, preflightOptions); | 336 loadRequest(preflightRequest, preflightOptions); |
348 // |this| may be dead here in async mode. | |
349 } | 337 } |
350 } | 338 } |
351 } | 339 } |
352 | 340 |
353 DocumentThreadableLoader::~DocumentThreadableLoader() | 341 DocumentThreadableLoader::~DocumentThreadableLoader() |
354 { | 342 { |
355 CHECK(!m_client); | 343 CHECK(!m_client); |
356 DCHECK(!m_resource); | 344 DCHECK(!m_resource); |
haraken
2016/08/01 07:34:20
ToT still has clearResource() here. Maybe this pat
yhirano
2016/08/01 07:56:43
Yes, this CL is depending on https://codereview.ch
| |
357 } | 345 } |
358 | 346 |
359 void DocumentThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds ) | 347 void DocumentThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds ) |
360 { | 348 { |
361 ASSERT(m_async); | 349 ASSERT(m_async); |
362 | 350 |
363 // |m_requestStartedSeconds| == 0.0 indicates loading is already finished | 351 // |m_requestStartedSeconds| == 0.0 indicates loading is already finished |
364 // and |m_timeoutTimer| is already stopped, and thus we do nothing for such | 352 // and |m_timeoutTimer| is already stopped, and thus we do nothing for such |
365 // cases. See https://crbug.com/551663 for details. | 353 // cases. See https://crbug.com/551663 for details. |
366 if (m_requestStartedSeconds <= 0.0) | 354 if (m_requestStartedSeconds <= 0.0) |
(...skipping 11 matching lines...) Expand all Loading... | |
378 double elapsedTime = monotonicallyIncreasingTime() - m_requestStartedSec onds; | 366 double elapsedTime = monotonicallyIncreasingTime() - m_requestStartedSec onds; |
379 double nextFire = timeoutMilliseconds / 1000.0; | 367 double nextFire = timeoutMilliseconds / 1000.0; |
380 double resolvedTime = std::max(nextFire - elapsedTime, 0.0); | 368 double resolvedTime = std::max(nextFire - elapsedTime, 0.0); |
381 m_timeoutTimer.startOneShot(resolvedTime, BLINK_FROM_HERE); | 369 m_timeoutTimer.startOneShot(resolvedTime, BLINK_FROM_HERE); |
382 } | 370 } |
383 } | 371 } |
384 | 372 |
385 void DocumentThreadableLoader::cancel() | 373 void DocumentThreadableLoader::cancel() |
386 { | 374 { |
387 cancelWithError(ResourceError()); | 375 cancelWithError(ResourceError()); |
388 // |this| may be dead here. | |
389 } | 376 } |
390 | 377 |
391 void DocumentThreadableLoader::cancelWithError(const ResourceError& error) | 378 void DocumentThreadableLoader::cancelWithError(const ResourceError& error) |
392 { | 379 { |
393 // Cancel can re-enter and m_resource might be null here as a result. | 380 // Cancel can re-enter and m_resource might be null here as a result. |
394 if (!m_client || !resource()) { | 381 if (!m_client || !resource()) { |
395 clear(); | 382 clear(); |
396 return; | 383 return; |
397 } | 384 } |
398 | 385 |
399 ResourceError errorForCallback = error; | 386 ResourceError errorForCallback = error; |
400 if (errorForCallback.isNull()) { | 387 if (errorForCallback.isNull()) { |
401 // FIXME: This error is sent to the client in didFail(), so it should no t be an internal one. Use FrameLoaderClient::cancelledError() instead. | 388 // FIXME: This error is sent to the client in didFail(), so it should no t be an internal one. Use FrameLoaderClient::cancelledError() instead. |
402 errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resource() ->url().getString(), "Load cancelled"); | 389 errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resource() ->url().getString(), "Load cancelled"); |
403 errorForCallback.setIsCancellation(true); | 390 errorForCallback.setIsCancellation(true); |
404 } | 391 } |
405 | 392 |
406 ThreadableLoaderClient* client = m_client; | 393 ThreadableLoaderClient* client = m_client; |
407 clear(); | 394 clear(); |
408 client->didFail(errorForCallback); | 395 client->didFail(errorForCallback); |
409 // |this| may be dead here in async mode. | |
410 } | 396 } |
411 | 397 |
412 void DocumentThreadableLoader::setDefersLoading(bool value) | 398 void DocumentThreadableLoader::setDefersLoading(bool value) |
413 { | 399 { |
414 if (resource()) | 400 if (resource()) |
415 resource()->setDefersLoading(value); | 401 resource()->setDefersLoading(value); |
416 } | 402 } |
417 | 403 |
418 void DocumentThreadableLoader::clear() | 404 void DocumentThreadableLoader::clear() |
419 { | 405 { |
(...skipping 12 matching lines...) Expand all Loading... | |
432 void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ est& request, const ResourceResponse& redirectResponse) | 418 void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ est& request, const ResourceResponse& redirectResponse) |
433 { | 419 { |
434 ASSERT(m_client); | 420 ASSERT(m_client); |
435 ASSERT_UNUSED(resource, resource == this->resource()); | 421 ASSERT_UNUSED(resource, resource == this->resource()); |
436 ASSERT(m_async); | 422 ASSERT(m_async); |
437 | 423 |
438 if (!m_actualRequest.isNull()) { | 424 if (!m_actualRequest.isNull()) { |
439 reportResponseReceived(resource->identifier(), redirectResponse); | 425 reportResponseReceived(resource->identifier(), redirectResponse); |
440 | 426 |
441 handlePreflightFailure(redirectResponse.url().getString(), "Response for preflight is invalid (redirect)"); | 427 handlePreflightFailure(redirectResponse.url().getString(), "Response for preflight is invalid (redirect)"); |
442 // |this| may be dead here. | |
443 | 428 |
444 request = ResourceRequest(); | 429 request = ResourceRequest(); |
445 | 430 |
446 return; | 431 return; |
447 } | 432 } |
448 | 433 |
449 if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) { | 434 if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) { |
450 // Keep |this| alive even if the client release a reference in | 435 // Keep |this| alive even if the client release a reference in |
451 // responseReceived(). | 436 // responseReceived(). |
452 WeakPtr<DocumentThreadableLoader> self(m_weakFactory.createWeakPtr()); | 437 WeakPtr<DocumentThreadableLoader> self(m_weakFactory.createWeakPtr()); |
(...skipping 22 matching lines...) Expand all Loading... | |
475 | 460 |
476 request = ResourceRequest(); | 461 request = ResourceRequest(); |
477 | 462 |
478 return; | 463 return; |
479 } | 464 } |
480 | 465 |
481 if (m_redirectMode == WebURLRequest::FetchRedirectModeError) { | 466 if (m_redirectMode == WebURLRequest::FetchRedirectModeError) { |
482 ThreadableLoaderClient* client = m_client; | 467 ThreadableLoaderClient* client = m_client; |
483 clear(); | 468 clear(); |
484 client->didFailRedirectCheck(); | 469 client->didFailRedirectCheck(); |
485 // |this| may be dead here. | |
486 | 470 |
487 request = ResourceRequest(); | 471 request = ResourceRequest(); |
488 | 472 |
489 return; | 473 return; |
490 } | 474 } |
491 | 475 |
492 // Allow same origin requests to continue after allowing clients to audit th e redirect. | 476 // Allow same origin requests to continue after allowing clients to audit th e redirect. |
493 if (isAllowedRedirect(request.url())) { | 477 if (isAllowedRedirect(request.url())) { |
494 if (m_client->isDocumentThreadableLoaderClient()) | 478 if (m_client->isDocumentThreadableLoaderClient()) |
495 static_cast<DocumentThreadableLoaderClient*>(m_client)->willFollowRe direct(request, redirectResponse); | 479 static_cast<DocumentThreadableLoaderClient*>(m_client)->willFollowRe direct(request, redirectResponse); |
496 return; | 480 return; |
497 } | 481 } |
498 | 482 |
499 if (m_corsRedirectLimit <= 0) { | 483 if (m_corsRedirectLimit <= 0) { |
500 ThreadableLoaderClient* client = m_client; | 484 ThreadableLoaderClient* client = m_client; |
501 clear(); | 485 clear(); |
502 client->didFailRedirectCheck(); | 486 client->didFailRedirectCheck(); |
503 // |this| may be dead here. | |
504 } else if (m_options.crossOriginRequestPolicy == UseAccessControl) { | 487 } else if (m_options.crossOriginRequestPolicy == UseAccessControl) { |
505 --m_corsRedirectLimit; | 488 --m_corsRedirectLimit; |
506 | 489 |
507 InspectorInstrumentation::didReceiveCORSRedirectResponse(document().fram e(), resource->identifier(), document().frame()->loader().documentLoader(), redi rectResponse, resource); | 490 InspectorInstrumentation::didReceiveCORSRedirectResponse(document().fram e(), resource->identifier(), document().frame()->loader().documentLoader(), redi rectResponse, resource); |
508 | 491 |
509 bool allowRedirect = false; | 492 bool allowRedirect = false; |
510 String accessControlErrorDescription; | 493 String accessControlErrorDescription; |
511 | 494 |
512 // Non-simple cross origin requests (both preflight and actual one) are | 495 // Non-simple cross origin requests (both preflight and actual one) are |
513 // not allowed to follow redirect. | 496 // not allowed to follow redirect. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 m_referrerAfterRedirect = Referrer(request.httpReferrer(), request.g etReferrerPolicy()); | 528 m_referrerAfterRedirect = Referrer(request.httpReferrer(), request.g etReferrerPolicy()); |
546 | 529 |
547 // Remove any headers that may have been added by the network layer that cause access control to fail. | 530 // Remove any headers that may have been added by the network layer that cause access control to fail. |
548 request.clearHTTPReferrer(); | 531 request.clearHTTPReferrer(); |
549 request.clearHTTPOrigin(); | 532 request.clearHTTPOrigin(); |
550 request.clearHTTPUserAgent(); | 533 request.clearHTTPUserAgent(); |
551 // Add any CORS simple request headers which we previously saved fro m the original request. | 534 // Add any CORS simple request headers which we previously saved fro m the original request. |
552 for (const auto& header : m_simpleRequestHeaders) | 535 for (const auto& header : m_simpleRequestHeaders) |
553 request.setHTTPHeaderField(header.key, header.value); | 536 request.setHTTPHeaderField(header.key, header.value); |
554 makeCrossOriginAccessRequest(request); | 537 makeCrossOriginAccessRequest(request); |
555 // |this| may be dead here. | |
556 return; | 538 return; |
557 } | 539 } |
558 | 540 |
559 ThreadableLoaderClient* client = m_client; | 541 ThreadableLoaderClient* client = m_client; |
560 clear(); | 542 clear(); |
561 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, redirectResponse.url().getString(), accessControlErrorDescription)); | 543 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal , 0, redirectResponse.url().getString(), accessControlErrorDescription)); |
562 // |this| may be dead here. | |
563 } else { | 544 } else { |
564 ThreadableLoaderClient* client = m_client; | 545 ThreadableLoaderClient* client = m_client; |
565 clear(); | 546 clear(); |
566 client->didFailRedirectCheck(); | 547 client->didFailRedirectCheck(); |
567 // |this| may be dead here. | |
568 } | 548 } |
569 | 549 |
570 request = ResourceRequest(); | 550 request = ResourceRequest(); |
571 } | 551 } |
572 | 552 |
573 void DocumentThreadableLoader::redirectBlocked() | 553 void DocumentThreadableLoader::redirectBlocked() |
574 { | 554 { |
575 // Tells the client that a redirect was received but not followed (for an un known reason). | 555 // Tells the client that a redirect was received but not followed (for an un known reason). |
576 ThreadableLoaderClient* client = m_client; | 556 ThreadableLoaderClient* client = m_client; |
577 clear(); | 557 clear(); |
578 client->didFailRedirectCheck(); | 558 client->didFailRedirectCheck(); |
579 // |this| may be dead here | |
580 } | 559 } |
581 | 560 |
582 void DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long b ytesSent, unsigned long long totalBytesToBeSent) | 561 void DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long b ytesSent, unsigned long long totalBytesToBeSent) |
583 { | 562 { |
584 ASSERT(m_client); | 563 ASSERT(m_client); |
585 ASSERT_UNUSED(resource, resource == this->resource()); | 564 ASSERT_UNUSED(resource, resource == this->resource()); |
586 ASSERT(m_async); | 565 ASSERT(m_async); |
587 | 566 |
588 m_client->didSendData(bytesSent, totalBytesToBeSent); | 567 m_client->didSendData(bytesSent, totalBytesToBeSent); |
589 // |this| may be dead here. | |
590 } | 568 } |
591 | 569 |
592 void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength ) | 570 void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength ) |
593 { | 571 { |
594 ASSERT(m_client); | 572 ASSERT(m_client); |
595 ASSERT_UNUSED(resource, resource == this->resource()); | 573 ASSERT_UNUSED(resource, resource == this->resource()); |
596 ASSERT(m_actualRequest.isNull()); | 574 ASSERT(m_actualRequest.isNull()); |
597 ASSERT(m_async); | 575 ASSERT(m_async); |
598 | 576 |
599 m_client->didDownloadData(dataLength); | 577 m_client->didDownloadData(dataLength); |
600 // |this| may be dead here. | |
601 } | 578 } |
602 | 579 |
603 void DocumentThreadableLoader::didReceiveResourceTiming(Resource* resource, cons t ResourceTimingInfo& info) | 580 void DocumentThreadableLoader::didReceiveResourceTiming(Resource* resource, cons t ResourceTimingInfo& info) |
604 { | 581 { |
605 ASSERT(m_client); | 582 ASSERT(m_client); |
606 ASSERT_UNUSED(resource, resource == this->resource()); | 583 ASSERT_UNUSED(resource, resource == this->resource()); |
607 ASSERT(m_async); | 584 ASSERT(m_async); |
608 | 585 |
609 m_client->didReceiveResourceTiming(info); | 586 m_client->didReceiveResourceTiming(info); |
610 // |this| may be dead here. | |
611 } | 587 } |
612 | 588 |
613 void DocumentThreadableLoader::responseReceived(Resource* resource, const Resour ceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) | 589 void DocumentThreadableLoader::responseReceived(Resource* resource, const Resour ceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) |
614 { | 590 { |
615 ASSERT_UNUSED(resource, resource == this->resource()); | 591 ASSERT_UNUSED(resource, resource == this->resource()); |
616 ASSERT(m_async); | 592 ASSERT(m_async); |
617 | 593 |
618 if (handle) | 594 if (handle) |
619 m_isUsingDataConsumerHandle = true; | 595 m_isUsingDataConsumerHandle = true; |
620 | 596 |
621 handleResponse(resource->identifier(), response, std::move(handle)); | 597 handleResponse(resource->identifier(), response, std::move(handle)); |
622 // |this| may be dead here. | |
623 } | 598 } |
624 | 599 |
625 void DocumentThreadableLoader::handlePreflightResponse(const ResourceResponse& r esponse) | 600 void DocumentThreadableLoader::handlePreflightResponse(const ResourceResponse& r esponse) |
626 { | 601 { |
627 String accessControlErrorDescription; | 602 String accessControlErrorDescription; |
628 | 603 |
629 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), getSecu rityOrigin(), accessControlErrorDescription, m_requestContext)) { | 604 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), getSecu rityOrigin(), accessControlErrorDescription, m_requestContext)) { |
630 handlePreflightFailure(response.url().getString(), "Response to prefligh t request doesn't pass access control check: " + accessControlErrorDescription); | 605 handlePreflightFailure(response.url().getString(), "Response to prefligh t request doesn't pass access control check: " + accessControlErrorDescription); |
631 // |this| may be dead here in async mode. | |
632 return; | 606 return; |
633 } | 607 } |
634 | 608 |
635 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { | 609 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { |
636 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription); | 610 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription); |
637 // |this| may be dead here in async mode. | |
638 return; | 611 return; |
639 } | 612 } |
640 | 613 |
641 if (m_actualRequest.isExternalRequest() && !passesExternalPreflightCheck(res ponse, accessControlErrorDescription)) { | 614 if (m_actualRequest.isExternalRequest() && !passesExternalPreflightCheck(res ponse, accessControlErrorDescription)) { |
642 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription); | 615 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription); |
643 // |this| may be dead here in async mode. | |
644 return; | 616 return; |
645 } | 617 } |
646 | 618 |
647 std::unique_ptr<CrossOriginPreflightResultCacheItem> preflightResult = wrapU nique(new CrossOriginPreflightResultCacheItem(effectiveAllowCredentials())); | 619 std::unique_ptr<CrossOriginPreflightResultCacheItem> preflightResult = wrapU nique(new CrossOriginPreflightResultCacheItem(effectiveAllowCredentials())); |
648 if (!preflightResult->parse(response, accessControlErrorDescription) | 620 if (!preflightResult->parse(response, accessControlErrorDescription) |
649 || !preflightResult->allowsCrossOriginMethod(m_actualRequest.httpMethod( ), accessControlErrorDescription) | 621 || !preflightResult->allowsCrossOriginMethod(m_actualRequest.httpMethod( ), accessControlErrorDescription) |
650 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest.httpHeader Fields(), accessControlErrorDescription)) { | 622 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest.httpHeader Fields(), accessControlErrorDescription)) { |
651 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription); | 623 handlePreflightFailure(response.url().getString(), accessControlErrorDes cription); |
652 // |this| may be dead here in async mode. | |
653 return; | 624 return; |
654 } | 625 } |
655 | 626 |
656 CrossOriginPreflightResultCache::shared().appendEntry(getSecurityOrigin()->t oString(), m_actualRequest.url(), std::move(preflightResult)); | 627 CrossOriginPreflightResultCache::shared().appendEntry(getSecurityOrigin()->t oString(), m_actualRequest.url(), std::move(preflightResult)); |
657 } | 628 } |
658 | 629 |
659 void DocumentThreadableLoader::reportResponseReceived(unsigned long identifier, const ResourceResponse& response) | 630 void DocumentThreadableLoader::reportResponseReceived(unsigned long identifier, const ResourceResponse& response) |
660 { | 631 { |
661 LocalFrame* frame = document().frame(); | 632 LocalFrame* frame = document().frame(); |
662 // We are seeing crashes caused by nullptr (crbug.com/578849). But the frame | 633 // We are seeing crashes caused by nullptr (crbug.com/578849). But the frame |
663 // must be set here. TODO(horo): Find the root cause of the unset frame. | 634 // must be set here. TODO(horo): Find the root cause of the unset frame. |
664 ASSERT(frame); | 635 ASSERT(frame); |
665 if (!frame) | 636 if (!frame) |
666 return; | 637 return; |
667 DocumentLoader* loader = frame->loader().documentLoader(); | 638 DocumentLoader* loader = frame->loader().documentLoader(); |
668 TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceReceiveResponse", TRACE_E VENT_SCOPE_THREAD, "data", InspectorReceiveResponseEvent::data(identifier, frame , response)); | 639 TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceReceiveResponse", TRACE_E VENT_SCOPE_THREAD, "data", InspectorReceiveResponseEvent::data(identifier, frame , response)); |
669 InspectorInstrumentation::didReceiveResourceResponse(frame, identifier, load er, response, resource()); | 640 InspectorInstrumentation::didReceiveResourceResponse(frame, identifier, load er, response, resource()); |
670 frame->console().reportResourceResponseReceived(loader, identifier, response ); | 641 frame->console().reportResourceResponseReceived(loader, identifier, response ); |
671 } | 642 } |
672 | 643 |
673 void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re sourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) | 644 void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re sourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) |
674 { | 645 { |
675 ASSERT(m_client); | 646 ASSERT(m_client); |
676 | 647 |
677 if (!m_actualRequest.isNull()) { | 648 if (!m_actualRequest.isNull()) { |
678 reportResponseReceived(identifier, response); | 649 reportResponseReceived(identifier, response); |
679 handlePreflightResponse(response); | 650 handlePreflightResponse(response); |
680 // |this| may be dead here in async mode. | |
681 return; | 651 return; |
682 } | 652 } |
683 | 653 |
684 if (response.wasFetchedViaServiceWorker()) { | 654 if (response.wasFetchedViaServiceWorker()) { |
685 if (response.wasFallbackRequiredByServiceWorker()) { | 655 if (response.wasFallbackRequiredByServiceWorker()) { |
686 // At this point we must have m_fallbackRequestForServiceWorker. | 656 // At this point we must have m_fallbackRequestForServiceWorker. |
687 // (For SharedWorker the request won't be CORS or CORS-with-prefligh t, | 657 // (For SharedWorker the request won't be CORS or CORS-with-prefligh t, |
688 // therefore fallback-to-network is handled in the browser process | 658 // therefore fallback-to-network is handled in the browser process |
689 // when the ServiceWorker does not call respondWith().) | 659 // when the ServiceWorker does not call respondWith().) |
690 ASSERT(!m_fallbackRequestForServiceWorker.isNull()); | 660 ASSERT(!m_fallbackRequestForServiceWorker.isNull()); |
691 reportResponseReceived(identifier, response); | 661 reportResponseReceived(identifier, response); |
692 loadFallbackRequestForServiceWorker(); | 662 loadFallbackRequestForServiceWorker(); |
693 // |this| may be dead here in async mode. | |
694 return; | 663 return; |
695 } | 664 } |
696 m_fallbackRequestForServiceWorker = ResourceRequest(); | 665 m_fallbackRequestForServiceWorker = ResourceRequest(); |
697 m_client->didReceiveResponse(identifier, response, std::move(handle)); | 666 m_client->didReceiveResponse(identifier, response, std::move(handle)); |
698 return; | 667 return; |
699 } | 668 } |
700 | 669 |
701 // Even if the request met the conditions to get handled by a Service Worker | 670 // Even if the request met the conditions to get handled by a Service Worker |
702 // in the constructor of this class (and therefore | 671 // in the constructor of this class (and therefore |
703 // |m_fallbackRequestForServiceWorker| is set), the Service Worker may skip | 672 // |m_fallbackRequestForServiceWorker| is set), the Service Worker may skip |
704 // processing the request. Only if the request is same origin, the skipped | 673 // processing the request. Only if the request is same origin, the skipped |
705 // response may come here (wasFetchedViaServiceWorker() returns false) since | 674 // response may come here (wasFetchedViaServiceWorker() returns false) since |
706 // such a request doesn't have to go through the CORS algorithm by calling | 675 // such a request doesn't have to go through the CORS algorithm by calling |
707 // loadFallbackRequestForServiceWorker(). | 676 // loadFallbackRequestForServiceWorker(). |
708 // FIXME: We should use |m_sameOriginRequest| when we will support | 677 // FIXME: We should use |m_sameOriginRequest| when we will support |
709 // Suborigins (crbug.com/336894) for Service Worker. | 678 // Suborigins (crbug.com/336894) for Service Worker. |
710 ASSERT(m_fallbackRequestForServiceWorker.isNull() || getSecurityOrigin()->ca nRequest(m_fallbackRequestForServiceWorker.url())); | 679 ASSERT(m_fallbackRequestForServiceWorker.isNull() || getSecurityOrigin()->ca nRequest(m_fallbackRequestForServiceWorker.url())); |
711 m_fallbackRequestForServiceWorker = ResourceRequest(); | 680 m_fallbackRequestForServiceWorker = ResourceRequest(); |
712 | 681 |
713 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC ontrol) { | 682 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC ontrol) { |
714 String accessControlErrorDescription; | 683 String accessControlErrorDescription; |
715 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), get SecurityOrigin(), accessControlErrorDescription, m_requestContext)) { | 684 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), get SecurityOrigin(), accessControlErrorDescription, m_requestContext)) { |
716 reportResponseReceived(identifier, response); | 685 reportResponseReceived(identifier, response); |
717 | 686 |
718 ThreadableLoaderClient* client = m_client; | 687 ThreadableLoaderClient* client = m_client; |
719 clear(); | 688 clear(); |
720 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInte rnal, 0, response.url().getString(), accessControlErrorDescription)); | 689 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInte rnal, 0, response.url().getString(), accessControlErrorDescription)); |
721 // |this| may be dead here. | |
722 return; | 690 return; |
723 } | 691 } |
724 } | 692 } |
725 | 693 |
726 m_client->didReceiveResponse(identifier, response, std::move(handle)); | 694 m_client->didReceiveResponse(identifier, response, std::move(handle)); |
727 } | 695 } |
728 | 696 |
729 void DocumentThreadableLoader::setSerializedCachedMetadata(Resource*, const char * data, size_t size) | 697 void DocumentThreadableLoader::setSerializedCachedMetadata(Resource*, const char * data, size_t size) |
730 { | 698 { |
731 if (!m_actualRequest.isNull()) | 699 if (!m_actualRequest.isNull()) |
732 return; | 700 return; |
733 m_client->didReceiveCachedMetadata(data, size); | 701 m_client->didReceiveCachedMetadata(data, size); |
734 // |this| may be dead here. | |
735 } | 702 } |
736 | 703 |
737 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data , size_t dataLength) | 704 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data , size_t dataLength) |
738 { | 705 { |
739 ASSERT_UNUSED(resource, resource == this->resource()); | 706 ASSERT_UNUSED(resource, resource == this->resource()); |
740 ASSERT(m_async); | 707 ASSERT(m_async); |
741 | 708 |
742 if (m_isUsingDataConsumerHandle) | 709 if (m_isUsingDataConsumerHandle) |
743 return; | 710 return; |
744 | 711 |
745 // TODO(junov): Fix the ThreadableLoader ecosystem to use size_t. | 712 // TODO(junov): Fix the ThreadableLoader ecosystem to use size_t. |
746 // Until then, we use safeCast to trap potential overflows. | 713 // Until then, we use safeCast to trap potential overflows. |
747 handleReceivedData(data, safeCast<unsigned>(dataLength)); | 714 handleReceivedData(data, safeCast<unsigned>(dataLength)); |
748 // |this| may be dead here. | |
749 } | 715 } |
750 | 716 |
751 void DocumentThreadableLoader::handleReceivedData(const char* data, size_t dataL ength) | 717 void DocumentThreadableLoader::handleReceivedData(const char* data, size_t dataL ength) |
752 { | 718 { |
753 ASSERT(m_client); | 719 ASSERT(m_client); |
754 | 720 |
755 // Preflight data should be invisible to clients. | 721 // Preflight data should be invisible to clients. |
756 if (!m_actualRequest.isNull()) | 722 if (!m_actualRequest.isNull()) |
757 return; | 723 return; |
758 | 724 |
759 ASSERT(m_fallbackRequestForServiceWorker.isNull()); | 725 ASSERT(m_fallbackRequestForServiceWorker.isNull()); |
760 | 726 |
761 m_client->didReceiveData(data, dataLength); | 727 m_client->didReceiveData(data, dataLength); |
762 // |this| may be dead here in async mode. | |
763 } | 728 } |
764 | 729 |
765 void DocumentThreadableLoader::notifyFinished(Resource* resource) | 730 void DocumentThreadableLoader::notifyFinished(Resource* resource) |
766 { | 731 { |
767 ASSERT(m_client); | 732 ASSERT(m_client); |
768 ASSERT(resource == this->resource()); | 733 ASSERT(resource == this->resource()); |
769 ASSERT(m_async); | 734 ASSERT(m_async); |
770 | 735 |
771 if (resource->errorOccurred()) { | 736 if (resource->errorOccurred()) { |
772 handleError(resource->resourceError()); | 737 handleError(resource->resourceError()); |
773 // |this| may be dead here. | |
774 } else { | 738 } else { |
775 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); | 739 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); |
776 // |this| may be dead here. | |
777 } | 740 } |
778 } | 741 } |
779 | 742 |
780 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) | 743 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) |
781 { | 744 { |
782 ASSERT(m_fallbackRequestForServiceWorker.isNull()); | 745 ASSERT(m_fallbackRequestForServiceWorker.isNull()); |
783 | 746 |
784 if (!m_actualRequest.isNull()) { | 747 if (!m_actualRequest.isNull()) { |
785 // FIXME: Timeout should be applied to whole fetch, not for each of | 748 // FIXME: Timeout should be applied to whole fetch, not for each of |
786 // preflight and actual request. | 749 // preflight and actual request. |
787 m_timeoutTimer.stop(); | 750 m_timeoutTimer.stop(); |
788 ASSERT(!m_sameOriginRequest); | 751 ASSERT(!m_sameOriginRequest); |
789 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 752 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
790 loadActualRequest(); | 753 loadActualRequest(); |
791 // |this| may be dead here in async mode. | |
792 return; | 754 return; |
793 } | 755 } |
794 | 756 |
795 ThreadableLoaderClient* client = m_client; | 757 ThreadableLoaderClient* client = m_client; |
796 // Protect the resource in |didFinishLoading| in order not to release the | 758 // Protect the resource in |didFinishLoading| in order not to release the |
797 // downloaded file. | 759 // downloaded file. |
798 Persistent<Resource> resource = m_resource; | 760 Persistent<Resource> protect = resource(); |
799 clear(); | 761 clear(); |
800 client->didFinishLoading(identifier, finishTime); | 762 client->didFinishLoading(identifier, finishTime); |
801 // |this| may be dead here in async mode. | |
802 } | 763 } |
803 | 764 |
804 void DocumentThreadableLoader::didTimeout(TimerBase* timer) | 765 void DocumentThreadableLoader::didTimeout(TimerBase* timer) |
805 { | 766 { |
806 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); | 767 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); |
807 | 768 |
808 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, | 769 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, |
809 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. | 770 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. |
810 static const int timeoutError = -7; | 771 static const int timeoutError = -7; |
811 ResourceError error("net", timeoutError, resource()->url(), String()); | 772 ResourceError error("net", timeoutError, resource()->url(), String()); |
812 error.setIsTimeout(true); | 773 error.setIsTimeout(true); |
813 cancelWithError(error); | 774 cancelWithError(error); |
814 // |this| may be dead here. | |
815 } | 775 } |
816 | 776 |
817 void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() | 777 void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() |
818 { | 778 { |
819 clearResource(); | 779 clearResource(); |
820 ResourceRequest fallbackRequest(m_fallbackRequestForServiceWorker); | 780 ResourceRequest fallbackRequest(m_fallbackRequestForServiceWorker); |
821 m_fallbackRequestForServiceWorker = ResourceRequest(); | 781 m_fallbackRequestForServiceWorker = ResourceRequest(); |
822 dispatchInitialRequest(fallbackRequest); | 782 dispatchInitialRequest(fallbackRequest); |
823 // |this| may be dead here in async mode. | |
824 } | 783 } |
825 | 784 |
826 void DocumentThreadableLoader::loadActualRequest() | 785 void DocumentThreadableLoader::loadActualRequest() |
827 { | 786 { |
828 ResourceRequest actualRequest = m_actualRequest; | 787 ResourceRequest actualRequest = m_actualRequest; |
829 ResourceLoaderOptions actualOptions = m_actualOptions; | 788 ResourceLoaderOptions actualOptions = m_actualOptions; |
830 m_actualRequest = ResourceRequest(); | 789 m_actualRequest = ResourceRequest(); |
831 m_actualOptions = ResourceLoaderOptions(); | 790 m_actualOptions = ResourceLoaderOptions(); |
832 | 791 |
833 actualRequest.setHTTPOrigin(getSecurityOrigin()); | 792 actualRequest.setHTTPOrigin(getSecurityOrigin()); |
834 | 793 |
835 clearResource(); | 794 clearResource(); |
836 | 795 |
837 // Explicitly set the SkipServiceWorker flag here. Even if the page was not | 796 // Explicitly set the SkipServiceWorker flag here. Even if the page was not |
838 // controlled by a SW when the preflight request was sent, a new SW may be | 797 // controlled by a SW when the preflight request was sent, a new SW may be |
839 // controlling the page now by calling clients.claim(). We should not send | 798 // controlling the page now by calling clients.claim(). We should not send |
840 // the actual request to the SW. https://crbug.com/604583 | 799 // the actual request to the SW. https://crbug.com/604583 |
841 actualRequest.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); | 800 actualRequest.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); |
842 | 801 |
843 loadRequest(actualRequest, actualOptions); | 802 loadRequest(actualRequest, actualOptions); |
844 // |this| may be dead here in async mode. | |
845 } | 803 } |
846 | 804 |
847 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) | 805 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) |
848 { | 806 { |
849 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); | 807 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); |
850 | 808 |
851 // Prevent handleSuccessfulFinish() from bypassing access check. | 809 // Prevent handleSuccessfulFinish() from bypassing access check. |
852 m_actualRequest = ResourceRequest(); | 810 m_actualRequest = ResourceRequest(); |
853 | 811 |
854 ThreadableLoaderClient* client = m_client; | 812 ThreadableLoaderClient* client = m_client; |
855 clear(); | 813 clear(); |
856 client->didFailAccessControlCheck(error); | 814 client->didFailAccessControlCheck(error); |
857 // |this| may be dead here in async mode. | |
858 } | 815 } |
859 | 816 |
860 void DocumentThreadableLoader::handleError(const ResourceError& error) | 817 void DocumentThreadableLoader::handleError(const ResourceError& error) |
861 { | 818 { |
862 // Copy the ResourceError instance to make it sure that the passed | 819 // Copy the ResourceError instance to make it sure that the passed |
863 // ResourceError is alive during didFail() even when the Resource is | 820 // ResourceError is alive during didFail() even when the Resource is |
864 // destructed during didFail(). | 821 // destructed during didFail(). |
865 ResourceError copiedError = error; | 822 ResourceError copiedError = error; |
866 | 823 |
867 ThreadableLoaderClient* client = m_client; | 824 ThreadableLoaderClient* client = m_client; |
868 clear(); | 825 clear(); |
869 client->didFail(copiedError); | 826 client->didFail(copiedError); |
870 // |this| may be dead here. | |
871 } | 827 } |
872 | 828 |
873 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) | 829 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) |
874 { | 830 { |
875 // Any credential should have been removed from the cross-site requests. | 831 // Any credential should have been removed from the cross-site requests. |
876 const KURL& requestURL = request.url(); | 832 const KURL& requestURL = request.url(); |
877 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); | 833 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); |
878 ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); | 834 ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty()); |
879 | 835 |
880 // Update resourceLoaderOptions with enforced values. | 836 // Update resourceLoaderOptions with enforced values. |
(...skipping 15 matching lines...) Expand all Loading... | |
896 WeakPtr<DocumentThreadableLoader> self(m_weakFactory.createWeakPtr()); | 852 WeakPtr<DocumentThreadableLoader> self(m_weakFactory.createWeakPtr()); |
897 | 853 |
898 if (request.requestContext() == WebURLRequest::RequestContextVideo || re quest.requestContext() == WebURLRequest::RequestContextAudio) | 854 if (request.requestContext() == WebURLRequest::RequestContextVideo || re quest.requestContext() == WebURLRequest::RequestContextAudio) |
899 setResource(RawResource::fetchMedia(newRequest, document().fetcher() )); | 855 setResource(RawResource::fetchMedia(newRequest, document().fetcher() )); |
900 else if (request.requestContext() == WebURLRequest::RequestContextManife st) | 856 else if (request.requestContext() == WebURLRequest::RequestContextManife st) |
901 setResource(RawResource::fetchManifest(newRequest, document().fetche r())); | 857 setResource(RawResource::fetchManifest(newRequest, document().fetche r())); |
902 else | 858 else |
903 setResource(RawResource::fetch(newRequest, document().fetcher())); | 859 setResource(RawResource::fetch(newRequest, document().fetcher())); |
904 | 860 |
905 // setResource() might call notifyFinished() synchronously, and thus | 861 // setResource() might call notifyFinished() synchronously, and thus |
906 // clear() might be called and |this| may be dead here. | |
907 if (!self) | 862 if (!self) |
908 return; | 863 return; |
909 | 864 |
910 if (!resource()) { | 865 if (!resource()) { |
911 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadi ngForClient(m_document, m_client); | 866 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadi ngForClient(m_document, m_client); |
912 ThreadableLoaderClient* client = m_client; | 867 ThreadableLoaderClient* client = m_client; |
913 clear(); | 868 clear(); |
914 // setResource() might call notifyFinished() and thus clear() | 869 // setResource() might call notifyFinished() and thus clear() |
915 // synchronously, and in such cases ThreadableLoaderClient is | 870 // synchronously, and in such cases ThreadableLoaderClient is |
916 // already notified and |client| is null. | 871 // already notified and |client| is null. |
917 if (!client) | 872 if (!client) |
918 return; | 873 return; |
919 client->didFail(ResourceError(errorDomainBlinkInternal, 0, requestUR L.getString(), "Failed to start loading.")); | 874 client->didFail(ResourceError(errorDomainBlinkInternal, 0, requestUR L.getString(), "Failed to start loading.")); |
920 // |this| may be dead here. | |
921 return; | 875 return; |
922 } | 876 } |
923 | 877 |
924 if (resource()->loader()) { | 878 if (resource()->loader()) { |
925 unsigned long identifier = resource()->identifier(); | 879 unsigned long identifier = resource()->identifier(); |
926 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForC lient(m_document, identifier, m_client); | 880 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForC lient(m_document, identifier, m_client); |
927 } else { | 881 } else { |
928 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadi ngForClient(m_document, m_client); | 882 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadi ngForClient(m_document, m_client); |
929 } | 883 } |
930 return; | 884 return; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1005 { | 959 { |
1006 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri gin(); | 960 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri gin(); |
1007 } | 961 } |
1008 | 962 |
1009 Document& DocumentThreadableLoader::document() const | 963 Document& DocumentThreadableLoader::document() const |
1010 { | 964 { |
1011 ASSERT(m_document); | 965 ASSERT(m_document); |
1012 return *m_document; | 966 return *m_document; |
1013 } | 967 } |
1014 | 968 |
969 DEFINE_TRACE(DocumentThreadableLoader) | |
970 { | |
971 visitor->trace(m_resource); | |
972 visitor->trace(m_document); | |
973 ThreadableLoader::trace(visitor); | |
974 } | |
975 | |
1015 } // namespace blink | 976 } // namespace blink |
OLD | NEW |