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

Side by Side Diff: third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp

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

Powered by Google App Engine
This is Rietveld 408576698