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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document&
document, ThreadableLoaderClient* client, const ResourceRequest& request, const
ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOpt
ions) | 119 PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document&
document, ThreadableLoaderClient* client, const ResourceRequest& request, const
ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOpt
ions) |
120 { | 120 { |
121 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, client, LoadAsynchronously, request, options, resourceLoaderOption
s)); | 121 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, client, LoadAsynchronously, request, options, resourceLoaderOption
s)); |
122 if (!loader->resource()) | 122 if (!loader->resource()) |
123 loader = nullptr; | 123 loader = nullptr; |
124 return loader.release(); | 124 return loader.release(); |
125 } | 125 } |
126 | 126 |
127 DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
eLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest&
request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& r
esourceLoaderOptions) | 127 DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
eLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest&
request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& r
esourceLoaderOptions) |
128 : m_client(client) | 128 : m_client(client) |
129 , m_document(document) | 129 , m_document(&document) |
130 , m_options(options) | 130 , m_options(options) |
131 , m_resourceLoaderOptions(resourceLoaderOptions) | 131 , m_resourceLoaderOptions(resourceLoaderOptions) |
132 , m_forceDoNotAllowStoredCredentials(false) | 132 , m_forceDoNotAllowStoredCredentials(false) |
133 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) | 133 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) |
134 , m_sameOriginRequest(securityOrigin()->canRequestNoSuborigin(request.url())
) | 134 , m_sameOriginRequest(securityOrigin()->canRequestNoSuborigin(request.url())
) |
135 , m_crossOriginNonSimpleRequest(false) | 135 , m_crossOriginNonSimpleRequest(false) |
136 , m_isUsingDataConsumerHandle(false) | 136 , m_isUsingDataConsumerHandle(false) |
137 , m_async(blockingBehavior == LoadAsynchronously) | 137 , m_async(blockingBehavior == LoadAsynchronously) |
138 , m_requestContext(request.requestContext()) | 138 , m_requestContext(request.requestContext()) |
139 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) | 139 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 // - ThreadableLoader is used as backend for all javascript initiated networ
k | 175 // - ThreadableLoader is used as backend for all javascript initiated networ
k |
176 // fetches. | 176 // fetches. |
177 // - Note that ThreadableLoader is also used for non-network fetch such as | 177 // - Note that ThreadableLoader is also used for non-network fetch such as |
178 // FileReaderLoader. However it emulates GET method so signal is not | 178 // FileReaderLoader. However it emulates GET method so signal is not |
179 // recorded here. | 179 // recorded here. |
180 // - ThreadableLoader w/ non-GET request is only created from javascript | 180 // - ThreadableLoader w/ non-GET request is only created from javascript |
181 // initiated fetch. | 181 // initiated fetch. |
182 // - Some non-script initiated fetches such as WorkerScriptLoader also use | 182 // - Some non-script initiated fetches such as WorkerScriptLoader also use |
183 // ThreadableLoader, but they are guaranteed to use GET method. | 183 // ThreadableLoader, but they are guaranteed to use GET method. |
184 if (request.httpMethod() != "GET") { | 184 if (request.httpMethod() != "GET") { |
185 if (Page* page = m_document.page()) | 185 if (Page* page = document.page()) |
186 page->chromeClient().didObserveNonGetFetchFromScript(); | 186 page->chromeClient().didObserveNonGetFetchFromScript(); |
187 } | 187 } |
188 | 188 |
189 // If the fetch request will be handled by the ServiceWorker, the | 189 // If the fetch request will be handled by the ServiceWorker, the |
190 // FetchRequestMode of the request must be FetchRequestModeCORS or | 190 // FetchRequestMode of the request must be FetchRequestModeCORS or |
191 // FetchRequestModeCORSWithForcedPreflight. Otherwise the ServiceWorker can | 191 // FetchRequestModeCORSWithForcedPreflight. Otherwise the ServiceWorker can |
192 // return a opaque response which is from the other origin site and the | 192 // return a opaque response which is from the other origin site and the |
193 // script in the page can read the content. | 193 // script in the page can read the content. |
194 // | 194 // |
195 // We assume that ServiceWorker is skipped for sync requests and non-HTTP | 195 // We assume that ServiceWorker is skipped for sync requests and non-HTTP |
196 // familiy requests by content/ code. | 196 // familiy requests by content/ code. |
197 if (m_async && !request.skipServiceWorker() && request.url().protocolIsInHTT
PFamily() && m_document.fetcher()->isControlledByServiceWorker()) { | 197 if (m_async && !request.skipServiceWorker() && request.url().protocolIsInHTT
PFamily() && document.fetcher()->isControlledByServiceWorker()) { |
198 ResourceRequest newRequest(request); | 198 ResourceRequest newRequest(request); |
199 // FetchRequestMode should be set by the caller. But the expected value | 199 // FetchRequestMode should be set by the caller. But the expected value |
200 // of FetchRequestMode is not speced yet except for XHR. So we set here. | 200 // of FetchRequestMode is not speced yet except for XHR. So we set here. |
201 // FIXME: When we support fetch API in document, this value should not | 201 // FIXME: When we support fetch API in document, this value should not |
202 // be overridden here. | 202 // be overridden here. |
203 if (options.preflightPolicy == ForcePreflight) | 203 if (options.preflightPolicy == ForcePreflight) |
204 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORSWi
thForcedPreflight); | 204 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORSWi
thForcedPreflight); |
205 else | 205 else |
206 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); | 206 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); |
207 | 207 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 } else { | 259 } else { |
260 m_crossOriginNonSimpleRequest = true; | 260 m_crossOriginNonSimpleRequest = true; |
261 | 261 |
262 OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceReques
t(request)); | 262 OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceReques
t(request)); |
263 OwnPtr<ResourceLoaderOptions> crossOriginOptions = adoptPtr(new Resource
LoaderOptions(m_resourceLoaderOptions)); | 263 OwnPtr<ResourceLoaderOptions> crossOriginOptions = adoptPtr(new Resource
LoaderOptions(m_resourceLoaderOptions)); |
264 // Do not set the Origin header for preflight requests. | 264 // Do not set the Origin header for preflight requests. |
265 updateRequestForAccessControl(*crossOriginRequest, 0, effectiveAllowCred
entials()); | 265 updateRequestForAccessControl(*crossOriginRequest, 0, effectiveAllowCred
entials()); |
266 m_actualRequest = crossOriginRequest.release(); | 266 m_actualRequest = crossOriginRequest.release(); |
267 m_actualOptions = crossOriginOptions.release(); | 267 m_actualOptions = crossOriginOptions.release(); |
268 | 268 |
269 bool shouldForcePreflight = InspectorInstrumentation::shouldForceCORSPre
flight(&m_document); | 269 bool shouldForcePreflight = InspectorInstrumentation::shouldForceCORSPre
flight(m_document); |
270 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki
pPreflight(securityOrigin()->toString(), m_actualRequest->url(), effectiveAllowC
redentials(), m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields()
); | 270 bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSki
pPreflight(securityOrigin()->toString(), m_actualRequest->url(), effectiveAllowC
redentials(), m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields()
); |
271 if (canSkipPreflight && !shouldForcePreflight) { | 271 if (canSkipPreflight && !shouldForcePreflight) { |
272 loadActualRequest(); | 272 loadActualRequest(); |
273 } else { | 273 } else { |
274 ResourceRequest preflightRequest = createAccessControlPreflightReque
st(*m_actualRequest, securityOrigin()); | 274 ResourceRequest preflightRequest = createAccessControlPreflightReque
st(*m_actualRequest, securityOrigin()); |
275 // Create a ResourceLoaderOptions for preflight. | 275 // Create a ResourceLoaderOptions for preflight. |
276 ResourceLoaderOptions preflightOptions = *m_actualOptions; | 276 ResourceLoaderOptions preflightOptions = *m_actualOptions; |
277 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; | 277 preflightOptions.allowCredentials = DoNotAllowStoredCredentials; |
278 loadRequest(preflightRequest, preflightOptions); | 278 loadRequest(preflightRequest, preflightOptions); |
279 } | 279 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 } | 418 } |
419 | 419 |
420 if (m_corsRedirectLimit <= 0) { | 420 if (m_corsRedirectLimit <= 0) { |
421 ThreadableLoaderClient* client = m_client; | 421 ThreadableLoaderClient* client = m_client; |
422 clear(); | 422 clear(); |
423 client->didFailRedirectCheck(); | 423 client->didFailRedirectCheck(); |
424 // |this| may be dead here. | 424 // |this| may be dead here. |
425 } else if (m_options.crossOriginRequestPolicy == UseAccessControl) { | 425 } else if (m_options.crossOriginRequestPolicy == UseAccessControl) { |
426 --m_corsRedirectLimit; | 426 --m_corsRedirectLimit; |
427 | 427 |
428 InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document.fram
e(), resource->identifier(), m_document.frame()->loader().documentLoader(), redi
rectResponse, 0); | 428 InspectorInstrumentation::didReceiveCORSRedirectResponse(document().fram
e(), resource->identifier(), document().frame()->loader().documentLoader(), redi
rectResponse, 0); |
429 | 429 |
430 bool allowRedirect = false; | 430 bool allowRedirect = false; |
431 String accessControlErrorDescription; | 431 String accessControlErrorDescription; |
432 | 432 |
433 // Non-simple cross origin requests (both preflight and actual one) are | 433 // Non-simple cross origin requests (both preflight and actual one) are |
434 // not allowed to follow redirect. | 434 // not allowed to follow redirect. |
435 if (m_crossOriginNonSimpleRequest) { | 435 if (m_crossOriginNonSimpleRequest) { |
436 accessControlErrorDescription = "The request was redirected to '"+ r
equest.url().string() + "', which is disallowed for cross-origin requests that r
equire preflight."; | 436 accessControlErrorDescription = "The request was redirected to '"+ r
equest.url().string() + "', which is disallowed for cross-origin requests that r
equire preflight."; |
437 } else { | 437 } else { |
438 // The redirect response must pass the access control check if the | 438 // The redirect response must pass the access control check if the |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 handlePreflightFailure(response.url().string(), accessControlErrorDescri
ption); | 553 handlePreflightFailure(response.url().string(), accessControlErrorDescri
ption); |
554 // |this| may be dead here in async mode. | 554 // |this| may be dead here in async mode. |
555 return; | 555 return; |
556 } | 556 } |
557 | 557 |
558 CrossOriginPreflightResultCache::shared().appendEntry(securityOrigin()->toSt
ring(), m_actualRequest->url(), preflightResult.release()); | 558 CrossOriginPreflightResultCache::shared().appendEntry(securityOrigin()->toSt
ring(), m_actualRequest->url(), preflightResult.release()); |
559 } | 559 } |
560 | 560 |
561 void DocumentThreadableLoader::reportResponseReceived(unsigned long identifier,
const ResourceResponse& response) | 561 void DocumentThreadableLoader::reportResponseReceived(unsigned long identifier,
const ResourceResponse& response) |
562 { | 562 { |
563 DocumentLoader* loader = m_document.frame()->loader().documentLoader(); | 563 LocalFrame* frame = document().frame(); |
564 LocalFrame* frame = m_document.frame(); | 564 DocumentLoader* loader = frame->loader().documentLoader(); |
565 InspectorInstrumentation::didReceiveResourceResponse(frame, identifier, load
er, response, resource() ? resource()->loader() : 0); | 565 InspectorInstrumentation::didReceiveResourceResponse(frame, identifier, load
er, response, resource() ? resource()->loader() : 0); |
566 frame->console().reportResourceResponseReceived(loader, identifier, response
); | 566 frame->console().reportResourceResponseReceived(loader, identifier, response
); |
567 } | 567 } |
568 | 568 |
569 void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re
sourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle) | 569 void DocumentThreadableLoader::handleResponse(unsigned long identifier, const Re
sourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle) |
570 { | 570 { |
571 ASSERT(m_client); | 571 ASSERT(m_client); |
572 | 572 |
573 if (m_actualRequest) { | 573 if (m_actualRequest) { |
574 reportResponseReceived(identifier, response); | 574 reportResponseReceived(identifier, response); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 resourceLoaderOptions.dataBufferingPolicy = BufferData; | 778 resourceLoaderOptions.dataBufferingPolicy = BufferData; |
779 | 779 |
780 if (m_options.timeoutMilliseconds > 0) | 780 if (m_options.timeoutMilliseconds > 0) |
781 m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0,
BLINK_FROM_HERE); | 781 m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0,
BLINK_FROM_HERE); |
782 | 782 |
783 FetchRequest newRequest(request, m_options.initiator, resourceLoaderOpti
ons); | 783 FetchRequest newRequest(request, m_options.initiator, resourceLoaderOpti
ons); |
784 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) | 784 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
785 newRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); | 785 newRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); |
786 ASSERT(!resource()); | 786 ASSERT(!resource()); |
787 if (request.requestContext() == WebURLRequest::RequestContextVideo || re
quest.requestContext() == WebURLRequest::RequestContextAudio) | 787 if (request.requestContext() == WebURLRequest::RequestContextVideo || re
quest.requestContext() == WebURLRequest::RequestContextAudio) |
788 setResource(RawResource::fetchMedia(newRequest, m_document.fetcher()
)); | 788 setResource(RawResource::fetchMedia(newRequest, document().fetcher()
)); |
789 else | 789 else |
790 setResource(RawResource::fetch(newRequest, m_document.fetcher())); | 790 setResource(RawResource::fetch(newRequest, document().fetcher())); |
791 if (resource() && resource()->loader()) { | 791 if (resource() && resource()->loader()) { |
792 unsigned long identifier = resource()->identifier(); | 792 unsigned long identifier = resource()->identifier(); |
793 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForC
lient(&m_document, identifier, m_client); | 793 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForC
lient(m_document, identifier, m_client); |
794 } | 794 } |
795 return; | 795 return; |
796 } | 796 } |
797 | 797 |
798 FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOption
s); | 798 FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOption
s); |
799 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) | 799 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
800 fetchRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); | 800 fetchRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); |
801 ResourcePtr<Resource> resource = RawResource::fetchSynchronously(fetchReques
t, m_document.fetcher()); | 801 ResourcePtr<Resource> resource = RawResource::fetchSynchronously(fetchReques
t, document().fetcher()); |
802 ResourceResponse response = resource ? resource->response() : ResourceRespon
se(); | 802 ResourceResponse response = resource ? resource->response() : ResourceRespon
se(); |
803 unsigned long identifier = resource ? resource->identifier() : std::numeric_
limits<unsigned long>::max(); | 803 unsigned long identifier = resource ? resource->identifier() : std::numeric_
limits<unsigned long>::max(); |
804 ResourceError error = resource ? resource->resourceError() : ResourceError()
; | 804 ResourceError error = resource ? resource->resourceError() : ResourceError()
; |
805 | 805 |
806 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(&m
_document, identifier, m_client); | 806 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_
document, identifier, m_client); |
807 | 807 |
808 if (!resource) { | 808 if (!resource) { |
809 m_client->didFail(error); | 809 m_client->didFail(error); |
810 return; | 810 return; |
811 } | 811 } |
812 | 812 |
813 // No exception for file:/// resources, see <rdar://problem/4962298>. | 813 // No exception for file:/// resources, see <rdar://problem/4962298>. |
814 // Also, if we have an HTTP response, then it wasn't a network error in fact
. | 814 // Also, if we have an HTTP response, then it wasn't a network error in fact
. |
815 if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode(
) <= 0) { | 815 if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode(
) <= 0) { |
816 m_client->didFail(error); | 816 m_client->didFail(error); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) | 852 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
853 return true; | 853 return true; |
854 | 854 |
855 return m_sameOriginRequest && securityOrigin()->canRequest(url); | 855 return m_sameOriginRequest && securityOrigin()->canRequest(url); |
856 } | 856 } |
857 | 857 |
858 bool DocumentThreadableLoader::isAllowedByContentSecurityPolicy(const KURL& url,
ContentSecurityPolicy::RedirectStatus redirectStatus) const | 858 bool DocumentThreadableLoader::isAllowedByContentSecurityPolicy(const KURL& url,
ContentSecurityPolicy::RedirectStatus redirectStatus) const |
859 { | 859 { |
860 if (m_options.contentSecurityPolicyEnforcement != EnforceConnectSrcDirective
) | 860 if (m_options.contentSecurityPolicyEnforcement != EnforceConnectSrcDirective
) |
861 return true; | 861 return true; |
862 return m_document.contentSecurityPolicy()->allowConnectToSource(url, redirec
tStatus); | 862 return document().contentSecurityPolicy()->allowConnectToSource(url, redirec
tStatus); |
863 } | 863 } |
864 | 864 |
865 StoredCredentials DocumentThreadableLoader::effectiveAllowCredentials() const | 865 StoredCredentials DocumentThreadableLoader::effectiveAllowCredentials() const |
866 { | 866 { |
867 if (m_forceDoNotAllowStoredCredentials) | 867 if (m_forceDoNotAllowStoredCredentials) |
868 return DoNotAllowStoredCredentials; | 868 return DoNotAllowStoredCredentials; |
869 return m_resourceLoaderOptions.allowCredentials; | 869 return m_resourceLoaderOptions.allowCredentials; |
870 } | 870 } |
871 | 871 |
872 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const | 872 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const |
873 { | 873 { |
874 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin
(); | 874 return m_securityOrigin ? m_securityOrigin.get() : document().securityOrigin
(); |
| 875 } |
| 876 |
| 877 Document& DocumentThreadableLoader::document() const |
| 878 { |
| 879 ASSERT(m_document); |
| 880 return *m_document; |
875 } | 881 } |
876 | 882 |
877 } // namespace blink | 883 } // namespace blink |
OLD | NEW |