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 28 matching lines...) Expand all Loading... |
39 #include "core/fetch/Resource.h" | 39 #include "core/fetch/Resource.h" |
40 #include "core/fetch/ResourceFetcher.h" | 40 #include "core/fetch/ResourceFetcher.h" |
41 #include "core/frame/FrameConsole.h" | 41 #include "core/frame/FrameConsole.h" |
42 #include "core/frame/LocalFrame.h" | 42 #include "core/frame/LocalFrame.h" |
43 #include "core/frame/csp/ContentSecurityPolicy.h" | 43 #include "core/frame/csp/ContentSecurityPolicy.h" |
44 #include "core/inspector/InspectorInstrumentation.h" | 44 #include "core/inspector/InspectorInstrumentation.h" |
45 #include "core/inspector/InspectorTraceEvents.h" | 45 #include "core/inspector/InspectorTraceEvents.h" |
46 #include "core/loader/CrossOriginPreflightResultCache.h" | 46 #include "core/loader/CrossOriginPreflightResultCache.h" |
47 #include "core/loader/DocumentThreadableLoaderClient.h" | 47 #include "core/loader/DocumentThreadableLoaderClient.h" |
48 #include "core/loader/FrameLoader.h" | 48 #include "core/loader/FrameLoader.h" |
| 49 #include "core/loader/FrameLoaderClient.h" |
49 #include "core/loader/ThreadableLoaderClient.h" | 50 #include "core/loader/ThreadableLoaderClient.h" |
50 #include "platform/SharedBuffer.h" | 51 #include "platform/SharedBuffer.h" |
51 #include "platform/network/ResourceRequest.h" | 52 #include "platform/network/ResourceRequest.h" |
52 #include "platform/weborigin/SchemeRegistry.h" | 53 #include "platform/weborigin/SchemeRegistry.h" |
53 #include "platform/weborigin/SecurityOrigin.h" | 54 #include "platform/weborigin/SecurityOrigin.h" |
54 #include "public/platform/WebURLRequest.h" | 55 #include "public/platform/WebURLRequest.h" |
55 #include "wtf/Assertions.h" | 56 #include "wtf/Assertions.h" |
56 | 57 |
57 namespace blink { | 58 namespace blink { |
58 | 59 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 | 93 |
93 // Save any CORS simple headers on the request here. If this request redirec
ts cross-origin, we cancel the old request | 94 // Save any CORS simple headers on the request here. If this request redirec
ts cross-origin, we cancel the old request |
94 // create a new one, and copy these headers. | 95 // create a new one, and copy these headers. |
95 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); | 96 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); |
96 HTTPHeaderMap::const_iterator end = headerMap.end(); | 97 HTTPHeaderMap::const_iterator end = headerMap.end(); |
97 for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it)
{ | 98 for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it)
{ |
98 if (FetchUtils::isSimpleHeader(it->key, it->value)) | 99 if (FetchUtils::isSimpleHeader(it->key, it->value)) |
99 m_simpleRequestHeaders.add(it->key, it->value); | 100 m_simpleRequestHeaders.add(it->key, it->value); |
100 } | 101 } |
101 | 102 |
| 103 // If the fetch request will be handled by the ServiceWorker, the |
| 104 // FetchRequestMode of the request must be FetchRequestModeCORS or |
| 105 // FetchRequestModeCORSWithForcedPreflight. Otherwise the ServiceWorker can |
| 106 // return a opaque response which is from the other origin site and the |
| 107 // script in the page can read the content. |
| 108 if (m_async && !request.skipServiceWorker() && m_document.fetcher()->isContr
olledByServiceWorker()) { |
| 109 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCr
ossOriginRequests) { |
| 110 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request
.url().string(), "Cross origin requests are not supported.")); |
| 111 return; |
| 112 } |
| 113 ResourceRequest newRequest(request); |
| 114 // FetchRequestMode should be set by the caller. But the expected value |
| 115 // of FetchRequestMode is not speced yet except for XHR. So we set here. |
| 116 // FIXME: When we support fetch API in document, this value should not |
| 117 // be overridden here. |
| 118 if (options.preflightPolicy == ForcePreflight) |
| 119 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORSWi
thForcedPreflight); |
| 120 else |
| 121 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); |
| 122 |
| 123 m_fallbackRequestForServiceWorker = adoptPtr(new ResourceRequest(request
)); |
| 124 m_fallbackRequestForServiceWorker->setSkipServiceWorker(true); |
| 125 |
| 126 loadRequest(newRequest, m_resourceLoaderOptions); |
| 127 return; |
| 128 } |
| 129 |
102 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO
riginRequests) { | 130 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO
riginRequests) { |
103 loadRequest(request, m_resourceLoaderOptions); | 131 loadRequest(request, m_resourceLoaderOptions); |
104 return; | 132 return; |
105 } | 133 } |
106 | 134 |
107 if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { | 135 if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { |
108 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url
().string(), "Cross origin requests are not supported.")); | 136 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url
().string(), "Cross origin requests are not supported.")); |
109 return; | 137 return; |
110 } | 138 } |
111 | 139 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re
sourceResponse& response) | 383 void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re
sourceResponse& response) |
356 { | 384 { |
357 ASSERT(m_client); | 385 ASSERT(m_client); |
358 | 386 |
359 if (m_actualRequest) { | 387 if (m_actualRequest) { |
360 notifyResponseReceived(identifier, response); | 388 notifyResponseReceived(identifier, response); |
361 handlePreflightResponse(response); | 389 handlePreflightResponse(response); |
362 return; | 390 return; |
363 } | 391 } |
364 | 392 |
365 // If the response is fetched via ServiceWorker, the original URL of the res
ponse could be different from the URL of the request. | |
366 bool isCrossOriginResponse = false; | |
367 if (response.wasFetchedViaServiceWorker()) { | 393 if (response.wasFetchedViaServiceWorker()) { |
368 if (!isAllowedByPolicy(response.url())) { | 394 if (response.wasFallbackRequiredByServiceWorker()) { |
369 notifyResponseReceived(identifier, response); | 395 ASSERT(m_fallbackRequestForServiceWorker); |
370 m_client->didFailRedirectCheck(); | 396 loadFallbackRequestForServiceWorker(); |
371 return; | 397 return; |
372 } | 398 } |
373 isCrossOriginResponse = !securityOrigin()->canRequest(response.url()); | 399 m_fallbackRequestForServiceWorker = nullptr; |
374 if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests && isC
rossOriginResponse) { | 400 m_client->didReceiveResponse(identifier, response); |
375 notifyResponseReceived(identifier, response); | 401 return; |
376 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, respons
e.url().string(), "Cross origin requests are not supported.")); | |
377 return; | |
378 } | |
379 if (isCrossOriginResponse && m_resourceLoaderOptions.credentialsRequeste
d == ClientDidNotRequestCredentials) { | |
380 // Since the request is no longer same-origin, if the user didn't re
quest credentials in | |
381 // the first place, update our state so we neither request them nor
expect they must be allowed. | |
382 m_forceDoNotAllowStoredCredentials = true; | |
383 } | |
384 } else { | |
385 isCrossOriginResponse = !m_sameOriginRequest; | |
386 } | 402 } |
387 if (isCrossOriginResponse && m_options.crossOriginRequestPolicy == UseAccess
Control) { | 403 |
| 404 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessC
ontrol) { |
388 String accessControlErrorDescription; | 405 String accessControlErrorDescription; |
389 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), sec
urityOrigin(), accessControlErrorDescription)) { | 406 if (!passesAccessControlCheck(response, effectiveAllowCredentials(), sec
urityOrigin(), accessControlErrorDescription)) { |
390 notifyResponseReceived(identifier, response); | 407 notifyResponseReceived(identifier, response); |
391 m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkIn
ternal, 0, response.url().string(), accessControlErrorDescription)); | 408 m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkIn
ternal, 0, response.url().string(), accessControlErrorDescription)); |
392 return; | 409 return; |
393 } | 410 } |
394 } | 411 } |
395 | 412 |
396 m_client->didReceiveResponse(identifier, response); | 413 m_client->didReceiveResponse(identifier, response); |
397 } | 414 } |
398 | 415 |
399 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data
, unsigned dataLength) | 416 void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data
, unsigned dataLength) |
400 { | 417 { |
401 ASSERT_UNUSED(resource, resource == this->resource()); | 418 ASSERT_UNUSED(resource, resource == this->resource()); |
402 handleReceivedData(data, dataLength); | 419 handleReceivedData(data, dataLength); |
403 } | 420 } |
404 | 421 |
405 void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat
aLength) | 422 void DocumentThreadableLoader::handleReceivedData(const char* data, unsigned dat
aLength) |
406 { | 423 { |
407 ASSERT(m_client); | 424 ASSERT(m_client); |
408 // Preflight data should be invisible to clients. | 425 // Preflight data should be invisible to clients. |
409 if (!m_actualRequest) | 426 if (!m_actualRequest && !m_fallbackRequestForServiceWorker) |
410 m_client->didReceiveData(data, dataLength); | 427 m_client->didReceiveData(data, dataLength); |
411 } | 428 } |
412 | 429 |
413 void DocumentThreadableLoader::notifyFinished(Resource* resource) | 430 void DocumentThreadableLoader::notifyFinished(Resource* resource) |
414 { | 431 { |
415 ASSERT(m_client); | 432 ASSERT(m_client); |
416 ASSERT(resource == this->resource()); | 433 ASSERT(resource == this->resource()); |
417 | 434 |
418 m_timeoutTimer.stop(); | 435 m_timeoutTimer.stop(); |
419 | 436 |
(...skipping 21 matching lines...) Expand all Loading... |
441 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); | 458 ASSERT_UNUSED(timer, timer == &m_timeoutTimer); |
442 | 459 |
443 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, | 460 // Using values from net/base/net_error_list.h ERR_TIMED_OUT, |
444 // Same as existing FIXME above - this error should be coming from FrameLoad
erClient to be identifiable. | 461 // Same as existing FIXME above - this error should be coming from FrameLoad
erClient to be identifiable. |
445 static const int timeoutError = -7; | 462 static const int timeoutError = -7; |
446 ResourceError error("net", timeoutError, resource()->url(), String()); | 463 ResourceError error("net", timeoutError, resource()->url(), String()); |
447 error.setIsTimeout(true); | 464 error.setIsTimeout(true); |
448 cancelWithError(error); | 465 cancelWithError(error); |
449 } | 466 } |
450 | 467 |
| 468 void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() |
| 469 { |
| 470 clearResource(); |
| 471 OwnPtr<ResourceRequest> fallbackRequest(m_fallbackRequestForServiceWorker.re
lease()); |
| 472 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO
riginRequests) { |
| 473 loadRequest(*fallbackRequest, m_resourceLoaderOptions); |
| 474 return; |
| 475 } |
| 476 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
| 477 makeCrossOriginAccessRequest(*fallbackRequest); |
| 478 } |
| 479 |
451 void DocumentThreadableLoader::loadActualRequest() | 480 void DocumentThreadableLoader::loadActualRequest() |
452 { | 481 { |
453 OwnPtr<ResourceRequest> actualRequest; | 482 OwnPtr<ResourceRequest> actualRequest; |
454 actualRequest.swap(m_actualRequest); | 483 actualRequest.swap(m_actualRequest); |
455 OwnPtr<ResourceLoaderOptions> actualOptions; | 484 OwnPtr<ResourceLoaderOptions> actualOptions; |
456 actualOptions.swap(m_actualOptions); | 485 actualOptions.swap(m_actualOptions); |
457 | 486 |
458 actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString()); | 487 actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString()); |
459 | 488 |
460 clearResource(); | 489 clearResource(); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 return DoNotAllowStoredCredentials; | 596 return DoNotAllowStoredCredentials; |
568 return m_resourceLoaderOptions.allowCredentials; | 597 return m_resourceLoaderOptions.allowCredentials; |
569 } | 598 } |
570 | 599 |
571 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const | 600 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const |
572 { | 601 { |
573 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin
(); | 602 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin
(); |
574 } | 603 } |
575 | 604 |
576 } // namespace blink | 605 } // namespace blink |
OLD | NEW |