| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 return true; | 114 return true; |
| 115 case WebURLRequest::RequestContextPlugin: | 115 case WebURLRequest::RequestContextPlugin: |
| 116 return skipServiceWorker == WebURLRequest::SkipServiceWorker::All; | 116 return skipServiceWorker == WebURLRequest::SkipServiceWorker::All; |
| 117 default: | 117 default: |
| 118 return false; | 118 return false; |
| 119 } | 119 } |
| 120 } | 120 } |
| 121 | 121 |
| 122 } // namespace | 122 } // namespace |
| 123 | 123 |
| 124 // Max number of CORS redirects handled in DocumentThreadableLoader. | 124 // Max number of CORS redirects handled in DocumentThreadableLoader. Same number |
| 125 // Same number as net/url_request/url_request.cc, and | 125 // as net/url_request/url_request.cc, and same number as |
| 126 // same number as https://fetch.spec.whatwg.org/#concept-http-fetch, Step 4. | 126 // https://fetch.spec.whatwg.org/#concept-http-fetch, Step 4. |
| 127 // FIXME: currently the number of redirects is counted and limited here and in | 127 // FIXME: currently the number of redirects is counted and limited here and in |
| 128 // net/url_request/url_request.cc separately. | 128 // net/url_request/url_request.cc separately. |
| 129 static const int kMaxCORSRedirects = 20; | 129 static const int kMaxCORSRedirects = 20; |
| 130 | 130 |
| 131 void DocumentThreadableLoader::loadResourceSynchronously( | 131 void DocumentThreadableLoader::loadResourceSynchronously( |
| 132 Document& document, | 132 Document& document, |
| 133 const ResourceRequest& request, | 133 const ResourceRequest& request, |
| 134 ThreadableLoaderClient& client, | 134 ThreadableLoaderClient& client, |
| 135 const ThreadableLoaderOptions& options, | 135 const ThreadableLoaderOptions& options, |
| 136 const ResourceLoaderOptions& resourceLoaderOptions) { | 136 const ResourceLoaderOptions& resourceLoaderOptions) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 ThreadableLoaderClient* client = m_client; | 192 ThreadableLoaderClient* client = m_client; |
| 193 clear(); | 193 clear(); |
| 194 client->didFail(ResourceError(errorDomainBlinkInternal, 0, | 194 client->didFail(ResourceError(errorDomainBlinkInternal, 0, |
| 195 request.url().getString(), | 195 request.url().getString(), |
| 196 "Cross origin requests are not supported.")); | 196 "Cross origin requests are not supported.")); |
| 197 return; | 197 return; |
| 198 } | 198 } |
| 199 | 199 |
| 200 m_requestStartedSeconds = monotonicallyIncreasingTime(); | 200 m_requestStartedSeconds = monotonicallyIncreasingTime(); |
| 201 | 201 |
| 202 // Save any CORS simple headers on the request here. If this request redirects
cross-origin, we cancel the old request | 202 // Save any CORS simple headers on the request here. If this request redirects |
| 203 // create a new one, and copy these headers. | 203 // cross-origin, we cancel the old request create a new one, and copy these |
| 204 // headers. |
| 204 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); | 205 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); |
| 205 for (const auto& header : headerMap) { | 206 for (const auto& header : headerMap) { |
| 206 if (FetchUtils::isSimpleHeader(header.key, header.value)) { | 207 if (FetchUtils::isSimpleHeader(header.key, header.value)) { |
| 207 m_simpleRequestHeaders.add(header.key, header.value); | 208 m_simpleRequestHeaders.add(header.key, header.value); |
| 208 } else if (equalIgnoringCase(header.key, HTTPNames::Range) && | 209 } else if (equalIgnoringCase(header.key, HTTPNames::Range) && |
| 209 m_options.crossOriginRequestPolicy == UseAccessControl && | 210 m_options.crossOriginRequestPolicy == UseAccessControl && |
| 210 m_options.preflightPolicy == PreventPreflight) { | 211 m_options.preflightPolicy == PreventPreflight) { |
| 211 // Allow an exception for the "range" header for when CORS callers request
no preflight, this ensures cross-origin | 212 // Allow an exception for the "range" header for when CORS callers request |
| 212 // redirects work correctly for crossOrigin enabled WebURLRequest::Request
ContextVideo type requests. | 213 // no preflight, this ensures cross-origin redirects work correctly for |
| 214 // crossOrigin enabled WebURLRequest::RequestContextVideo type requests. |
| 213 m_simpleRequestHeaders.add(header.key, header.value); | 215 m_simpleRequestHeaders.add(header.key, header.value); |
| 214 } | 216 } |
| 215 } | 217 } |
| 216 | 218 |
| 217 // DocumentThreadableLoader is used by all javascript initiated fetch, so | 219 // DocumentThreadableLoader is used by all javascript initiated fetch, so we |
| 218 // we use this chance to record non-GET fetch script requests. | 220 // use this chance to record non-GET fetch script requests. However, this is |
| 219 // However, this is based on the following assumptions, so please be careful | 221 // based on the following assumptions, so please be careful when adding |
| 220 // when adding similar logic: | 222 // similar logic: |
| 221 // - ThreadableLoader is used as backend for all javascript initiated network | 223 // - ThreadableLoader is used as backend for all javascript initiated network |
| 222 // fetches. | 224 // fetches. |
| 223 // - Note that ThreadableLoader is also used for non-network fetch such as | 225 // - Note that ThreadableLoader is also used for non-network fetch such as |
| 224 // FileReaderLoader. However it emulates GET method so signal is not | 226 // FileReaderLoader. However it emulates GET method so signal is not |
| 225 // recorded here. | 227 // recorded here. |
| 226 // - ThreadableLoader w/ non-GET request is only created from javascript | 228 // - ThreadableLoader w/ non-GET request is only created from javascript |
| 227 // initiated fetch. | 229 // initiated fetch. |
| 228 // - Some non-script initiated fetches such as WorkerScriptLoader also use | 230 // - Some non-script initiated fetches such as WorkerScriptLoader also use |
| 229 // ThreadableLoader, but they are guaranteed to use GET method. | 231 // ThreadableLoader, but they are guaranteed to use GET method. |
| 230 if (request.httpMethod() != HTTPNames::GET) { | 232 if (request.httpMethod() != HTTPNames::GET) { |
| 231 if (Page* page = m_document->page()) | 233 if (Page* page = m_document->page()) |
| 232 page->chromeClient().didObserveNonGetFetchFromScript(); | 234 page->chromeClient().didObserveNonGetFetchFromScript(); |
| 233 } | 235 } |
| 234 | 236 |
| 235 ResourceRequest newRequest(request); | 237 ResourceRequest newRequest(request); |
| 236 if (m_requestContext != WebURLRequest::RequestContextFetch) { | 238 if (m_requestContext != WebURLRequest::RequestContextFetch) { |
| 237 // When the request context is not "fetch", | 239 // When the request context is not "fetch", |crossOriginRequestPolicy| |
| 238 // |crossOriginRequestPolicy| represents the fetch request mode, | 240 // represents the fetch request mode, and |credentialsRequested| represents |
| 239 // and |credentialsRequested| represents the fetch credentials mode. | 241 // the fetch credentials mode. So we set those flags here so that we can see |
| 240 // So we set those flags here so that we can see the correct request | 242 // the correct request mode and credentials mode in the service worker's |
| 241 // mode and credentials mode in the service worker's fetch event | 243 // fetch event handler. |
| 242 // handler. | |
| 243 switch (m_options.crossOriginRequestPolicy) { | 244 switch (m_options.crossOriginRequestPolicy) { |
| 244 case DenyCrossOriginRequests: | 245 case DenyCrossOriginRequests: |
| 245 newRequest.setFetchRequestMode( | 246 newRequest.setFetchRequestMode( |
| 246 WebURLRequest::FetchRequestModeSameOrigin); | 247 WebURLRequest::FetchRequestModeSameOrigin); |
| 247 break; | 248 break; |
| 248 case UseAccessControl: | 249 case UseAccessControl: |
| 249 if (m_options.preflightPolicy == ForcePreflight) | 250 if (m_options.preflightPolicy == ForcePreflight) |
| 250 newRequest.setFetchRequestMode( | 251 newRequest.setFetchRequestMode( |
| 251 WebURLRequest::FetchRequestModeCORSWithForcedPreflight); | 252 WebURLRequest::FetchRequestModeCORSWithForcedPreflight); |
| 252 else | 253 else |
| (...skipping 20 matching lines...) Expand all Loading... |
| 273 SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers( | 274 SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers( |
| 274 request.url().protocol()) && | 275 request.url().protocol()) && |
| 275 m_document->fetcher()->isControlledByServiceWorker()) { | 276 m_document->fetcher()->isControlledByServiceWorker()) { |
| 276 if (newRequest.fetchRequestMode() == WebURLRequest::FetchRequestModeCORS || | 277 if (newRequest.fetchRequestMode() == WebURLRequest::FetchRequestModeCORS || |
| 277 newRequest.fetchRequestMode() == | 278 newRequest.fetchRequestMode() == |
| 278 WebURLRequest::FetchRequestModeCORSWithForcedPreflight) { | 279 WebURLRequest::FetchRequestModeCORSWithForcedPreflight) { |
| 279 m_fallbackRequestForServiceWorker = ResourceRequest(request); | 280 m_fallbackRequestForServiceWorker = ResourceRequest(request); |
| 280 // m_fallbackRequestForServiceWorker is used when a regular controlling | 281 // m_fallbackRequestForServiceWorker is used when a regular controlling |
| 281 // service worker doesn't handle a cross origin request. When this happens | 282 // service worker doesn't handle a cross origin request. When this happens |
| 282 // we still want to give foreign fetch a chance to handle the request, so | 283 // we still want to give foreign fetch a chance to handle the request, so |
| 283 // only skip the controlling service worker for the fallback request. | 284 // only skip the controlling service worker for the fallback request. This |
| 284 // This is currently safe because of http://crbug.com/604084 the | 285 // is currently safe because of http://crbug.com/604084 the |
| 285 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch | 286 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch |
| 286 // handled a request. | 287 // handled a request. |
| 287 m_fallbackRequestForServiceWorker.setSkipServiceWorker( | 288 m_fallbackRequestForServiceWorker.setSkipServiceWorker( |
| 288 WebURLRequest::SkipServiceWorker::Controlling); | 289 WebURLRequest::SkipServiceWorker::Controlling); |
| 289 } | 290 } |
| 290 loadRequest(newRequest, m_resourceLoaderOptions); | 291 loadRequest(newRequest, m_resourceLoaderOptions); |
| 291 return; | 292 return; |
| 292 } | 293 } |
| 293 | 294 |
| 294 dispatchInitialRequest(newRequest); | 295 dispatchInitialRequest(newRequest); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 309 makeCrossOriginAccessRequest(request); | 310 makeCrossOriginAccessRequest(request); |
| 310 } | 311 } |
| 311 | 312 |
| 312 void DocumentThreadableLoader::makeCrossOriginAccessRequest( | 313 void DocumentThreadableLoader::makeCrossOriginAccessRequest( |
| 313 const ResourceRequest& request) { | 314 const ResourceRequest& request) { |
| 314 DCHECK(m_options.crossOriginRequestPolicy == UseAccessControl || | 315 DCHECK(m_options.crossOriginRequestPolicy == UseAccessControl || |
| 315 request.isExternalRequest()); | 316 request.isExternalRequest()); |
| 316 DCHECK(m_client); | 317 DCHECK(m_client); |
| 317 DCHECK(!resource()); | 318 DCHECK(!resource()); |
| 318 | 319 |
| 319 // Cross-origin requests are only allowed certain registered schemes. | 320 // Cross-origin requests are only allowed certain registered schemes. We would |
| 320 // We would catch this when checking response headers later, but there | 321 // catch this when checking response headers later, but there is no reason to |
| 321 // is no reason to send a request, preflighted or not, that's guaranteed | 322 // send a request, preflighted or not, that's guaranteed to be denied. |
| 322 // to be denied. | |
| 323 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled( | 323 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled( |
| 324 request.url().protocol())) { | 324 request.url().protocol())) { |
| 325 InspectorInstrumentation:: | 325 InspectorInstrumentation:: |
| 326 documentThreadableLoaderFailedToStartLoadingForClient(m_document, | 326 documentThreadableLoaderFailedToStartLoadingForClient(m_document, |
| 327 m_client); | 327 m_client); |
| 328 ThreadableLoaderClient* client = m_client; | 328 ThreadableLoaderClient* client = m_client; |
| 329 clear(); | 329 clear(); |
| 330 client->didFailAccessControlCheck(ResourceError( | 330 client->didFailAccessControlCheck(ResourceError( |
| 331 errorDomainBlinkInternal, 0, request.url().getString(), | 331 errorDomainBlinkInternal, 0, request.url().getString(), |
| 332 "Cross origin requests are only supported for protocol schemes: " + | 332 "Cross origin requests are only supported for protocol schemes: " + |
| 333 SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); | 333 SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); |
| 334 return; | 334 return; |
| 335 } | 335 } |
| 336 | 336 |
| 337 // Non-secure origins may not make "external requests": https://mikewest.githu
b.io/cors-rfc1918/#integration-fetch | 337 // Non-secure origins may not make "external requests": |
| 338 // https://mikewest.github.io/cors-rfc1918/#integration-fetch |
| 338 if (!document().isSecureContext() && request.isExternalRequest()) { | 339 if (!document().isSecureContext() && request.isExternalRequest()) { |
| 339 ThreadableLoaderClient* client = m_client; | 340 ThreadableLoaderClient* client = m_client; |
| 340 clear(); | 341 clear(); |
| 341 client->didFailAccessControlCheck( | 342 client->didFailAccessControlCheck( |
| 342 ResourceError(errorDomainBlinkInternal, 0, request.url().getString(), | 343 ResourceError(errorDomainBlinkInternal, 0, request.url().getString(), |
| 343 "Requests to internal network resources are not allowed " | 344 "Requests to internal network resources are not allowed " |
| 344 "from non-secure contexts (see https://goo.gl/Y0ZkNV). " | 345 "from non-secure contexts (see https://goo.gl/Y0ZkNV). " |
| 345 "This is an experimental restriction which is part of " | 346 "This is an experimental restriction which is part of " |
| 346 "'https://mikewest.github.io/cors-rfc1918/'.")); | 347 "'https://mikewest.github.io/cors-rfc1918/'.")); |
| 347 return; | 348 return; |
| 348 } | 349 } |
| 349 | 350 |
| 350 ResourceRequest crossOriginRequest(request); | 351 ResourceRequest crossOriginRequest(request); |
| 351 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); | 352 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); |
| 352 | 353 |
| 353 // We use isSimpleOrForbiddenRequest() here since |request| may have been | 354 // We use isSimpleOrForbiddenRequest() here since |request| may have been |
| 354 // modified in the process of loading (not from the user's input). For | 355 // modified in the process of loading (not from the user's input). For |
| 355 // example, referrer. We need to accept them. For security, we must reject | 356 // example, referrer. We need to accept them. For security, we must reject |
| 356 // forbidden headers/methods at the point we accept user's input. Not here. | 357 // forbidden headers/methods at the point we accept user's input. Not here. |
| 357 if (!request.isExternalRequest() && | 358 if (!request.isExternalRequest() && |
| 358 ((m_options.preflightPolicy == ConsiderPreflight && | 359 ((m_options.preflightPolicy == ConsiderPreflight && |
| 359 FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), | 360 FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), |
| 360 request.httpHeaderFields())) || | 361 request.httpHeaderFields())) || |
| 361 m_options.preflightPolicy == PreventPreflight)) { | 362 m_options.preflightPolicy == PreventPreflight)) { |
| 362 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), | 363 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), |
| 363 effectiveAllowCredentials()); | 364 effectiveAllowCredentials()); |
| 364 // We update the credentials mode according to effectiveAllowCredentials() h
ere for backward compatibility. But this is not correct. | 365 // We update the credentials mode according to effectiveAllowCredentials() |
| 366 // here for backward compatibility. But this is not correct. |
| 365 // FIXME: We should set it in the caller of DocumentThreadableLoader. | 367 // FIXME: We should set it in the caller of DocumentThreadableLoader. |
| 366 crossOriginRequest.setFetchCredentialsMode( | 368 crossOriginRequest.setFetchCredentialsMode( |
| 367 effectiveAllowCredentials() == AllowStoredCredentials | 369 effectiveAllowCredentials() == AllowStoredCredentials |
| 368 ? WebURLRequest::FetchCredentialsModeInclude | 370 ? WebURLRequest::FetchCredentialsModeInclude |
| 369 : WebURLRequest::FetchCredentialsModeOmit); | 371 : WebURLRequest::FetchCredentialsModeOmit); |
| 370 if (m_didRedirect) { | 372 if (m_didRedirect) { |
| 371 crossOriginRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( | 373 crossOriginRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( |
| 372 m_referrerAfterRedirect.referrerPolicy, crossOriginRequest.url(), | 374 m_referrerAfterRedirect.referrerPolicy, crossOriginRequest.url(), |
| 373 m_referrerAfterRedirect.referrer)); | 375 m_referrerAfterRedirect.referrer)); |
| 374 } | 376 } |
| 375 loadRequest(crossOriginRequest, crossOriginOptions); | 377 loadRequest(crossOriginRequest, crossOriginOptions); |
| 376 } else { | 378 } else { |
| 377 m_crossOriginNonSimpleRequest = true; | 379 m_crossOriginNonSimpleRequest = true; |
| 378 // Do not set the Origin header for preflight requests. | 380 // Do not set the Origin header for preflight requests. |
| 379 updateRequestForAccessControl(crossOriginRequest, 0, | 381 updateRequestForAccessControl(crossOriginRequest, 0, |
| 380 effectiveAllowCredentials()); | 382 effectiveAllowCredentials()); |
| 381 // We update the credentials mode according to effectiveAllowCredentials() h
ere for backward compatibility. But this is not correct. | 383 // We update the credentials mode according to effectiveAllowCredentials() |
| 384 // here for backward compatibility. But this is not correct. |
| 382 // FIXME: We should set it in the caller of DocumentThreadableLoader. | 385 // FIXME: We should set it in the caller of DocumentThreadableLoader. |
| 383 crossOriginRequest.setFetchCredentialsMode( | 386 crossOriginRequest.setFetchCredentialsMode( |
| 384 effectiveAllowCredentials() == AllowStoredCredentials | 387 effectiveAllowCredentials() == AllowStoredCredentials |
| 385 ? WebURLRequest::FetchCredentialsModeInclude | 388 ? WebURLRequest::FetchCredentialsModeInclude |
| 386 : WebURLRequest::FetchCredentialsModeOmit); | 389 : WebURLRequest::FetchCredentialsModeOmit); |
| 387 m_actualRequest = crossOriginRequest; | 390 m_actualRequest = crossOriginRequest; |
| 388 m_actualOptions = crossOriginOptions; | 391 m_actualOptions = crossOriginOptions; |
| 389 | 392 |
| 390 if (m_didRedirect) { | 393 if (m_didRedirect) { |
| 391 m_actualRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( | 394 m_actualRequest.setHTTPReferrer(SecurityPolicy::generateReferrer( |
| (...skipping 24 matching lines...) Expand all Loading... |
| 416 | 419 |
| 417 DocumentThreadableLoader::~DocumentThreadableLoader() { | 420 DocumentThreadableLoader::~DocumentThreadableLoader() { |
| 418 CHECK(!m_client); | 421 CHECK(!m_client); |
| 419 DCHECK(!m_resource); | 422 DCHECK(!m_resource); |
| 420 } | 423 } |
| 421 | 424 |
| 422 void DocumentThreadableLoader::overrideTimeout( | 425 void DocumentThreadableLoader::overrideTimeout( |
| 423 unsigned long timeoutMilliseconds) { | 426 unsigned long timeoutMilliseconds) { |
| 424 DCHECK(m_async); | 427 DCHECK(m_async); |
| 425 | 428 |
| 426 // |m_requestStartedSeconds| == 0.0 indicates loading is already finished | 429 // |m_requestStartedSeconds| == 0.0 indicates loading is already finished and |
| 427 // and |m_timeoutTimer| is already stopped, and thus we do nothing for such | 430 // |m_timeoutTimer| is already stopped, and thus we do nothing for such cases. |
| 428 // cases. See https://crbug.com/551663 for details. | 431 // See https://crbug.com/551663 for details. |
| 429 if (m_requestStartedSeconds <= 0.0) | 432 if (m_requestStartedSeconds <= 0.0) |
| 430 return; | 433 return; |
| 431 | 434 |
| 432 m_timeoutTimer.stop(); | 435 m_timeoutTimer.stop(); |
| 433 // At the time of this method's implementation, it is only ever called by | 436 // At the time of this method's implementation, it is only ever called by |
| 434 // XMLHttpRequest, when the timeout attribute is set after sending the | 437 // XMLHttpRequest, when the timeout attribute is set after sending the |
| 435 // request. | 438 // request. |
| 436 // | 439 // |
| 437 // The XHR request says to resolve the time relative to when the request | 440 // The XHR request says to resolve the time relative to when the request |
| 438 // was initially sent, however other uses of this method may need to | 441 // was initially sent, however other uses of this method may need to |
| (...skipping 13 matching lines...) Expand all Loading... |
| 452 | 455 |
| 453 void DocumentThreadableLoader::cancelWithError(const ResourceError& error) { | 456 void DocumentThreadableLoader::cancelWithError(const ResourceError& error) { |
| 454 // Cancel can re-enter and m_resource might be null here as a result. | 457 // Cancel can re-enter and m_resource might be null here as a result. |
| 455 if (!m_client || !resource()) { | 458 if (!m_client || !resource()) { |
| 456 clear(); | 459 clear(); |
| 457 return; | 460 return; |
| 458 } | 461 } |
| 459 | 462 |
| 460 ResourceError errorForCallback = error; | 463 ResourceError errorForCallback = error; |
| 461 if (errorForCallback.isNull()) { | 464 if (errorForCallback.isNull()) { |
| 462 // FIXME: This error is sent to the client in didFail(), so it should not be
an internal one. Use FrameLoaderClient::cancelledError() instead. | 465 // FIXME: This error is sent to the client in didFail(), so it should not be |
| 466 // an internal one. Use FrameLoaderClient::cancelledError() instead. |
| 463 errorForCallback = | 467 errorForCallback = |
| 464 ResourceError(errorDomainBlinkInternal, 0, | 468 ResourceError(errorDomainBlinkInternal, 0, |
| 465 resource()->url().getString(), "Load cancelled"); | 469 resource()->url().getString(), "Load cancelled"); |
| 466 errorForCallback.setIsCancellation(true); | 470 errorForCallback.setIsCancellation(true); |
| 467 } | 471 } |
| 468 | 472 |
| 469 ThreadableLoaderClient* client = m_client; | 473 ThreadableLoaderClient* client = m_client; |
| 470 clear(); | 474 clear(); |
| 471 client->didFail(errorForCallback); | 475 client->didFail(errorForCallback); |
| 472 } | 476 } |
| 473 | 477 |
| 474 void DocumentThreadableLoader::setDefersLoading(bool value) { | 478 void DocumentThreadableLoader::setDefersLoading(bool value) { |
| 475 if (resource()) | 479 if (resource()) |
| 476 resource()->setDefersLoading(value); | 480 resource()->setDefersLoading(value); |
| 477 } | 481 } |
| 478 | 482 |
| 479 void DocumentThreadableLoader::clear() { | 483 void DocumentThreadableLoader::clear() { |
| 480 m_client = nullptr; | 484 m_client = nullptr; |
| 481 m_timeoutTimer.stop(); | 485 m_timeoutTimer.stop(); |
| 482 m_requestStartedSeconds = 0.0; | 486 m_requestStartedSeconds = 0.0; |
| 483 clearResource(); | 487 clearResource(); |
| 484 } | 488 } |
| 485 | 489 |
| 486 // In this method, we can clear |request| to tell content::WebURLLoaderImpl of | 490 // In this method, we can clear |request| to tell content::WebURLLoaderImpl of |
| 487 // Chromium not to follow the redirect. This works only when this method is | 491 // Chromium not to follow the redirect. This works only when this method is |
| 488 // called by RawResource::willSendRequest(). If called by | 492 // called by RawResource::willSendRequest(). If called by |
| 489 // RawResource::didAddClient(), clearing |request| won't be propagated | 493 // RawResource::didAddClient(), clearing |request| won't be propagated to |
| 490 // to content::WebURLLoaderImpl. So, this loader must also get detached from | 494 // content::WebURLLoaderImpl. So, this loader must also get detached from the |
| 491 // the resource by calling clearResource(). | 495 // resource by calling clearResource(). |
| 492 void DocumentThreadableLoader::redirectReceived( | 496 void DocumentThreadableLoader::redirectReceived( |
| 493 Resource* resource, | 497 Resource* resource, |
| 494 ResourceRequest& request, | 498 ResourceRequest& request, |
| 495 const ResourceResponse& redirectResponse) { | 499 const ResourceResponse& redirectResponse) { |
| 496 DCHECK(m_client); | 500 DCHECK(m_client); |
| 497 DCHECK_EQ(resource, this->resource()); | 501 DCHECK_EQ(resource, this->resource()); |
| 498 DCHECK(m_async); | 502 DCHECK(m_async); |
| 499 | 503 |
| 500 m_checker.redirectReceived(); | 504 m_checker.redirectReceived(); |
| 501 | 505 |
| 502 if (!m_actualRequest.isNull()) { | 506 if (!m_actualRequest.isNull()) { |
| 503 reportResponseReceived(resource->identifier(), redirectResponse); | 507 reportResponseReceived(resource->identifier(), redirectResponse); |
| 504 | 508 |
| 505 handlePreflightFailure(redirectResponse.url().getString(), | 509 handlePreflightFailure(redirectResponse.url().getString(), |
| 506 "Response for preflight is invalid (redirect)"); | 510 "Response for preflight is invalid (redirect)"); |
| 507 | 511 |
| 508 request = ResourceRequest(); | 512 request = ResourceRequest(); |
| 509 | 513 |
| 510 return; | 514 return; |
| 511 } | 515 } |
| 512 | 516 |
| 513 if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) { | 517 if (m_redirectMode == WebURLRequest::FetchRedirectModeManual) { |
| 514 // We use |m_redirectMode| to check the original redirect mode. | 518 // We use |m_redirectMode| to check the original redirect mode. |request| is |
| 515 // |request| is a new request for redirect. So we don't set the redirect | 519 // a new request for redirect. So we don't set the redirect mode of it in |
| 516 // mode of it in WebURLLoaderImpl::Context::OnReceivedRedirect(). | 520 // WebURLLoaderImpl::Context::OnReceivedRedirect(). |
| 517 DCHECK(request.useStreamOnResponse()); | 521 DCHECK(request.useStreamOnResponse()); |
| 518 // There is no need to read the body of redirect response because there | 522 // There is no need to read the body of redirect response because there is |
| 519 // is no way to read the body of opaque-redirect filtered response's | 523 // no way to read the body of opaque-redirect filtered response's internal |
| 520 // internal response. | 524 // response. |
| 521 // TODO(horo): If we support any API which expose the internal body, we | 525 // TODO(horo): If we support any API which expose the internal body, we will |
| 522 // will have to read the body. And also HTTPCache changes will be needed | 526 // have to read the body. And also HTTPCache changes will be needed because |
| 523 // because it doesn't store the body of redirect responses. | 527 // it doesn't store the body of redirect responses. |
| 524 responseReceived(resource, redirectResponse, | 528 responseReceived(resource, redirectResponse, |
| 525 wrapUnique(new EmptyDataHandle())); | 529 wrapUnique(new EmptyDataHandle())); |
| 526 | 530 |
| 527 if (m_client) { | 531 if (m_client) { |
| 528 DCHECK(m_actualRequest.isNull()); | 532 DCHECK(m_actualRequest.isNull()); |
| 529 notifyFinished(resource); | 533 notifyFinished(resource); |
| 530 } | 534 } |
| 531 | 535 |
| 532 request = ResourceRequest(); | 536 request = ResourceRequest(); |
| 533 | 537 |
| 534 return; | 538 return; |
| 535 } | 539 } |
| 536 | 540 |
| 537 if (m_redirectMode == WebURLRequest::FetchRedirectModeError) { | 541 if (m_redirectMode == WebURLRequest::FetchRedirectModeError) { |
| 538 ThreadableLoaderClient* client = m_client; | 542 ThreadableLoaderClient* client = m_client; |
| 539 clear(); | 543 clear(); |
| 540 client->didFailRedirectCheck(); | 544 client->didFailRedirectCheck(); |
| 541 | 545 |
| 542 request = ResourceRequest(); | 546 request = ResourceRequest(); |
| 543 | 547 |
| 544 return; | 548 return; |
| 545 } | 549 } |
| 546 | 550 |
| 547 // Allow same origin requests to continue after allowing clients to audit the
redirect. | 551 // Allow same origin requests to continue after allowing clients to audit the |
| 552 // redirect. |
| 548 if (isAllowedRedirect(request.url())) { | 553 if (isAllowedRedirect(request.url())) { |
| 549 if (m_client->isDocumentThreadableLoaderClient()) | 554 if (m_client->isDocumentThreadableLoaderClient()) |
| 550 static_cast<DocumentThreadableLoaderClient*>(m_client) | 555 static_cast<DocumentThreadableLoaderClient*>(m_client) |
| 551 ->willFollowRedirect(request, redirectResponse); | 556 ->willFollowRedirect(request, redirectResponse); |
| 552 return; | 557 return; |
| 553 } | 558 } |
| 554 | 559 |
| 555 if (m_corsRedirectLimit <= 0) { | 560 if (m_corsRedirectLimit <= 0) { |
| 556 ThreadableLoaderClient* client = m_client; | 561 ThreadableLoaderClient* client = m_client; |
| 557 clear(); | 562 clear(); |
| 558 client->didFailRedirectCheck(); | 563 client->didFailRedirectCheck(); |
| 559 request = ResourceRequest(); | 564 request = ResourceRequest(); |
| 560 return; | 565 return; |
| 561 } | 566 } |
| 562 | 567 |
| 563 --m_corsRedirectLimit; | 568 --m_corsRedirectLimit; |
| 564 | 569 |
| 565 InspectorInstrumentation::didReceiveCORSRedirectResponse( | 570 InspectorInstrumentation::didReceiveCORSRedirectResponse( |
| 566 document().frame(), resource->identifier(), | 571 document().frame(), resource->identifier(), |
| 567 document().frame()->loader().documentLoader(), redirectResponse, | 572 document().frame()->loader().documentLoader(), redirectResponse, |
| 568 resource); | 573 resource); |
| 569 | 574 |
| 570 bool allowRedirect = false; | 575 bool allowRedirect = false; |
| 571 String accessControlErrorDescription; | 576 String accessControlErrorDescription; |
| 572 | 577 |
| 573 if (m_crossOriginNonSimpleRequest) { | 578 if (m_crossOriginNonSimpleRequest) { |
| 574 // Non-simple cross origin requests (both preflight and actual one) are | 579 // Non-simple cross origin requests (both preflight and actual one) are not |
| 575 // not allowed to follow redirect. | 580 // allowed to follow redirect. |
| 576 accessControlErrorDescription = | 581 accessControlErrorDescription = |
| 577 "Redirect from '" + redirectResponse.url().getString() + "' to '" + | 582 "Redirect from '" + redirectResponse.url().getString() + "' to '" + |
| 578 request.url().getString() + | 583 request.url().getString() + |
| 579 "' has been blocked by CORS policy: Request requires preflight, which " | 584 "' has been blocked by CORS policy: Request requires preflight, which " |
| 580 "is disallowed to follow cross-origin redirect."; | 585 "is disallowed to follow cross-origin redirect."; |
| 581 } else if (!CrossOriginAccessControl::isLegalRedirectLocation( | 586 } else if (!CrossOriginAccessControl::isLegalRedirectLocation( |
| 582 request.url(), accessControlErrorDescription)) { | 587 request.url(), accessControlErrorDescription)) { |
| 583 accessControlErrorDescription = | 588 accessControlErrorDescription = |
| 584 "Redirect from '" + redirectResponse.url().getString() + | 589 "Redirect from '" + redirectResponse.url().getString() + |
| 585 "' has been blocked by CORS policy: " + accessControlErrorDescription; | 590 "' has been blocked by CORS policy: " + accessControlErrorDescription; |
| 586 } else if (!m_sameOriginRequest && | 591 } else if (!m_sameOriginRequest && |
| 587 !passesAccessControlCheck( | 592 !passesAccessControlCheck( |
| 588 redirectResponse, effectiveAllowCredentials(), | 593 redirectResponse, effectiveAllowCredentials(), |
| 589 getSecurityOrigin(), accessControlErrorDescription, | 594 getSecurityOrigin(), accessControlErrorDescription, |
| 590 m_requestContext)) { | 595 m_requestContext)) { |
| 591 // The redirect response must pass the access control check if the | 596 // The redirect response must pass the access control check if the original |
| 592 // original request was not same-origin. | 597 // request was not same-origin. |
| 593 accessControlErrorDescription = | 598 accessControlErrorDescription = |
| 594 "Redirect from '" + redirectResponse.url().getString() + "' to '" + | 599 "Redirect from '" + redirectResponse.url().getString() + "' to '" + |
| 595 request.url().getString() + "' has been blocked by CORS policy: " + | 600 request.url().getString() + "' has been blocked by CORS policy: " + |
| 596 accessControlErrorDescription; | 601 accessControlErrorDescription; |
| 597 } else { | 602 } else { |
| 598 allowRedirect = true; | 603 allowRedirect = true; |
| 599 } | 604 } |
| 600 | 605 |
| 601 if (!allowRedirect) { | 606 if (!allowRedirect) { |
| 602 ThreadableLoaderClient* client = m_client; | 607 ThreadableLoaderClient* client = m_client; |
| 603 clear(); | 608 clear(); |
| 604 client->didFailAccessControlCheck(ResourceError( | 609 client->didFailAccessControlCheck(ResourceError( |
| 605 errorDomainBlinkInternal, 0, redirectResponse.url().getString(), | 610 errorDomainBlinkInternal, 0, redirectResponse.url().getString(), |
| 606 accessControlErrorDescription)); | 611 accessControlErrorDescription)); |
| 607 request = ResourceRequest(); | 612 request = ResourceRequest(); |
| 608 return; | 613 return; |
| 609 } | 614 } |
| 610 | 615 |
| 611 // FIXME: consider combining this with CORS redirect handling performed by | 616 // FIXME: consider combining this with CORS redirect handling performed by |
| 612 // CrossOriginAccessControl::handleRedirect(). | 617 // CrossOriginAccessControl::handleRedirect(). |
| 613 clearResource(); | 618 clearResource(); |
| 614 | 619 |
| 615 // If the original request wasn't same-origin, then if the request URL origin
is not same origin with the original URL origin, | 620 // If the original request wasn't same-origin, then if the request URL origin |
| 616 // set the source origin to a globally unique identifier. (If the original req
uest was same-origin, the origin of the new request | 621 // is not same origin with the original URL origin, set the source origin to a |
| 617 // should be the original URL origin.) | 622 // globally unique identifier. (If the original request was same-origin, the |
| 623 // origin of the new request should be the original URL origin.) |
| 618 if (!m_sameOriginRequest) { | 624 if (!m_sameOriginRequest) { |
| 619 RefPtr<SecurityOrigin> originalOrigin = | 625 RefPtr<SecurityOrigin> originalOrigin = |
| 620 SecurityOrigin::create(redirectResponse.url()); | 626 SecurityOrigin::create(redirectResponse.url()); |
| 621 RefPtr<SecurityOrigin> requestOrigin = | 627 RefPtr<SecurityOrigin> requestOrigin = |
| 622 SecurityOrigin::create(request.url()); | 628 SecurityOrigin::create(request.url()); |
| 623 if (!originalOrigin->isSameSchemeHostPort(requestOrigin.get())) | 629 if (!originalOrigin->isSameSchemeHostPort(requestOrigin.get())) |
| 624 m_securityOrigin = SecurityOrigin::createUnique(); | 630 m_securityOrigin = SecurityOrigin::createUnique(); |
| 625 } | 631 } |
| 626 // Force any subsequent requests to use these checks. | 632 // Force any subsequent requests to use these checks. |
| 627 m_sameOriginRequest = false; | 633 m_sameOriginRequest = false; |
| 628 | 634 |
| 629 // Since the request is no longer same-origin, if the user didn't request cred
entials in | 635 // Since the request is no longer same-origin, if the user didn't request |
| 630 // the first place, update our state so we neither request them nor expect the
y must be allowed. | 636 // credentials in the first place, update our state so we neither request them |
| 637 // nor expect they must be allowed. |
| 631 if (m_resourceLoaderOptions.credentialsRequested == | 638 if (m_resourceLoaderOptions.credentialsRequested == |
| 632 ClientDidNotRequestCredentials) | 639 ClientDidNotRequestCredentials) |
| 633 m_forceDoNotAllowStoredCredentials = true; | 640 m_forceDoNotAllowStoredCredentials = true; |
| 634 | 641 |
| 635 // Save the referrer to use when following the redirect. | 642 // Save the referrer to use when following the redirect. |
| 636 m_didRedirect = true; | 643 m_didRedirect = true; |
| 637 m_referrerAfterRedirect = | 644 m_referrerAfterRedirect = |
| 638 Referrer(request.httpReferrer(), request.getReferrerPolicy()); | 645 Referrer(request.httpReferrer(), request.getReferrerPolicy()); |
| 639 | 646 |
| 640 // Remove any headers that may have been added by the network layer that cause
access control to fail. | 647 // Remove any headers that may have been added by the network layer that cause |
| 648 // access control to fail. |
| 641 request.clearHTTPReferrer(); | 649 request.clearHTTPReferrer(); |
| 642 request.clearHTTPOrigin(); | 650 request.clearHTTPOrigin(); |
| 643 request.clearHTTPUserAgent(); | 651 request.clearHTTPUserAgent(); |
| 644 // Add any CORS simple request headers which we previously saved from the orig
inal request. | 652 // Add any CORS simple request headers which we previously saved from the |
| 653 // original request. |
| 645 for (const auto& header : m_simpleRequestHeaders) | 654 for (const auto& header : m_simpleRequestHeaders) |
| 646 request.setHTTPHeaderField(header.key, header.value); | 655 request.setHTTPHeaderField(header.key, header.value); |
| 647 makeCrossOriginAccessRequest(request); | 656 makeCrossOriginAccessRequest(request); |
| 648 // |this| may be dead here. | 657 // |this| may be dead here. |
| 649 } | 658 } |
| 650 | 659 |
| 651 void DocumentThreadableLoader::redirectBlocked() { | 660 void DocumentThreadableLoader::redirectBlocked() { |
| 652 m_checker.redirectBlocked(); | 661 m_checker.redirectBlocked(); |
| 653 | 662 |
| 654 // Tells the client that a redirect was received but not followed (for an unkn
own reason). | 663 // Tells the client that a redirect was received but not followed (for an |
| 664 // unknown reason). |
| 655 ThreadableLoaderClient* client = m_client; | 665 ThreadableLoaderClient* client = m_client; |
| 656 clear(); | 666 clear(); |
| 657 client->didFailRedirectCheck(); | 667 client->didFailRedirectCheck(); |
| 658 } | 668 } |
| 659 | 669 |
| 660 void DocumentThreadableLoader::dataSent(Resource* resource, | 670 void DocumentThreadableLoader::dataSent(Resource* resource, |
| 661 unsigned long long bytesSent, | 671 unsigned long long bytesSent, |
| 662 unsigned long long totalBytesToBeSent) { | 672 unsigned long long totalBytesToBeSent) { |
| 663 DCHECK(m_client); | 673 DCHECK(m_client); |
| 664 DCHECK_EQ(resource, this->resource()); | 674 DCHECK_EQ(resource, this->resource()); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 if (!m_actualRequest.isNull()) { | 786 if (!m_actualRequest.isNull()) { |
| 777 reportResponseReceived(identifier, response); | 787 reportResponseReceived(identifier, response); |
| 778 handlePreflightResponse(response); | 788 handlePreflightResponse(response); |
| 779 return; | 789 return; |
| 780 } | 790 } |
| 781 | 791 |
| 782 if (response.wasFetchedViaServiceWorker()) { | 792 if (response.wasFetchedViaServiceWorker()) { |
| 783 if (response.wasFetchedViaForeignFetch()) | 793 if (response.wasFetchedViaForeignFetch()) |
| 784 UseCounter::count(m_document, UseCounter::ForeignFetchInterception); | 794 UseCounter::count(m_document, UseCounter::ForeignFetchInterception); |
| 785 if (response.wasFallbackRequiredByServiceWorker()) { | 795 if (response.wasFallbackRequiredByServiceWorker()) { |
| 786 // At this point we must have m_fallbackRequestForServiceWorker. | 796 // At this point we must have m_fallbackRequestForServiceWorker. (For |
| 787 // (For SharedWorker the request won't be CORS or CORS-with-preflight, | 797 // SharedWorker the request won't be CORS or CORS-with-preflight, |
| 788 // therefore fallback-to-network is handled in the browser process | 798 // therefore fallback-to-network is handled in the browser process when |
| 789 // when the ServiceWorker does not call respondWith().) | 799 // the ServiceWorker does not call respondWith().) |
| 790 DCHECK(!m_fallbackRequestForServiceWorker.isNull()); | 800 DCHECK(!m_fallbackRequestForServiceWorker.isNull()); |
| 791 reportResponseReceived(identifier, response); | 801 reportResponseReceived(identifier, response); |
| 792 loadFallbackRequestForServiceWorker(); | 802 loadFallbackRequestForServiceWorker(); |
| 793 return; | 803 return; |
| 794 } | 804 } |
| 795 m_fallbackRequestForServiceWorker = ResourceRequest(); | 805 m_fallbackRequestForServiceWorker = ResourceRequest(); |
| 796 m_client->didReceiveResponse(identifier, response, std::move(handle)); | 806 m_client->didReceiveResponse(identifier, response, std::move(handle)); |
| 797 return; | 807 return; |
| 798 } | 808 } |
| 799 | 809 |
| 800 // Even if the request met the conditions to get handled by a Service Worker | 810 // Even if the request met the conditions to get handled by a Service Worker |
| 801 // in the constructor of this class (and therefore | 811 // in the constructor of this class (and therefore |
| 802 // |m_fallbackRequestForServiceWorker| is set), the Service Worker may skip | 812 // |m_fallbackRequestForServiceWorker| is set), the Service Worker may skip |
| 803 // processing the request. Only if the request is same origin, the skipped | 813 // processing the request. Only if the request is same origin, the skipped |
| 804 // response may come here (wasFetchedViaServiceWorker() returns false) since | 814 // response may come here (wasFetchedViaServiceWorker() returns false) since |
| 805 // such a request doesn't have to go through the CORS algorithm by calling | 815 // such a request doesn't have to go through the CORS algorithm by calling |
| 806 // loadFallbackRequestForServiceWorker(). | 816 // loadFallbackRequestForServiceWorker(). |
| 807 // FIXME: We should use |m_sameOriginRequest| when we will support | 817 // FIXME: We should use |m_sameOriginRequest| when we will support Suborigins |
| 808 // Suborigins (crbug.com/336894) for Service Worker. | 818 // (crbug.com/336894) for Service Worker. |
| 809 DCHECK( | 819 DCHECK( |
| 810 m_fallbackRequestForServiceWorker.isNull() || | 820 m_fallbackRequestForServiceWorker.isNull() || |
| 811 getSecurityOrigin()->canRequest(m_fallbackRequestForServiceWorker.url())); | 821 getSecurityOrigin()->canRequest(m_fallbackRequestForServiceWorker.url())); |
| 812 m_fallbackRequestForServiceWorker = ResourceRequest(); | 822 m_fallbackRequestForServiceWorker = ResourceRequest(); |
| 813 | 823 |
| 814 if (!m_sameOriginRequest && | 824 if (!m_sameOriginRequest && |
| 815 m_options.crossOriginRequestPolicy == UseAccessControl) { | 825 m_options.crossOriginRequestPolicy == UseAccessControl) { |
| 816 String accessControlErrorDescription; | 826 String accessControlErrorDescription; |
| 817 if (!passesAccessControlCheck( | 827 if (!passesAccessControlCheck( |
| 818 response, effectiveAllowCredentials(), getSecurityOrigin(), | 828 response, effectiveAllowCredentials(), getSecurityOrigin(), |
| (...skipping 26 matching lines...) Expand all Loading... |
| 845 const char* data, | 855 const char* data, |
| 846 size_t dataLength) { | 856 size_t dataLength) { |
| 847 DCHECK_EQ(resource, this->resource()); | 857 DCHECK_EQ(resource, this->resource()); |
| 848 DCHECK(m_async); | 858 DCHECK(m_async); |
| 849 | 859 |
| 850 m_checker.dataReceived(); | 860 m_checker.dataReceived(); |
| 851 | 861 |
| 852 if (m_isUsingDataConsumerHandle) | 862 if (m_isUsingDataConsumerHandle) |
| 853 return; | 863 return; |
| 854 | 864 |
| 855 // TODO(junov): Fix the ThreadableLoader ecosystem to use size_t. | 865 // TODO(junov): Fix the ThreadableLoader ecosystem to use size_t. Until then, |
| 856 // Until then, we use safeCast to trap potential overflows. | 866 // we use safeCast to trap potential overflows. |
| 857 handleReceivedData(data, safeCast<unsigned>(dataLength)); | 867 handleReceivedData(data, safeCast<unsigned>(dataLength)); |
| 858 } | 868 } |
| 859 | 869 |
| 860 void DocumentThreadableLoader::handleReceivedData(const char* data, | 870 void DocumentThreadableLoader::handleReceivedData(const char* data, |
| 861 size_t dataLength) { | 871 size_t dataLength) { |
| 862 DCHECK(m_client); | 872 DCHECK(m_client); |
| 863 | 873 |
| 864 // Preflight data should be invisible to clients. | 874 // Preflight data should be invisible to clients. |
| 865 if (!m_actualRequest.isNull()) | 875 if (!m_actualRequest.isNull()) |
| 866 return; | 876 return; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 // Protect the resource in |didFinishLoading| in order not to release the | 912 // Protect the resource in |didFinishLoading| in order not to release the |
| 903 // downloaded file. | 913 // downloaded file. |
| 904 Persistent<Resource> protect = resource(); | 914 Persistent<Resource> protect = resource(); |
| 905 clear(); | 915 clear(); |
| 906 client->didFinishLoading(identifier, finishTime); | 916 client->didFinishLoading(identifier, finishTime); |
| 907 } | 917 } |
| 908 | 918 |
| 909 void DocumentThreadableLoader::didTimeout(TimerBase* timer) { | 919 void DocumentThreadableLoader::didTimeout(TimerBase* timer) { |
| 910 DCHECK_EQ(timer, &m_timeoutTimer); | 920 DCHECK_EQ(timer, &m_timeoutTimer); |
| 911 | 921 |
| 912 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, | 922 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, Same as existing |
| 913 // Same as existing FIXME above - this error should be coming from FrameLoader
Client to be identifiable. | 923 // FIXME above - this error should be coming from FrameLoaderClient to be |
| 924 // identifiable. |
| 914 static const int timeoutError = -7; | 925 static const int timeoutError = -7; |
| 915 ResourceError error("net", timeoutError, resource()->url(), String()); | 926 ResourceError error("net", timeoutError, resource()->url(), String()); |
| 916 error.setIsTimeout(true); | 927 error.setIsTimeout(true); |
| 917 cancelWithError(error); | 928 cancelWithError(error); |
| 918 } | 929 } |
| 919 | 930 |
| 920 void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() { | 931 void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() { |
| 921 clearResource(); | 932 clearResource(); |
| 922 ResourceRequest fallbackRequest(m_fallbackRequestForServiceWorker); | 933 ResourceRequest fallbackRequest(m_fallbackRequestForServiceWorker); |
| 923 m_fallbackRequestForServiceWorker = ResourceRequest(); | 934 m_fallbackRequestForServiceWorker = ResourceRequest(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 else | 1012 else |
| 1002 setResource(RawResource::fetch(newRequest, document().fetcher())); | 1013 setResource(RawResource::fetch(newRequest, document().fetcher())); |
| 1003 | 1014 |
| 1004 if (!resource()) { | 1015 if (!resource()) { |
| 1005 InspectorInstrumentation:: | 1016 InspectorInstrumentation:: |
| 1006 documentThreadableLoaderFailedToStartLoadingForClient(m_document, | 1017 documentThreadableLoaderFailedToStartLoadingForClient(m_document, |
| 1007 m_client); | 1018 m_client); |
| 1008 ThreadableLoaderClient* client = m_client; | 1019 ThreadableLoaderClient* client = m_client; |
| 1009 clear(); | 1020 clear(); |
| 1010 // setResource() might call notifyFinished() and thus clear() | 1021 // setResource() might call notifyFinished() and thus clear() |
| 1011 // synchronously, and in such cases ThreadableLoaderClient is | 1022 // synchronously, and in such cases ThreadableLoaderClient is already |
| 1012 // already notified and |client| is null. | 1023 // notified and |client| is null. |
| 1013 if (!client) | 1024 if (!client) |
| 1014 return; | 1025 return; |
| 1015 client->didFail(ResourceError(errorDomainBlinkInternal, 0, | 1026 client->didFail(ResourceError(errorDomainBlinkInternal, 0, |
| 1016 requestURL.getString(), | 1027 requestURL.getString(), |
| 1017 "Failed to start loading.")); | 1028 "Failed to start loading.")); |
| 1018 return; | 1029 return; |
| 1019 } | 1030 } |
| 1020 | 1031 |
| 1021 if (resource()->isLoading()) { | 1032 if (resource()->isLoading()) { |
| 1022 unsigned long identifier = resource()->identifier(); | 1033 unsigned long identifier = resource()->identifier(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1046 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient( | 1057 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient( |
| 1047 m_document, identifier, m_client); | 1058 m_document, identifier, m_client); |
| 1048 ThreadableLoaderClient* client = m_client; | 1059 ThreadableLoaderClient* client = m_client; |
| 1049 | 1060 |
| 1050 if (!resource) { | 1061 if (!resource) { |
| 1051 m_client = nullptr; | 1062 m_client = nullptr; |
| 1052 client->didFail(error); | 1063 client->didFail(error); |
| 1053 return; | 1064 return; |
| 1054 } | 1065 } |
| 1055 | 1066 |
| 1056 // No exception for file:/// resources, see <rdar://problem/4962298>. | 1067 // No exception for file:/// resources, see <rdar://problem/4962298>. Also, if |
| 1057 // Also, if we have an HTTP response, then it wasn't a network error in fact. | 1068 // we have an HTTP response, then it wasn't a network error in fact. |
| 1058 if (!error.isNull() && !requestURL.isLocalFile() && | 1069 if (!error.isNull() && !requestURL.isLocalFile() && |
| 1059 response.httpStatusCode() <= 0) { | 1070 response.httpStatusCode() <= 0) { |
| 1060 m_client = nullptr; | 1071 m_client = nullptr; |
| 1061 client->didFail(error); | 1072 client->didFail(error); |
| 1062 return; | 1073 return; |
| 1063 } | 1074 } |
| 1064 | 1075 |
| 1065 // FIXME: A synchronous request does not tell us whether a redirect happened o
r not, so we guess by comparing the | 1076 // FIXME: A synchronous request does not tell us whether a redirect happened |
| 1066 // request and response URLs. This isn't a perfect test though, since a server
can serve a redirect to the same URL that was | 1077 // or not, so we guess by comparing the request and response URLs. This isn't |
| 1067 // requested. Also comparing the request and response URLs as strings will fai
l if the requestURL still has its credentials. | 1078 // a perfect test though, since a server can serve a redirect to the same URL |
| 1079 // that was requested. Also comparing the request and response URLs as strings |
| 1080 // will fail if the requestURL still has its credentials. |
| 1068 if (requestURL != response.url() && !isAllowedRedirect(response.url())) { | 1081 if (requestURL != response.url() && !isAllowedRedirect(response.url())) { |
| 1069 m_client = nullptr; | 1082 m_client = nullptr; |
| 1070 client->didFailRedirectCheck(); | 1083 client->didFailRedirectCheck(); |
| 1071 return; | 1084 return; |
| 1072 } | 1085 } |
| 1073 | 1086 |
| 1074 handleResponse(identifier, response, nullptr); | 1087 handleResponse(identifier, response, nullptr); |
| 1075 | 1088 |
| 1076 // handleResponse() may detect an error. In such a case (check |m_client| | 1089 // handleResponse() may detect an error. In such a case (check |m_client| as |
| 1077 // as it gets reset by clear() call), skip the rest. | 1090 // it gets reset by clear() call), skip the rest. |
| 1078 // | 1091 // |
| 1079 // |this| is alive here since loadResourceSynchronously() keeps it alive | 1092 // |this| is alive here since loadResourceSynchronously() keeps it alive until |
| 1080 // until the end of the function. | 1093 // the end of the function. |
| 1081 if (!m_client) | 1094 if (!m_client) |
| 1082 return; | 1095 return; |
| 1083 | 1096 |
| 1084 RefPtr<const SharedBuffer> data = resource->resourceBuffer(); | 1097 RefPtr<const SharedBuffer> data = resource->resourceBuffer(); |
| 1085 if (data) | 1098 if (data) |
| 1086 handleReceivedData(data->data(), data->size()); | 1099 handleReceivedData(data->data(), data->size()); |
| 1087 | 1100 |
| 1088 // The client may cancel this loader in handleReceivedData(). In such a | 1101 // The client may cancel this loader in handleReceivedData(). In such a case, |
| 1089 // case, skip the rest. | 1102 // skip the rest. |
| 1090 if (!m_client) | 1103 if (!m_client) |
| 1091 return; | 1104 return; |
| 1092 | 1105 |
| 1093 handleSuccessfulFinish(identifier, 0.0); | 1106 handleSuccessfulFinish(identifier, 0.0); |
| 1094 } | 1107 } |
| 1095 | 1108 |
| 1096 bool DocumentThreadableLoader::isAllowedRedirect(const KURL& url) const { | 1109 bool DocumentThreadableLoader::isAllowedRedirect(const KURL& url) const { |
| 1097 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) | 1110 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
| 1098 return true; | 1111 return true; |
| 1099 | 1112 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1117 } | 1130 } |
| 1118 | 1131 |
| 1119 DEFINE_TRACE(DocumentThreadableLoader) { | 1132 DEFINE_TRACE(DocumentThreadableLoader) { |
| 1120 visitor->trace(m_resource); | 1133 visitor->trace(m_resource); |
| 1121 visitor->trace(m_document); | 1134 visitor->trace(m_document); |
| 1122 ThreadableLoader::trace(visitor); | 1135 ThreadableLoader::trace(visitor); |
| 1123 RawResourceClient::trace(visitor); | 1136 RawResourceClient::trace(visitor); |
| 1124 } | 1137 } |
| 1125 | 1138 |
| 1126 } // namespace blink | 1139 } // namespace blink |
| OLD | NEW |