| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 #include "core/loader/DocumentThreadableLoaderClient.h" | 45 #include "core/loader/DocumentThreadableLoaderClient.h" |
| 46 #include "core/loader/FrameLoader.h" | 46 #include "core/loader/FrameLoader.h" |
| 47 #include "core/loader/FrameLoaderClient.h" | 47 #include "core/loader/FrameLoaderClient.h" |
| 48 #include "core/loader/ThreadableLoaderClient.h" | 48 #include "core/loader/ThreadableLoaderClient.h" |
| 49 #include "core/page/ChromeClient.h" | 49 #include "core/page/ChromeClient.h" |
| 50 #include "core/page/Page.h" | 50 #include "core/page/Page.h" |
| 51 #include "platform/SharedBuffer.h" | 51 #include "platform/SharedBuffer.h" |
| 52 #include "platform/network/ResourceRequest.h" | 52 #include "platform/network/ResourceRequest.h" |
| 53 #include "platform/weborigin/SchemeRegistry.h" | 53 #include "platform/weborigin/SchemeRegistry.h" |
| 54 #include "platform/weborigin/SecurityOrigin.h" | 54 #include "platform/weborigin/SecurityOrigin.h" |
| 55 #include "platform/weborigin/SecurityPolicy.h" |
| 55 #include "public/platform/Platform.h" | 56 #include "public/platform/Platform.h" |
| 56 #include "public/platform/WebURLRequest.h" | 57 #include "public/platform/WebURLRequest.h" |
| 57 #include "wtf/Assertions.h" | 58 #include "wtf/Assertions.h" |
| 58 #include "wtf/PtrUtil.h" | 59 #include "wtf/PtrUtil.h" |
| 59 #include <memory> | 60 #include <memory> |
| 60 | 61 |
| 61 namespace blink { | 62 namespace blink { |
| 62 | 63 |
| 63 namespace { | 64 namespace { |
| 64 | 65 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) | 145 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) |
| 145 , m_sameOriginRequest(false) | 146 , m_sameOriginRequest(false) |
| 146 , m_crossOriginNonSimpleRequest(false) | 147 , m_crossOriginNonSimpleRequest(false) |
| 147 , m_isUsingDataConsumerHandle(false) | 148 , m_isUsingDataConsumerHandle(false) |
| 148 , m_async(blockingBehavior == LoadAsynchronously) | 149 , m_async(blockingBehavior == LoadAsynchronously) |
| 149 , m_requestContext(WebURLRequest::RequestContextUnspecified) | 150 , m_requestContext(WebURLRequest::RequestContextUnspecified) |
| 150 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) | 151 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
| 151 , m_requestStartedSeconds(0.0) | 152 , m_requestStartedSeconds(0.0) |
| 152 , m_corsRedirectLimit(kMaxCORSRedirects) | 153 , m_corsRedirectLimit(kMaxCORSRedirects) |
| 153 , m_redirectMode(WebURLRequest::FetchRedirectModeFollow) | 154 , m_redirectMode(WebURLRequest::FetchRedirectModeFollow) |
| 155 , m_didRedirect(false) |
| 154 , m_weakFactory(this) | 156 , m_weakFactory(this) |
| 155 { | 157 { |
| 156 ASSERT(client); | 158 ASSERT(client); |
| 157 } | 159 } |
| 158 | 160 |
| 159 void DocumentThreadableLoader::start(const ResourceRequest& request) | 161 void DocumentThreadableLoader::start(const ResourceRequest& request) |
| 160 { | 162 { |
| 161 // 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. |
| 162 ASSERT(m_async || request.httpReferrer().isEmpty()); | 164 ASSERT(m_async || request.httpReferrer().isEmpty()); |
| 163 | 165 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 | 296 |
| 295 // Non-secure origins may not make "external requests": https://mikewest.git
hub.io/cors-rfc1918/#integration-fetch | 297 // Non-secure origins may not make "external requests": https://mikewest.git
hub.io/cors-rfc1918/#integration-fetch |
| 296 if (!document().isSecureContext() && request.isExternalRequest()) { | 298 if (!document().isSecureContext() && request.isExternalRequest()) { |
| 297 ThreadableLoaderClient* client = m_client; | 299 ThreadableLoaderClient* client = m_client; |
| 298 clear(); | 300 clear(); |
| 299 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal
, 0, request.url().getString(), "Requests to internal network resources are not
allowed from non-secure contexts (see https://goo.gl/Y0ZkNV). This is an experim
ental restriction which is part of 'https://mikewest.github.io/cors-rfc1918/'.")
); | 301 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal
, 0, request.url().getString(), "Requests to internal network resources are not
allowed from non-secure contexts (see https://goo.gl/Y0ZkNV). This is an experim
ental restriction which is part of 'https://mikewest.github.io/cors-rfc1918/'.")
); |
| 300 // |this| may be dead here in async mode. | 302 // |this| may be dead here in async mode. |
| 301 return; | 303 return; |
| 302 } | 304 } |
| 303 | 305 |
| 306 ResourceRequest crossOriginRequest(request); |
| 307 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); |
| 308 |
| 304 // We use isSimpleOrForbiddenRequest() here since |request| may have been | 309 // We use isSimpleOrForbiddenRequest() here since |request| may have been |
| 305 // modified in the process of loading (not from the user's input). For | 310 // modified in the process of loading (not from the user's input). For |
| 306 // example, referrer. We need to accept them. For security, we must reject | 311 // example, referrer. We need to accept them. For security, we must reject |
| 307 // forbidden headers/methods at the point we accept user's input. Not here. | 312 // forbidden headers/methods at the point we accept user's input. Not here. |
| 308 if (!request.isExternalRequest() && ((m_options.preflightPolicy == ConsiderP
reflight && FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), request
.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)) { | 313 if (!request.isExternalRequest() && ((m_options.preflightPolicy == ConsiderP
reflight && FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), request
.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)) { |
| 309 ResourceRequest crossOriginRequest(request); | |
| 310 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); | |
| 311 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), e
ffectiveAllowCredentials()); | 314 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), e
ffectiveAllowCredentials()); |
| 312 // We update the credentials mode according to effectiveAllowCredentials
() here for backward compatibility. But this is not correct. | 315 // We update the credentials mode according to effectiveAllowCredentials
() here for backward compatibility. But this is not correct. |
| 313 // FIXME: We should set it in the caller of DocumentThreadableLoader. | 316 // FIXME: We should set it in the caller of DocumentThreadableLoader. |
| 314 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() =
= AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe
quest::FetchCredentialsModeOmit); | 317 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() =
= AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe
quest::FetchCredentialsModeOmit); |
| 318 if (m_didRedirect) { |
| 319 crossOriginRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(
m_referrerAfterRedirect.referrerPolicy, crossOriginRequest.url(), m_referrerAfte
rRedirect.referrer)); |
| 320 } |
| 315 loadRequest(crossOriginRequest, crossOriginOptions); | 321 loadRequest(crossOriginRequest, crossOriginOptions); |
| 316 // |this| may be dead here in async mode. | 322 // |this| may be dead here in async mode. |
| 317 } else { | 323 } else { |
| 318 m_crossOriginNonSimpleRequest = true; | 324 m_crossOriginNonSimpleRequest = true; |
| 319 | |
| 320 ResourceRequest crossOriginRequest(request); | |
| 321 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); | |
| 322 // Do not set the Origin header for preflight requests. | 325 // Do not set the Origin header for preflight requests. |
| 323 updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCrede
ntials()); | 326 updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCrede
ntials()); |
| 324 // We update the credentials mode according to effectiveAllowCredentials
() here for backward compatibility. But this is not correct. | 327 // We update the credentials mode according to effectiveAllowCredentials
() here for backward compatibility. But this is not correct. |
| 325 // FIXME: We should set it in the caller of DocumentThreadableLoader. | 328 // FIXME: We should set it in the caller of DocumentThreadableLoader. |
| 326 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() =
= AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe
quest::FetchCredentialsModeOmit); | 329 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() =
= AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe
quest::FetchCredentialsModeOmit); |
| 327 m_actualRequest = crossOriginRequest; | 330 m_actualRequest = crossOriginRequest; |
| 328 m_actualOptions = crossOriginOptions; | 331 m_actualOptions = crossOriginOptions; |
| 329 | 332 |
| 333 if (m_didRedirect) { |
| 334 m_actualRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(m_r
eferrerAfterRedirect.referrerPolicy, m_actualRequest.url(), m_referrerAfterRedir
ect.referrer)); |
| 335 } |
| 336 |
| 330 bool shouldForcePreflight = request.isExternalRequest() || InspectorInst
rumentation::shouldForceCORSPreflight(m_document); | 337 bool shouldForcePreflight = request.isExternalRequest() || InspectorInst
rumentation::shouldForceCORSPreflight(m_document); |
| 331 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki
pPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllo
wCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields()
); | 338 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki
pPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllo
wCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields()
); |
| 332 if (canSkipPreflight && !shouldForcePreflight) { | 339 if (canSkipPreflight && !shouldForcePreflight) { |
| 333 loadActualRequest(); | 340 loadActualRequest(); |
| 334 // |this| may be dead here in async mode. | 341 // |this| may be dead here in async mode. |
| 335 } else { | 342 } else { |
| 336 ResourceRequest preflightRequest = createAccessControlPreflightReque
st(m_actualRequest, getSecurityOrigin()); | 343 ResourceRequest preflightRequest = createAccessControlPreflightReque
st(m_actualRequest, getSecurityOrigin()); |
| 337 // Create a ResourceLoaderOptions for preflight. | 344 // Create a ResourceLoaderOptions for preflight. |
| 338 ResourceLoaderOptions preflightOptions = m_actualOptions; | 345 ResourceLoaderOptions preflightOptions = m_actualOptions; |
| 339 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; | 346 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 if (!m_sameOriginRequest && !originalOrigin->isSameSchemeHostPort(re
questOrigin.get())) | 539 if (!m_sameOriginRequest && !originalOrigin->isSameSchemeHostPort(re
questOrigin.get())) |
| 533 m_securityOrigin = SecurityOrigin::createUnique(); | 540 m_securityOrigin = SecurityOrigin::createUnique(); |
| 534 // Force any subsequent requests to use these checks. | 541 // Force any subsequent requests to use these checks. |
| 535 m_sameOriginRequest = false; | 542 m_sameOriginRequest = false; |
| 536 | 543 |
| 537 // Since the request is no longer same-origin, if the user didn't re
quest credentials in | 544 // Since the request is no longer same-origin, if the user didn't re
quest credentials in |
| 538 // the first place, update our state so we neither request them nor
expect they must be allowed. | 545 // the first place, update our state so we neither request them nor
expect they must be allowed. |
| 539 if (m_resourceLoaderOptions.credentialsRequested == ClientDidNotRequ
estCredentials) | 546 if (m_resourceLoaderOptions.credentialsRequested == ClientDidNotRequ
estCredentials) |
| 540 m_forceDoNotAllowStoredCredentials = true; | 547 m_forceDoNotAllowStoredCredentials = true; |
| 541 | 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 |
| 542 // Remove any headers that may have been added by the network layer
that cause access control to fail. | 553 // Remove any headers that may have been added by the network layer
that cause access control to fail. |
| 543 request.clearHTTPReferrer(); | 554 request.clearHTTPReferrer(); |
| 544 request.clearHTTPOrigin(); | 555 request.clearHTTPOrigin(); |
| 545 request.clearHTTPUserAgent(); | 556 request.clearHTTPUserAgent(); |
| 546 // Add any CORS simple request headers which we previously saved fro
m the original request. | 557 // Add any CORS simple request headers which we previously saved fro
m the original request. |
| 547 for (const auto& header : m_simpleRequestHeaders) | 558 for (const auto& header : m_simpleRequestHeaders) |
| 548 request.setHTTPHeaderField(header.key, header.value); | 559 request.setHTTPHeaderField(header.key, header.value); |
| 549 makeCrossOriginAccessRequest(request); | 560 makeCrossOriginAccessRequest(request); |
| 550 // |this| may be dead here. | 561 // |this| may be dead here. |
| 551 return; | 562 return; |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri
gin(); | 1011 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri
gin(); |
| 1001 } | 1012 } |
| 1002 | 1013 |
| 1003 Document& DocumentThreadableLoader::document() const | 1014 Document& DocumentThreadableLoader::document() const |
| 1004 { | 1015 { |
| 1005 ASSERT(m_document); | 1016 ASSERT(m_document); |
| 1006 return *m_document; | 1017 return *m_document; |
| 1007 } | 1018 } |
| 1008 | 1019 |
| 1009 } // namespace blink | 1020 } // namespace blink |
| OLD | NEW |