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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 // |this| may be dead here. | 228 // |this| may be dead here. |
229 return; | 229 return; |
230 } | 230 } |
231 | 231 |
232 dispatchInitialRequest(request); | 232 dispatchInitialRequest(request); |
233 // |this| may be dead here in async mode. | 233 // |this| may be dead here in async mode. |
234 } | 234 } |
235 | 235 |
236 void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req
uest) | 236 void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& req
uest) |
237 { | 237 { |
238 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO
riginRequests) { | 238 if (!request.isExternalRequest() && (m_sameOriginRequest || m_options.crossO
riginRequestPolicy == AllowCrossOriginRequests)) { |
239 loadRequest(request, m_resourceLoaderOptions); | 239 loadRequest(request, m_resourceLoaderOptions); |
240 // |this| may be dead here in async mode. | 240 // |this| may be dead here in async mode. |
241 return; | 241 return; |
242 } | 242 } |
243 | 243 |
244 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 244 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isE
xternalRequest()); |
245 | 245 |
246 makeCrossOriginAccessRequest(request); | 246 makeCrossOriginAccessRequest(request); |
247 // |this| may be dead here in async mode. | 247 // |this| may be dead here in async mode. |
248 } | 248 } |
249 | 249 |
250 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques
t& request) | 250 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques
t& request) |
251 { | 251 { |
252 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 252 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isE
xternalRequest()); |
253 ASSERT(m_client); | 253 ASSERT(m_client); |
254 ASSERT(!resource()); | 254 ASSERT(!resource()); |
255 | 255 |
256 // Cross-origin requests are only allowed certain registered schemes. | 256 // Cross-origin requests are only allowed certain registered schemes. |
257 // We would catch this when checking response headers later, but there | 257 // We would catch this when checking response headers later, but there |
258 // is no reason to send a request, preflighted or not, that's guaranteed | 258 // is no reason to send a request, preflighted or not, that's guaranteed |
259 // to be denied. | 259 // to be denied. |
260 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco
l())) { | 260 if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protoco
l())) { |
261 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadingFo
rClient(m_document, m_client); | 261 InspectorInstrumentation::documentThreadableLoaderFailedToStartLoadingFo
rClient(m_document, m_client); |
262 ThreadableLoaderClient* client = m_client; | 262 ThreadableLoaderClient* client = m_client; |
263 clear(); | 263 clear(); |
264 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal
, 0, request.url().getString(), "Cross origin requests are only supported for pr
otocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); | 264 client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal
, 0, request.url().getString(), "Cross origin requests are only supported for pr
otocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); |
265 // |this| may be dead here in async mode. | 265 // |this| may be dead here in async mode. |
266 return; | 266 return; |
267 } | 267 } |
268 | 268 |
| 269 // Non-secure origins may not make "external requests": https://mikewest.git
hub.io/cors-rfc1918/#integration-fetch |
| 270 if (!document().isSecureContext() && request.isExternalRequest()) { |
| 271 ThreadableLoaderClient* client = m_client; |
| 272 clear(); |
| 273 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/'.")
); |
| 274 // |this| may be dead here in async mode. |
| 275 return; |
| 276 } |
| 277 |
269 // We use isSimpleOrForbiddenRequest() here since |request| may have been | 278 // We use isSimpleOrForbiddenRequest() here since |request| may have been |
270 // modified in the process of loading (not from the user's input). For | 279 // modified in the process of loading (not from the user's input). For |
271 // example, referrer. We need to accept them. For security, we must reject | 280 // example, referrer. We need to accept them. For security, we must reject |
272 // forbidden headers/methods at the point we accept user's input. Not here. | 281 // forbidden headers/methods at the point we accept user's input. Not here. |
273 if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleO
rForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_option
s.preflightPolicy == PreventPreflight) { | 282 if (!request.isExternalRequest() && ((m_options.preflightPolicy == ConsiderP
reflight && FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), request
.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)) { |
274 ResourceRequest crossOriginRequest(request); | 283 ResourceRequest crossOriginRequest(request); |
275 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); | 284 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); |
276 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), e
ffectiveAllowCredentials()); | 285 updateRequestForAccessControl(crossOriginRequest, getSecurityOrigin(), e
ffectiveAllowCredentials()); |
277 // We update the credentials mode according to effectiveAllowCredentials
() here for backward compatibility. But this is not correct. | 286 // We update the credentials mode according to effectiveAllowCredentials
() here for backward compatibility. But this is not correct. |
278 // FIXME: We should set it in the caller of DocumentThreadableLoader. | 287 // FIXME: We should set it in the caller of DocumentThreadableLoader. |
279 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() =
= AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe
quest::FetchCredentialsModeOmit); | 288 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() =
= AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe
quest::FetchCredentialsModeOmit); |
280 loadRequest(crossOriginRequest, crossOriginOptions); | 289 loadRequest(crossOriginRequest, crossOriginOptions); |
281 // |this| may be dead here in async mode. | 290 // |this| may be dead here in async mode. |
282 } else { | 291 } else { |
283 m_crossOriginNonSimpleRequest = true; | 292 m_crossOriginNonSimpleRequest = true; |
284 | 293 |
285 ResourceRequest crossOriginRequest(request); | 294 ResourceRequest crossOriginRequest(request); |
286 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); | 295 ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions); |
287 // Do not set the Origin header for preflight requests. | 296 // Do not set the Origin header for preflight requests. |
288 updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCrede
ntials()); | 297 updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCrede
ntials()); |
289 // We update the credentials mode according to effectiveAllowCredentials
() here for backward compatibility. But this is not correct. | 298 // We update the credentials mode according to effectiveAllowCredentials
() here for backward compatibility. But this is not correct. |
290 // FIXME: We should set it in the caller of DocumentThreadableLoader. | 299 // FIXME: We should set it in the caller of DocumentThreadableLoader. |
291 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() =
= AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe
quest::FetchCredentialsModeOmit); | 300 crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() =
= AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRe
quest::FetchCredentialsModeOmit); |
292 m_actualRequest = crossOriginRequest; | 301 m_actualRequest = crossOriginRequest; |
293 m_actualOptions = crossOriginOptions; | 302 m_actualOptions = crossOriginOptions; |
294 | 303 |
295 bool shouldForcePreflight = InspectorInstrumentation::shouldForceCORSPre
flight(m_document); | 304 bool shouldForcePreflight = request.isExternalRequest() || InspectorInst
rumentation::shouldForceCORSPreflight(m_document); |
296 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki
pPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllo
wCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields()
); | 305 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki
pPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllo
wCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields()
); |
297 if (canSkipPreflight && !shouldForcePreflight) { | 306 if (canSkipPreflight && !shouldForcePreflight) { |
298 loadActualRequest(); | 307 loadActualRequest(); |
299 // |this| may be dead here in async mode. | 308 // |this| may be dead here in async mode. |
300 } else { | 309 } else { |
301 ResourceRequest preflightRequest = createAccessControlPreflightReque
st(m_actualRequest, getSecurityOrigin()); | 310 ResourceRequest preflightRequest = createAccessControlPreflightReque
st(m_actualRequest, getSecurityOrigin()); |
302 // Create a ResourceLoaderOptions for preflight. | 311 // Create a ResourceLoaderOptions for preflight. |
303 ResourceLoaderOptions preflightOptions = m_actualOptions; | 312 ResourceLoaderOptions preflightOptions = m_actualOptions; |
304 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; | 313 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; |
305 loadRequest(preflightRequest, preflightOptions); | 314 loadRequest(preflightRequest, preflightOptions); |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 // |this| may be dead here in async mode. | 600 // |this| may be dead here in async mode. |
592 return; | 601 return; |
593 } | 602 } |
594 | 603 |
595 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { | 604 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { |
596 handlePreflightFailure(response.url().getString(), accessControlErrorDes
cription); | 605 handlePreflightFailure(response.url().getString(), accessControlErrorDes
cription); |
597 // |this| may be dead here in async mode. | 606 // |this| may be dead here in async mode. |
598 return; | 607 return; |
599 } | 608 } |
600 | 609 |
| 610 if (m_actualRequest.isExternalRequest() && !passesExternalPreflightCheck(res
ponse, accessControlErrorDescription)) { |
| 611 handlePreflightFailure(response.url().getString(), accessControlErrorDes
cription); |
| 612 // |this| may be dead here in async mode. |
| 613 return; |
| 614 } |
| 615 |
601 OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new C
rossOriginPreflightResultCacheItem(effectiveAllowCredentials())); | 616 OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new C
rossOriginPreflightResultCacheItem(effectiveAllowCredentials())); |
602 if (!preflightResult->parse(response, accessControlErrorDescription) | 617 if (!preflightResult->parse(response, accessControlErrorDescription) |
603 || !preflightResult->allowsCrossOriginMethod(m_actualRequest.httpMethod(
), accessControlErrorDescription) | 618 || !preflightResult->allowsCrossOriginMethod(m_actualRequest.httpMethod(
), accessControlErrorDescription) |
604 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest.httpHeader
Fields(), accessControlErrorDescription)) { | 619 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest.httpHeader
Fields(), accessControlErrorDescription)) { |
605 handlePreflightFailure(response.url().getString(), accessControlErrorDes
cription); | 620 handlePreflightFailure(response.url().getString(), accessControlErrorDes
cription); |
606 // |this| may be dead here in async mode. | 621 // |this| may be dead here in async mode. |
607 return; | 622 return; |
608 } | 623 } |
609 | 624 |
610 CrossOriginPreflightResultCache::shared().appendEntry(getSecurityOrigin()->t
oString(), m_actualRequest.url(), preflightResult.release()); | 625 CrossOriginPreflightResultCache::shared().appendEntry(getSecurityOrigin()->t
oString(), m_actualRequest.url(), preflightResult.release()); |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri
gin(); | 968 return m_securityOrigin ? m_securityOrigin.get() : document().getSecurityOri
gin(); |
954 } | 969 } |
955 | 970 |
956 Document& DocumentThreadableLoader::document() const | 971 Document& DocumentThreadableLoader::document() const |
957 { | 972 { |
958 ASSERT(m_document); | 973 ASSERT(m_document); |
959 return *m_document; | 974 return *m_document; |
960 } | 975 } |
961 | 976 |
962 } // namespace blink | 977 } // namespace blink |
OLD | NEW |