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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
85 , m_options(options) | 85 , m_options(options) |
86 , m_resourceLoaderOptions(resourceLoaderOptions) | 86 , m_resourceLoaderOptions(resourceLoaderOptions) |
87 , m_forceDoNotAllowStoredCredentials(false) | 87 , m_forceDoNotAllowStoredCredentials(false) |
88 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) | 88 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) |
89 , m_sameOriginRequest(securityOrigin()->canRequest(request.url())) | 89 , m_sameOriginRequest(securityOrigin()->canRequest(request.url())) |
90 , m_simpleRequest(true) | 90 , m_simpleRequest(true) |
91 , m_async(blockingBehavior == LoadAsynchronously) | 91 , m_async(blockingBehavior == LoadAsynchronously) |
92 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) | 92 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
93 , m_requestStartedSeconds(0.0) | 93 , m_requestStartedSeconds(0.0) |
94 , m_corsRedirectLimit(kMaxCORSRedirects) | 94 , m_corsRedirectLimit(kMaxCORSRedirects) |
95 , m_accessControlCheckFailed(false) | |
95 { | 96 { |
96 ASSERT(client); | 97 ASSERT(client); |
97 // Setting an outgoing referer is only supported in the async code path. | 98 // Setting an outgoing referer is only supported in the async code path. |
98 ASSERT(m_async || request.httpReferrer().isEmpty()); | 99 ASSERT(m_async || request.httpReferrer().isEmpty()); |
99 | 100 |
100 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO riginRequests) { | 101 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO riginRequests) { |
101 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url ().string(), "Cross origin requests are not supported.")); | 102 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url ().string(), "Cross origin requests are not supported.")); |
102 return; | 103 return; |
103 } | 104 } |
104 | 105 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 | 156 |
156 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request) | 157 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques t& request) |
157 { | 158 { |
158 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 159 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
159 | 160 |
160 // Cross-origin requests are only allowed certain registered schemes. | 161 // Cross-origin requests are only allowed certain registered schemes. |
161 // We would catch this when checking response headers later, but there | 162 // We would catch this when checking response headers later, but there |
162 // is no reason to send a request, preflighted or not, that's guaranteed | 163 // is no reason to send a request, preflighted or not, that's guaranteed |
163 // to be denied. | 164 // to be denied. |
164 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) { | 165 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco l())) { |
165 m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkIntern al, 0, request.url().string(), "Cross origin requests are only supported for pro tocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); | 166 handlePreflightFailure(request.url().string(), "Cross origin requests ar e only supported for protocol schemes: " + SchemeRegistry::listOfCORSEnabledURLS chemes() + "."); |
166 return; | 167 return; |
167 } | 168 } |
168 | 169 |
169 // We use isSimpleOrForbiddenRequest() here since |request| may have been | 170 // We use isSimpleOrForbiddenRequest() here since |request| may have been |
170 // modified in the process of loading (not from the user's input). For | 171 // modified in the process of loading (not from the user's input). For |
171 // example, referrer. We need to accept them. For security, we must reject | 172 // example, referrer. We need to accept them. For security, we must reject |
172 // forbidden headers/methods at the point we accept user's input. Not here. | 173 // forbidden headers/methods at the point we accept user's input. Not here. |
173 if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleO rForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_option s.preflightPolicy == PreventPreflight) { | 174 if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleO rForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_option s.preflightPolicy == PreventPreflight) { |
174 ResourceRequest crossOriginRequest(request); | 175 ResourceRequest crossOriginRequest(request); |
175 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); | 176 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 request.clearHTTPReferrer(); | 329 request.clearHTTPReferrer(); |
329 request.clearHTTPOrigin(); | 330 request.clearHTTPOrigin(); |
330 request.clearHTTPUserAgent(); | 331 request.clearHTTPUserAgent(); |
331 // Add any CORS simple request headers which we previously saved fro m the original request. | 332 // Add any CORS simple request headers which we previously saved fro m the original request. |
332 for (const auto& header : m_simpleRequestHeaders) | 333 for (const auto& header : m_simpleRequestHeaders) |
333 request.setHTTPHeaderField(header.key, header.value); | 334 request.setHTTPHeaderField(header.key, header.value); |
334 makeCrossOriginAccessRequest(request); | 335 makeCrossOriginAccessRequest(request); |
335 return; | 336 return; |
336 } | 337 } |
337 | 338 |
338 ResourceError error(errorDomainBlinkInternal, 0, redirectResponse.url(). string(), accessControlErrorDescription); | 339 handlePreflightFailure(redirectResponse.url().string(), accessControlErr orDescription); |
339 m_client->didFailAccessControlCheck(error); | |
340 } else { | 340 } else { |
341 m_client->didFailRedirectCheck(); | 341 m_client->didFailRedirectCheck(); |
342 } | 342 } |
343 | 343 |
344 clearResource(); | 344 clearResource(); |
345 request = ResourceRequest(); | 345 request = ResourceRequest(); |
346 | 346 |
347 m_requestStartedSeconds = 0.0; | 347 m_requestStartedSeconds = 0.0; |
348 } | 348 } |
349 | 349 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 m_client->didReceiveResponse(identifier, response, handle); | 429 m_client->didReceiveResponse(identifier, response, handle); |
430 return; | 430 return; |
431 } | 431 } |
432 | 432 |
433 ASSERT(!m_fallbackRequestForServiceWorker); | 433 ASSERT(!m_fallbackRequestForServiceWorker); |
434 | 434 |
435 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC ontrol) { | 435 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC ontrol) { |
436 String accessControlErrorDescription; | 436 String accessControlErrorDescription; |
437 if (!passesAccessControlCheck(&m_document, response, effectiveAllowCrede ntials(), securityOrigin(), accessControlErrorDescription)) { | 437 if (!passesAccessControlCheck(&m_document, response, effectiveAllowCrede ntials(), securityOrigin(), accessControlErrorDescription)) { |
438 reportResponseReceived(identifier, response); | 438 reportResponseReceived(identifier, response); |
439 m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkIn ternal, 0, response.url().string(), accessControlErrorDescription)); | 439 handlePreflightFailure(response.url().string(), accessControlErrorDe scription); |
440 return; | 440 return; |
441 } | 441 } |
442 } | 442 } |
443 | 443 |
444 m_client->didReceiveResponse(identifier, response, handle); | 444 m_client->didReceiveResponse(identifier, response, handle); |
445 } | 445 } |
446 | 446 |
447 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data , unsigned dataLength) | 447 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data , unsigned dataLength) |
448 { | 448 { |
449 ASSERT_UNUSED(resource, resource == this->resource()); | 449 ASSERT_UNUSED(resource, resource == this->resource()); |
450 ASSERT(m_async); | 450 ASSERT(m_async); |
451 | 451 |
452 handleReceivedData(data, dataLength); | 452 handleReceivedData(data, dataLength); |
453 } | 453 } |
454 | 454 |
455 void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat aLength) | 455 void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat aLength) |
456 { | 456 { |
457 ASSERT(m_client); | 457 ASSERT(m_client); |
458 | 458 |
459 // Preflight data should be invisible to clients. | 459 // Preflight data should be invisible to clients. |
460 if (m_actualRequest) | 460 if (m_actualRequest) |
461 return; | 461 return; |
462 | 462 |
463 ASSERT(!m_fallbackRequestForServiceWorker); | 463 ASSERT(!m_fallbackRequestForServiceWorker); |
464 | 464 |
465 m_client->didReceiveData(data, dataLength); | 465 if (!m_accessControlCheckFailed) |
466 m_client->didReceiveData(data, dataLength); | |
466 } | 467 } |
467 | 468 |
468 void DocumentThreadableLoader::notifyFinished(Resource* resource) | 469 void DocumentThreadableLoader::notifyFinished(Resource* resource) |
469 { | 470 { |
470 ASSERT(m_client); | 471 ASSERT(m_client); |
471 ASSERT(resource == this->resource()); | 472 ASSERT(resource == this->resource()); |
472 ASSERT(m_async); | 473 ASSERT(m_async); |
473 | 474 |
474 m_timeoutTimer.stop(); | 475 m_timeoutTimer.stop(); |
475 | 476 |
476 if (resource->errorOccurred()) | 477 if (resource->errorOccurred()) |
477 m_client->didFail(resource->resourceError()); | 478 m_client->didFail(resource->resourceError()); |
478 else | 479 else |
479 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); | 480 handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime( )); |
480 } | 481 } |
481 | 482 |
482 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) | 483 void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime) |
483 { | 484 { |
484 ASSERT(!m_fallbackRequestForServiceWorker); | 485 ASSERT(!m_fallbackRequestForServiceWorker); |
485 | 486 |
486 if (m_actualRequest) { | 487 if (m_actualRequest) { |
487 ASSERT(!m_sameOriginRequest); | 488 ASSERT(!m_sameOriginRequest); |
488 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 489 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
489 loadActualRequest(); | 490 loadActualRequest(); |
490 } else { | 491 } else { |
491 // FIXME: Should prevent timeout from being overridden after finished lo ading, without | 492 // FIXME: Should prevent timeout from being overridden after finished lo ading, without |
492 // resetting m_requestStartedSeconds to 0.0 | 493 // resetting m_requestStartedSeconds to 0.0 |
493 m_client->didFinishLoading(identifier, finishTime); | 494 if (!m_accessControlCheckFailed) |
495 m_client->didFinishLoading(identifier, finishTime); | |
494 } | 496 } |
495 } | 497 } |
496 | 498 |
497 void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer ) | 499 void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer ) |
498 { | 500 { |
499 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); | 501 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); |
500 | 502 |
501 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, | 503 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, |
502 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. | 504 // Same as existing FIXME above - this error should be coming from FrameLoad erClient to be identifiable. |
503 static const int timeoutError = -7; | 505 static const int timeoutError = -7; |
(...skipping 16 matching lines...) Expand all Loading... | |
520 OwnPtr<ResourceLoaderOptions> actualOptions; | 522 OwnPtr<ResourceLoaderOptions> actualOptions; |
521 actualOptions.swap(m_actualOptions); | 523 actualOptions.swap(m_actualOptions); |
522 | 524 |
523 actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString()); | 525 actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString()); |
524 | 526 |
525 clearResource(); | 527 clearResource(); |
526 | 528 |
527 loadRequest(*actualRequest, *actualOptions); | 529 loadRequest(*actualRequest, *actualOptions); |
528 } | 530 } |
529 | 531 |
532 // Call handlePreflightFailure() instead of didFailAccessControlCheck() | |
533 // from other places in DocumentThreadableLoader. | |
kinuko
2015/02/03 02:35:36
nit: putting this comment in the header feels more
hiroshige
2015/02/03 08:19:44
Done.
| |
530 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) | 534 void DocumentThreadableLoader::handlePreflightFailure(const String& url, const S tring& errorDescription) |
tyoshino (SeeGerritForStatus)
2015/02/03 06:22:02
rename this as it's no longer specific to prefligh
hiroshige
2015/02/03 08:19:43
Done.
| |
531 { | 535 { |
532 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); | 536 ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); |
533 | 537 |
534 // Prevent handleSuccessfulFinish() from bypassing access check. | 538 // Prevent handleSuccessfulFinish() from bypassing access check. |
535 m_actualRequest = nullptr; | 539 m_actualRequest = nullptr; |
536 | 540 |
541 // Prevent m_client->didReceiveData()/didFinishLoading() from being called | |
542 // after m_client->didFailAccessControlCheck() is called here. | |
543 m_accessControlCheckFailed = true; | |
544 | |
537 // FIXME: Should prevent timeout from being overridden after preflight failu re, without | 545 // FIXME: Should prevent timeout from being overridden after preflight failu re, without |
538 // resetting m_requestStartedSeconds to 0.0 | 546 // resetting m_requestStartedSeconds to 0.0 |
539 m_client->didFailAccessControlCheck(error); | 547 m_client->didFailAccessControlCheck(error); |
540 } | 548 } |
541 | 549 |
542 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) | 550 void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Resou rceLoaderOptions resourceLoaderOptions) |
543 { | 551 { |
544 // Any credential should have been removed from the cross-site requests. | 552 // Any credential should have been removed from the cross-site requests. |
545 const KURL& requestURL = request.url(); | 553 const KURL& requestURL = request.url(); |
546 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); | 554 ASSERT(m_sameOriginRequest || requestURL.user().isEmpty()); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
632 return DoNotAllowStoredCredentials; | 640 return DoNotAllowStoredCredentials; |
633 return m_resourceLoaderOptions.allowCredentials; | 641 return m_resourceLoaderOptions.allowCredentials; |
634 } | 642 } |
635 | 643 |
636 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const | 644 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const |
637 { | 645 { |
638 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin (); | 646 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin (); |
639 } | 647 } |
640 | 648 |
641 } // namespace blink | 649 } // namespace blink |
OLD | NEW |