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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 // Max number of CORS redirects handled in DocumentThreadableLoader. | 60 // Max number of CORS redirects handled in DocumentThreadableLoader. |
61 // Same number as net/url_request/url_request.cc, and | 61 // Same number as net/url_request/url_request.cc, and |
62 // same number as https://fetch.spec.whatwg.org/#concept-http-fetch, Step 4. | 62 // same number as https://fetch.spec.whatwg.org/#concept-http-fetch, Step 4. |
63 // FIXME: currently the number of redirects is counted and limited here and in | 63 // FIXME: currently the number of redirects is counted and limited here and in |
64 // net/url_request/url_request.cc separately. | 64 // net/url_request/url_request.cc separately. |
65 static const int kMaxCORSRedirects = 20; | 65 static const int kMaxCORSRedirects = 20; |
66 | 66 |
67 void DocumentThreadableLoader::loadResourceSynchronously(Document& document, con
st ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoa
derOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) | 67 void DocumentThreadableLoader::loadResourceSynchronously(Document& document, con
st ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoa
derOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) |
68 { | 68 { |
69 // The loader will be deleted as soon as this function exits. | 69 // The loader will be deleted as soon as this function exits. |
70 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, &client, LoadSynchronously, request, options, resourceLoaderOption
s)); | 70 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, &client, LoadSynchronously, options, resourceLoaderOptions)); |
| 71 loader->start(request); |
71 ASSERT(loader->hasOneRef()); | 72 ASSERT(loader->hasOneRef()); |
72 } | 73 } |
73 | 74 |
74 PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document&
document, ThreadableLoaderClient* client, const ResourceRequest& request, const
ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOpt
ions) | 75 PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document&
document, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options
, const ResourceLoaderOptions& resourceLoaderOptions) |
75 { | 76 { |
76 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, client, LoadAsynchronously, request, options, resourceLoaderOption
s)); | 77 return adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchron
ously, options, resourceLoaderOptions)); |
77 if (!loader->resource()) | |
78 loader = nullptr; | |
79 return loader.release(); | |
80 } | 78 } |
81 | 79 |
82 DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
eLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest&
request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& r
esourceLoaderOptions) | 80 DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
eLoaderClient* client, BlockingBehavior blockingBehavior, const ThreadableLoader
Options& options, const ResourceLoaderOptions& resourceLoaderOptions) |
83 : m_client(client) | 81 : m_client(client) |
84 , m_document(document) | 82 , m_document(document) |
85 , m_options(options) | 83 , m_options(options) |
86 , m_resourceLoaderOptions(resourceLoaderOptions) | 84 , m_resourceLoaderOptions(resourceLoaderOptions) |
87 , m_forceDoNotAllowStoredCredentials(false) | 85 , m_forceDoNotAllowStoredCredentials(false) |
88 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) | 86 , m_securityOrigin(m_resourceLoaderOptions.securityOrigin) |
89 , m_sameOriginRequest(securityOrigin()->canRequestNoSuborigin(request.url())
) | 87 , m_sameOriginRequest(false) |
90 , m_crossOriginNonSimpleRequest(false) | 88 , m_crossOriginNonSimpleRequest(false) |
91 , m_isUsingDataConsumerHandle(false) | 89 , m_isUsingDataConsumerHandle(false) |
92 , m_async(blockingBehavior == LoadAsynchronously) | 90 , m_async(blockingBehavior == LoadAsynchronously) |
93 , m_requestContext(request.requestContext()) | 91 , m_requestContext(WebURLRequest::RequestContextUnspecified) |
94 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) | 92 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
95 , m_requestStartedSeconds(0.0) | 93 , m_requestStartedSeconds(0.0) |
96 , m_corsRedirectLimit(kMaxCORSRedirects) | 94 , m_corsRedirectLimit(kMaxCORSRedirects) |
97 { | 95 { |
98 ASSERT(client); | 96 ASSERT(client); |
| 97 } |
| 98 |
| 99 void DocumentThreadableLoader::start(const ResourceRequest& request) |
| 100 { |
99 // Setting an outgoing referer is only supported in the async code path. | 101 // Setting an outgoing referer is only supported in the async code path. |
100 ASSERT(m_async || request.httpReferrer().isEmpty()); | 102 ASSERT(m_async || request.httpReferrer().isEmpty()); |
101 | 103 |
| 104 m_sameOriginRequest = securityOrigin()->canRequestNoSuborigin(request.url())
; |
| 105 m_requestContext = request.requestContext(); |
| 106 |
102 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO
riginRequests) { | 107 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == DenyCrossO
riginRequests) { |
103 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url
().string(), "Cross origin requests are not supported.")); | 108 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url
().string(), "Cross origin requests are not supported.")); |
104 return; | 109 return; |
105 } | 110 } |
106 | 111 |
107 m_requestStartedSeconds = monotonicallyIncreasingTime(); | 112 m_requestStartedSeconds = monotonicallyIncreasingTime(); |
108 | 113 |
109 // Save any CORS simple headers on the request here. If this request redirec
ts cross-origin, we cancel the old request | 114 // Save any CORS simple headers on the request here. If this request redirec
ts cross-origin, we cancel the old request |
110 // create a new one, and copy these headers. | 115 // create a new one, and copy these headers. |
111 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); | 116 const HTTPHeaderMap& headerMap = request.httpHeaderFields(); |
112 for (const auto& header : headerMap) { | 117 for (const auto& header : headerMap) { |
113 if (FetchUtils::isSimpleHeader(header.key, header.value)) | 118 if (FetchUtils::isSimpleHeader(header.key, header.value)) |
114 m_simpleRequestHeaders.add(header.key, header.value); | 119 m_simpleRequestHeaders.add(header.key, header.value); |
115 } | 120 } |
116 | 121 |
117 // If the fetch request will be handled by the ServiceWorker, the | 122 // If the fetch request will be handled by the ServiceWorker, the |
118 // FetchRequestMode of the request must be FetchRequestModeCORS or | 123 // FetchRequestMode of the request must be FetchRequestModeCORS or |
119 // FetchRequestModeCORSWithForcedPreflight. Otherwise the ServiceWorker can | 124 // FetchRequestModeCORSWithForcedPreflight. Otherwise the ServiceWorker can |
120 // return a opaque response which is from the other origin site and the | 125 // return a opaque response which is from the other origin site and the |
121 // script in the page can read the content. | 126 // script in the page can read the content. |
122 // | 127 // |
123 // We assume that ServiceWorker is skipped for sync requests and non-HTTP | 128 // We assume that ServiceWorker is skipped for sync requests and non-HTTP |
124 // familiy requests by content/ code. | 129 // familiy requests by content/ code. |
125 if (m_async && !request.skipServiceWorker() && request.url().protocolIsInHTT
PFamily() && m_document.fetcher()->isControlledByServiceWorker()) { | 130 if (m_async && !request.skipServiceWorker() && request.url().protocolIsInHTT
PFamily() && m_document.fetcher()->isControlledByServiceWorker()) { |
126 ResourceRequest newRequest(request); | 131 ResourceRequest newRequest(request); |
127 // FetchRequestMode should be set by the caller. But the expected value | 132 // FetchRequestMode should be set by the caller. But the expected value |
128 // of FetchRequestMode is not speced yet except for XHR. So we set here. | 133 // of FetchRequestMode is not speced yet except for XHR. So we set here. |
129 // FIXME: When we support fetch API in document, this value should not | 134 // FIXME: When we support fetch API in document, this value should not |
130 // be overridden here. | 135 // be overridden here. |
131 if (options.preflightPolicy == ForcePreflight) | 136 if (m_options.preflightPolicy == ForcePreflight) |
132 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORSWi
thForcedPreflight); | 137 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORSWi
thForcedPreflight); |
133 else | 138 else |
134 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); | 139 newRequest.setFetchRequestMode(WebURLRequest::FetchRequestModeCORS); |
135 | 140 |
136 m_fallbackRequestForServiceWorker = adoptPtr(new ResourceRequest(request
)); | 141 m_fallbackRequestForServiceWorker = adoptPtr(new ResourceRequest(request
)); |
137 m_fallbackRequestForServiceWorker->setSkipServiceWorker(true); | 142 m_fallbackRequestForServiceWorker->setSkipServiceWorker(true); |
138 | 143 |
139 loadRequest(newRequest, m_resourceLoaderOptions); | 144 loadRequest(newRequest, m_resourceLoaderOptions); |
140 return; | 145 return; |
141 } | 146 } |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 if (m_actualRequest) | 601 if (m_actualRequest) |
597 resourceLoaderOptions.dataBufferingPolicy = BufferData; | 602 resourceLoaderOptions.dataBufferingPolicy = BufferData; |
598 | 603 |
599 if (m_options.timeoutMilliseconds > 0) | 604 if (m_options.timeoutMilliseconds > 0) |
600 m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0,
FROM_HERE); | 605 m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0,
FROM_HERE); |
601 | 606 |
602 FetchRequest newRequest(request, m_options.initiator, resourceLoaderOpti
ons); | 607 FetchRequest newRequest(request, m_options.initiator, resourceLoaderOpti
ons); |
603 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) | 608 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
604 newRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); | 609 newRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); |
605 ASSERT(!resource()); | 610 ASSERT(!resource()); |
| 611 |
606 if (request.requestContext() == WebURLRequest::RequestContextVideo || re
quest.requestContext() == WebURLRequest::RequestContextAudio) | 612 if (request.requestContext() == WebURLRequest::RequestContextVideo || re
quest.requestContext() == WebURLRequest::RequestContextAudio) |
607 setResource(RawResource::fetchMedia(newRequest, m_document.fetcher()
)); | 613 setResource(RawResource::fetchMedia(newRequest, m_document.fetcher()
)); |
608 else | 614 else |
609 setResource(RawResource::fetch(newRequest, m_document.fetcher())); | 615 setResource(RawResource::fetch(newRequest, m_document.fetcher())); |
610 if (resource() && resource()->loader()) { | 616 |
| 617 if (!resource()) { |
| 618 m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request
URL.string(), "Failed to start loading.")); |
| 619 return; |
| 620 } |
| 621 |
| 622 if (resource()->loader()) { |
611 unsigned long identifier = resource()->identifier(); | 623 unsigned long identifier = resource()->identifier(); |
612 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForC
lient(&m_document, identifier, m_client); | 624 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForC
lient(&m_document, identifier, m_client); |
613 } | 625 } |
614 return; | 626 return; |
615 } | 627 } |
616 | 628 |
617 FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOption
s); | 629 FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOption
s); |
618 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) | 630 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
619 fetchRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); | 631 fetchRequest.setOriginRestriction(FetchRequest::NoOriginRestriction); |
620 ResourcePtr<Resource> resource = RawResource::fetchSynchronously(fetchReques
t, m_document.fetcher()); | 632 ResourcePtr<Resource> resource = RawResource::fetchSynchronously(fetchReques
t, m_document.fetcher()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 return DoNotAllowStoredCredentials; | 686 return DoNotAllowStoredCredentials; |
675 return m_resourceLoaderOptions.allowCredentials; | 687 return m_resourceLoaderOptions.allowCredentials; |
676 } | 688 } |
677 | 689 |
678 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const | 690 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const |
679 { | 691 { |
680 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin
(); | 692 return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin
(); |
681 } | 693 } |
682 | 694 |
683 } // namespace blink | 695 } // namespace blink |
OLD | NEW |