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 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 , m_async(blockingBehavior == LoadAsynchronously) | 78 , m_async(blockingBehavior == LoadAsynchronously) |
79 #if ENABLE(INSPECTOR) | 79 #if ENABLE(INSPECTOR) |
80 , m_preflightRequestIdentifier(0) | 80 , m_preflightRequestIdentifier(0) |
81 #endif | 81 #endif |
82 { | 82 { |
83 ASSERT(document); | 83 ASSERT(document); |
84 ASSERT(client); | 84 ASSERT(client); |
85 // Setting an outgoing referer is only supported in the async code path. | 85 // Setting an outgoing referer is only supported in the async code path. |
86 ASSERT(m_async || request.httpReferrer().isEmpty()); | 86 ASSERT(m_async || request.httpReferrer().isEmpty()); |
87 | 87 |
88 makeRequest(request); | |
89 } | |
90 | |
91 void DocumentThreadableLoader::makeRequest(const ResourceRequest& request) | |
92 { | |
93 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO
riginRequests) { | 88 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO
riginRequests) { |
94 loadRequest(request, DoSecurityCheck); | 89 loadRequest(request, DoSecurityCheck); |
95 return; | 90 return; |
96 } | 91 } |
97 | 92 |
98 if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { | 93 if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { |
99 m_client->didFail(ResourceError(errorDomainWebKitInternal, 0, request.ur
l().string(), "Cross origin requests are not supported.")); | 94 m_client->didFail(ResourceError(errorDomainWebKitInternal, 0, request.ur
l().string(), "Cross origin requests are not supported.")); |
100 return; | 95 return; |
101 } | 96 } |
102 | 97 |
| 98 makeCrossOriginAccessRequest(request); |
| 99 } |
| 100 |
| 101 void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques
t& request) |
| 102 { |
103 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); | 103 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); |
104 | 104 |
105 OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(re
quest)); | 105 OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(re
quest)); |
106 updateRequestForAccessControl(*crossOriginRequest, securityOrigin(), m_optio
ns.allowCredentials); | 106 updateRequestForAccessControl(*crossOriginRequest, securityOrigin(), m_optio
ns.allowCredentials); |
107 | 107 |
108 if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAc
cessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFiel
ds())) || m_options.preflightPolicy == PreventPreflight) | 108 if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAc
cessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFiel
ds())) || m_options.preflightPolicy == PreventPreflight) |
109 makeSimpleCrossOriginAccessRequest(*crossOriginRequest); | 109 makeSimpleCrossOriginAccessRequest(*crossOriginRequest); |
110 else { | 110 else { |
111 m_simpleRequest = false; | 111 m_simpleRequest = false; |
112 m_actualRequest = crossOriginRequest.release(); | 112 m_actualRequest = crossOriginRequest.release(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 m_resource = 0; | 168 m_resource = 0; |
169 } | 169 } |
170 } | 170 } |
171 | 171 |
172 void DocumentThreadableLoader::redirectReceived(CachedResource* resource, Resour
ceRequest& request, const ResourceResponse& redirectResponse) | 172 void DocumentThreadableLoader::redirectReceived(CachedResource* resource, Resour
ceRequest& request, const ResourceResponse& redirectResponse) |
173 { | 173 { |
174 ASSERT(m_client); | 174 ASSERT(m_client); |
175 ASSERT_UNUSED(resource, resource == m_resource); | 175 ASSERT_UNUSED(resource, resource == m_resource); |
176 | 176 |
177 RefPtr<DocumentThreadableLoader> protect(this); | 177 RefPtr<DocumentThreadableLoader> protect(this); |
178 bool allowRedirect = false; | 178 // Allow same origin requests to continue after allowing clients to audit th
e redirect. |
| 179 if (isAllowedRedirect(request.url())) { |
| 180 if (m_client->isDocumentThreadableLoaderClient()) |
| 181 static_cast<DocumentThreadableLoaderClient*>(m_client)->willSendRequ
est(request, redirectResponse); |
| 182 return; |
| 183 } |
| 184 |
| 185 // When using access control, only simple cross origin requests are allowed
to redirect. The new request URL must have a supported |
| 186 // scheme and not contain the userinfo production. In addition, the redirect
response must pass the access control check. |
179 if (m_options.crossOriginRequestPolicy == UseAccessControl) { | 187 if (m_options.crossOriginRequestPolicy == UseAccessControl) { |
180 // When using access control, only simple cross origin requests are allo
wed to redirect. The new request URL must have a supported | 188 bool allowRedirect = false; |
181 // scheme and not contain the userinfo production. In addition, the redi
rect response must pass the access control check. | |
182 if (m_simpleRequest) { | 189 if (m_simpleRequest) { |
183 String accessControlErrorDescription; | 190 String accessControlErrorDescription; |
184 allowRedirect = SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(re
quest.url().protocol()) | 191 allowRedirect = SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(re
quest.url().protocol()) |
185 && request.url().user().isEmpty() | 192 && request.url().user().isEmpty() |
186 && request.url().pass().isEmpty() | 193 && request.url().pass().isEmpty() |
187 && passesAccessControlCheck(redirectResponse, m_opti
ons.allowCredentials, securityOrigin(), accessControlErrorDescription); | 194 && passesAccessControlCheck(redirectResponse, m_opti
ons.allowCredentials, securityOrigin(), accessControlErrorDescription); |
188 } | 195 } |
189 } else | |
190 allowRedirect = isAllowedRedirect(request.url()); | |
191 | 196 |
192 if (allowRedirect) { | 197 if (allowRedirect) { |
193 if (m_options.crossOriginRequestPolicy == UseAccessControl) { | |
194 if (m_resource) | 198 if (m_resource) |
195 clearResource(); | 199 clearResource(); |
196 | 200 |
197 RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::createFromSt
ring(redirectResponse.url()); | 201 RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::createFromSt
ring(redirectResponse.url()); |
198 RefPtr<SecurityOrigin> requestOrigin = SecurityOrigin::createFromStr
ing(request.url()); | 202 RefPtr<SecurityOrigin> requestOrigin = SecurityOrigin::createFromStr
ing(request.url()); |
199 // If the request URL origin is not same origin with the original UR
L origin, set source origin to a globally unique identifier. | 203 // If the request URL origin is not same origin with the original UR
L origin, set source origin to a globally unique identifier. |
200 if (!originalOrigin->isSameSchemeHostPort(requestOrigin.get())) | 204 if (!originalOrigin->isSameSchemeHostPort(requestOrigin.get())) |
201 m_options.securityOrigin = SecurityOrigin::createUnique(); | 205 m_options.securityOrigin = SecurityOrigin::createUnique(); |
202 m_sameOriginRequest = securityOrigin()->canRequest(request.url()); | 206 // Force any subsequent requests to use these checks. |
| 207 m_sameOriginRequest = false; |
203 | 208 |
204 // Remove any headers that may have been added by the network layer
that cause access control to fail. | 209 // Remove any headers that may have been added by the network layer
that cause access control to fail. |
205 request.clearHTTPContentType(); | 210 request.clearHTTPContentType(); |
206 request.clearHTTPReferrer(); | 211 request.clearHTTPReferrer(); |
207 request.clearHTTPOrigin(); | 212 request.clearHTTPOrigin(); |
208 request.clearHTTPUserAgent(); | 213 request.clearHTTPUserAgent(); |
209 request.clearHTTPAccept(); | 214 request.clearHTTPAccept(); |
210 makeRequest(request); | 215 makeCrossOriginAccessRequest(request); |
211 } else { | 216 return; |
212 // If not using access control, allow clients to audit the redirect. | |
213 if (m_client->isDocumentThreadableLoaderClient()) | |
214 static_cast<DocumentThreadableLoaderClient*>(m_client)->willSend
Request(request, redirectResponse); | |
215 } | 217 } |
216 } else { | |
217 m_client->didFailRedirectCheck(); | |
218 request = ResourceRequest(); | |
219 } | 218 } |
| 219 |
| 220 m_client->didFailRedirectCheck(); |
| 221 request = ResourceRequest(); |
220 } | 222 } |
221 | 223 |
222 void DocumentThreadableLoader::dataSent(CachedResource* resource, unsigned long
long bytesSent, unsigned long long totalBytesToBeSent) | 224 void DocumentThreadableLoader::dataSent(CachedResource* resource, unsigned long
long bytesSent, unsigned long long totalBytesToBeSent) |
223 { | 225 { |
224 ASSERT(m_client); | 226 ASSERT(m_client); |
225 ASSERT_UNUSED(resource, resource == m_resource); | 227 ASSERT_UNUSED(resource, resource == m_resource); |
226 m_client->didSendData(bytesSent, totalBytesToBeSent); | 228 m_client->didSendData(bytesSent, totalBytesToBeSent); |
227 } | 229 } |
228 | 230 |
229 void DocumentThreadableLoader::responseReceived(CachedResource* resource, const
ResourceResponse& response) | 231 void DocumentThreadableLoader::responseReceived(CachedResource* resource, const
ResourceResponse& response) |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 | 423 |
422 return m_sameOriginRequest && securityOrigin()->canRequest(url); | 424 return m_sameOriginRequest && securityOrigin()->canRequest(url); |
423 } | 425 } |
424 | 426 |
425 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const | 427 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const |
426 { | 428 { |
427 return m_options.securityOrigin ? m_options.securityOrigin.get() : m_documen
t->securityOrigin(); | 429 return m_options.securityOrigin ? m_options.securityOrigin.get() : m_documen
t->securityOrigin(); |
428 } | 430 } |
429 | 431 |
430 } // namespace WebCore | 432 } // namespace WebCore |
OLD | NEW |