| 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 |