| 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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 , m_resourceLoaderOptions(resourceLoaderOptions) | 143 , m_resourceLoaderOptions(resourceLoaderOptions) |
| 144 , m_forceDoNotAllowStoredCredentials(false) | 144 , m_forceDoNotAllowStoredCredentials(false) |
| 145 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) | 145 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) |
| 146 , m_sameOriginRequest(false) | 146 , m_sameOriginRequest(false) |
| 147 , m_crossOriginNonSimpleRequest(false) | 147 , m_crossOriginNonSimpleRequest(false) |
| 148 , m_isUsingDataConsumerHandle(false) | 148 , m_isUsingDataConsumerHandle(false) |
| 149 , m_async(blockingBehavior == LoadAsynchronously) | 149 , m_async(blockingBehavior == LoadAsynchronously) |
| 150 , m_requestContext(WebURLRequest::RequestContextUnspecified) | 150 , m_requestContext(WebURLRequest::RequestContextUnspecified) |
| 151 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) | 151 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
| 152 , m_requestStartedSeconds(0.0) | 152 , m_requestStartedSeconds(0.0) |
| 153 , m_corsRedirectLimit(kMaxCORSRedirects) | 153 , m_corsRedirectLimit(m_options.crossOriginRequestPolicy == UseAccessControl
? kMaxCORSRedirects : 0) |
| 154 , m_redirectMode(WebURLRequest::FetchRedirectModeFollow) | 154 , m_redirectMode(WebURLRequest::FetchRedirectModeFollow) |
| 155 , m_didRedirect(false) | 155 , m_didRedirect(false) |
| 156 , m_weakFactory(this) | 156 , m_weakFactory(this) |
| 157 { | 157 { |
| 158 ASSERT(client); | 158 ASSERT(client); |
| 159 } | 159 } |
| 160 | 160 |
| 161 void DocumentThreadableLoader::start(const ResourceRequest& request) | 161 void DocumentThreadableLoader::start(const ResourceRequest& request) |
| 162 { | 162 { |
| 163 // Setting an outgoing referer is only supported in the async code path. | 163 // Setting an outgoing referer is only supported in the async code path. |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 if (m_client->isDocumentThreadableLoaderClient()) | 500 if (m_client->isDocumentThreadableLoaderClient()) |
| 501 static_cast<DocumentThreadableLoaderClient*>(m_client)->willFollowRe
direct(request, redirectResponse); | 501 static_cast<DocumentThreadableLoaderClient*>(m_client)->willFollowRe
direct(request, redirectResponse); |
| 502 return; | 502 return; |
| 503 } | 503 } |
| 504 | 504 |
| 505 if (m_corsRedirectLimit <= 0) { | 505 if (m_corsRedirectLimit <= 0) { |
| 506 ThreadableLoaderClient* client = m_client; | 506 ThreadableLoaderClient* client = m_client; |
| 507 clear(); | 507 clear(); |
| 508 client->didFailRedirectCheck(); | 508 client->didFailRedirectCheck(); |
| 509 // |this| may be dead here. | 509 // |this| may be dead here. |
| 510 } else if (m_options.crossOriginRequestPolicy == UseAccessControl) { | |
| 511 --m_corsRedirectLimit; | |
| 512 | 510 |
| 513 InspectorInstrumentation::didReceiveCORSRedirectResponse(document().fram
e(), resource->identifier(), document().frame()->loader().documentLoader(), redi
rectResponse, resource); | 511 request = ResourceRequest(); |
| 514 | 512 |
| 515 bool allowRedirect = false; | 513 return; |
| 516 String accessControlErrorDescription; | 514 } |
| 517 | 515 |
| 516 --m_corsRedirectLimit; |
| 517 |
| 518 InspectorInstrumentation::didReceiveCORSRedirectResponse(document().frame(),
resource->identifier(), document().frame()->loader().documentLoader(), redirect
Response, resource); |
| 519 |
| 520 bool allowRedirect = false; |
| 521 String accessControlErrorDescription; |
| 522 |
| 523 if (m_crossOriginNonSimpleRequest) { |
| 518 // Non-simple cross origin requests (both preflight and actual one) are | 524 // Non-simple cross origin requests (both preflight and actual one) are |
| 519 // not allowed to follow redirect. | 525 // not allowed to follow redirect. |
| 520 if (m_crossOriginNonSimpleRequest) { | 526 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."; |
| 521 accessControlErrorDescription = "The request was redirected to '"+ r
equest.url().getString() + "', which is disallowed for cross-origin requests tha
t require preflight."; | 527 } else if (!CrossOriginAccessControl::isLegalRedirectLocation(request.url(),
accessControlErrorDescription)) { |
| 522 } else { | 528 accessControlErrorDescription = "Redirect from '" + redirectResponse.url
().getString() + "' has been blocked by CORS policy: " + accessControlErrorDescr
iption; |
| 523 // The redirect response must pass the access control check if the | 529 } else if (!m_sameOriginRequest && !passesAccessControlCheck(redirectRespons
e, effectiveAllowCredentials(), getSecurityOrigin(), accessControlErrorDescripti
on, m_requestContext)) { |
| 524 // original request was not same-origin. | 530 // The redirect response must pass the access control check if the |
| 525 allowRedirect = CrossOriginAccessControl::isLegalRedirectLocation(re
quest.url(), accessControlErrorDescription) | 531 // original request was not same-origin. |
| 526 && (m_sameOriginRequest || passesAccessControlCheck(redirectResp
onse, effectiveAllowCredentials(), getSecurityOrigin(), accessControlErrorDescri
ption, m_requestContext)); | 532 accessControlErrorDescription = "Redirect from '" + redirectResponse.url
().getString()+ "' to '" + request.url().getString() + "' has been blocked by CO
RS policy: " + accessControlErrorDescription; |
| 527 } | 533 } else { |
| 534 allowRedirect = true; |
| 535 } |
| 528 | 536 |
| 529 if (allowRedirect) { | 537 if (!allowRedirect) { |
| 530 // FIXME: consider combining this with CORS redirect handling perfor
med by | |
| 531 // CrossOriginAccessControl::handleRedirect(). | |
| 532 clearResource(); | |
| 533 | |
| 534 RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(redir
ectResponse.url()); | |
| 535 RefPtr<SecurityOrigin> requestOrigin = SecurityOrigin::create(reques
t.url()); | |
| 536 // If the original request wasn't same-origin, then if the request U
RL origin is not same origin with the original URL origin, | |
| 537 // set the source origin to a globally unique identifier. (If the or
iginal request was same-origin, the origin of the new request | |
| 538 // should be the original URL origin.) | |
| 539 if (!m_sameOriginRequest && !originalOrigin->isSameSchemeHostPort(re
questOrigin.get())) | |
| 540 m_securityOrigin = SecurityOrigin::createUnique(); | |
| 541 // Force any subsequent requests to use these checks. | |
| 542 m_sameOriginRequest = false; | |
| 543 | |
| 544 // Since the request is no longer same-origin, if the user didn't re
quest credentials in | |
| 545 // the first place, update our state so we neither request them nor
expect they must be allowed. | |
| 546 if (m_resourceLoaderOptions.credentialsRequested == ClientDidNotRequ
estCredentials) | |
| 547 m_forceDoNotAllowStoredCredentials = true; | |
| 548 | |
| 549 // Save the referrer to use when following the redirect. | |
| 550 m_didRedirect = true; | |
| 551 m_referrerAfterRedirect = Referrer(request.httpReferrer(), request.g
etReferrerPolicy()); | |
| 552 | |
| 553 // Remove any headers that may have been added by the network layer
that cause access control to fail. | |
| 554 request.clearHTTPReferrer(); | |
| 555 request.clearHTTPOrigin(); | |
| 556 request.clearHTTPUserAgent(); | |
| 557 // Add any CORS simple request headers which we previously saved fro
m the original request. | |
| 558 for (const auto& header : m_simpleRequestHeaders) | |
| 559 request.setHTTPHeaderField(header.key, header.value); | |
| 560 makeCrossOriginAccessRequest(request); | |
| 561 // |this| may be dead here. | |
| 562 return; | |
| 563 } | |
| 564 | |
| 565 ThreadableLoaderClient* client = m_client; | 538 ThreadableLoaderClient* client = m_client; |
| 566 clear(); | 539 clear(); |
| 567 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal
, 0, redirectResponse.url().getString(), accessControlErrorDescription)); | 540 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal
, 0, redirectResponse.url().getString(), accessControlErrorDescription)); |
| 568 // |this| may be dead here. | 541 // |this| may be dead here. |
| 569 } else { | 542 |
| 570 ThreadableLoaderClient* client = m_client; | 543 request = ResourceRequest(); |
| 571 clear(); | 544 |
| 572 client->didFailRedirectCheck(); | 545 return; |
| 573 // |this| may be dead here. | |
| 574 } | 546 } |
| 575 | 547 |
| 576 request = ResourceRequest(); | 548 // FIXME: consider combining this with CORS redirect handling performed by |
| 549 // CrossOriginAccessControl::handleRedirect(). |
| 550 clearResource(); |
| 551 |
| 552 // If the original request wasn't same-origin, then if the request URL origi
n is not same origin with the original URL origin, |
| 553 // set the source origin to a globally unique identifier. (If the original r
equest was same-origin, the origin of the new request |
| 554 // should be the original URL origin.) |
| 555 if (!m_sameOriginRequest) { |
| 556 RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(redirectR
esponse.url()); |
| 557 RefPtr<SecurityOrigin> requestOrigin = SecurityOrigin::create(request.ur
l()); |
| 558 if (!originalOrigin->isSameSchemeHostPort(requestOrigin.get())) |
| 559 m_securityOrigin = SecurityOrigin::createUnique(); |
| 560 } |
| 561 // Force any subsequent requests to use these checks. |
| 562 m_sameOriginRequest = false; |
| 563 |
| 564 // Since the request is no longer same-origin, if the user didn't request cr
edentials in |
| 565 // the first place, update our state so we neither request them nor expect t
hey must be allowed. |
| 566 if (m_resourceLoaderOptions.credentialsRequested == ClientDidNotRequestCrede
ntials) |
| 567 m_forceDoNotAllowStoredCredentials = true; |
| 568 |
| 569 // Save the referrer to use when following the redirect. |
| 570 m_didRedirect = true; |
| 571 m_referrerAfterRedirect = Referrer(request.httpReferrer(), request.getReferr
erPolicy()); |
| 572 |
| 573 // Remove any headers that may have been added by the network layer that cau
se access control to fail. |
| 574 request.clearHTTPReferrer(); |
| 575 request.clearHTTPOrigin(); |
| 576 request.clearHTTPUserAgent(); |
| 577 // Add any CORS simple request headers which we previously saved from the or
iginal request. |
| 578 for (const auto& header : m_simpleRequestHeaders) |
| 579 request.setHTTPHeaderField(header.key, header.value); |
| 580 makeCrossOriginAccessRequest(request); |
| 581 // |this| may be dead here. |
| 577 } | 582 } |
| 578 | 583 |
| 579 void DocumentThreadableLoader::redirectBlocked() | 584 void DocumentThreadableLoader::redirectBlocked() |
| 580 { | 585 { |
| 581 // Tells the client that a redirect was received but not followed (for an un
known reason). | 586 // Tells the client that a redirect was received but not followed (for an un
known reason). |
| 582 ThreadableLoaderClient* client = m_client; | 587 ThreadableLoaderClient* client = m_client; |
| 583 clear(); | 588 clear(); |
| 584 client->didFailRedirectCheck(); | 589 client->didFailRedirectCheck(); |
| 585 // |this| may be dead here | 590 // |this| may be dead here |
| 586 } | 591 } |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri
gin(); | 1020 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri
gin(); |
| 1016 } | 1021 } |
| 1017 | 1022 |
| 1018 Document& DocumentThreadableLoader::document() const | 1023 Document& DocumentThreadableLoader::document() const |
| 1019 { | 1024 { |
| 1020 ASSERT(m_document); | 1025 ASSERT(m_document); |
| 1021 return *m_document; | 1026 return *m_document; |
| 1022 } | 1027 } |
| 1023 | 1028 |
| 1024 } // namespace blink | 1029 } // namespace blink |
| OLD | NEW |