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: Redirect response does not pass CORS check: " + accessControlErrorDes cription; |
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 RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(redirectRespo nse.url()); | |
sof
2016/07/27 11:51:03
Having complained a bit about RefPtr<SecurityOrigi
tyoshino (SeeGerritForStatus)
2016/07/28 12:23:06
Oh, nice :)
| |
553 RefPtr<SecurityOrigin> requestOrigin = SecurityOrigin::create(request.url()) ; | |
554 // If the original request wasn't same-origin, then if the request URL origi n is not same origin with the original URL origin, | |
555 // set the source origin to a globally unique identifier. (If the original r equest was same-origin, the origin of the new request | |
556 // should be the original URL origin.) | |
557 if (!m_sameOriginRequest && !originalOrigin->isSameSchemeHostPort(requestOri gin.get())) | |
558 m_securityOrigin = SecurityOrigin::createUnique(); | |
559 // Force any subsequent requests to use these checks. | |
560 m_sameOriginRequest = false; | |
561 | |
562 // Since the request is no longer same-origin, if the user didn't request cr edentials in | |
563 // the first place, update our state so we neither request them nor expect t hey must be allowed. | |
564 if (m_resourceLoaderOptions.credentialsRequested == ClientDidNotRequestCrede ntials) | |
565 m_forceDoNotAllowStoredCredentials = true; | |
566 | |
567 // Save the referrer to use when following the redirect. | |
568 m_didRedirect = true; | |
569 m_referrerAfterRedirect = Referrer(request.httpReferrer(), request.getReferr erPolicy()); | |
570 | |
571 // Remove any headers that may have been added by the network layer that cau se access control to fail. | |
572 request.clearHTTPReferrer(); | |
573 request.clearHTTPOrigin(); | |
574 request.clearHTTPUserAgent(); | |
575 // Add any CORS simple request headers which we previously saved from the or iginal request. | |
576 for (const auto& header : m_simpleRequestHeaders) | |
577 request.setHTTPHeaderField(header.key, header.value); | |
578 makeCrossOriginAccessRequest(request); | |
579 // |this| may be dead here. | |
577 } | 580 } |
578 | 581 |
579 void DocumentThreadableLoader::redirectBlocked() | 582 void DocumentThreadableLoader::redirectBlocked() |
580 { | 583 { |
581 // Tells the client that a redirect was received but not followed (for an un known reason). | 584 // Tells the client that a redirect was received but not followed (for an un known reason). |
582 ThreadableLoaderClient* client = m_client; | 585 ThreadableLoaderClient* client = m_client; |
583 clear(); | 586 clear(); |
584 client->didFailRedirectCheck(); | 587 client->didFailRedirectCheck(); |
585 // |this| may be dead here | 588 // |this| may be dead here |
586 } | 589 } |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1015 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri gin(); | 1018 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri gin(); |
1016 } | 1019 } |
1017 | 1020 |
1018 Document& DocumentThreadableLoader::document() const | 1021 Document& DocumentThreadableLoader::document() const |
1019 { | 1022 { |
1020 ASSERT(m_document); | 1023 ASSERT(m_document); |
1021 return *m_document; | 1024 return *m_document; |
1022 } | 1025 } |
1023 | 1026 |
1024 } // namespace blink | 1027 } // namespace blink |
OLD | NEW |