| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 #include "core/loader/FrameLoader.h" | 45 #include "core/loader/FrameLoader.h" |
| 46 #include "core/loader/ThreadableLoaderClient.h" | 46 #include "core/loader/ThreadableLoaderClient.h" |
| 47 #include "platform/SharedBuffer.h" | 47 #include "platform/SharedBuffer.h" |
| 48 #include "platform/network/ResourceRequest.h" | 48 #include "platform/network/ResourceRequest.h" |
| 49 #include "platform/weborigin/SchemeRegistry.h" | 49 #include "platform/weborigin/SchemeRegistry.h" |
| 50 #include "platform/weborigin/SecurityOrigin.h" | 50 #include "platform/weborigin/SecurityOrigin.h" |
| 51 #include "wtf/Assertions.h" | 51 #include "wtf/Assertions.h" |
| 52 | 52 |
| 53 namespace WebCore { | 53 namespace WebCore { |
| 54 | 54 |
| 55 void DocumentThreadableLoader::loadResourceSynchronously(Document* document, con
st ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoa
derOptions& options) | 55 void DocumentThreadableLoader::loadResourceSynchronously(Document& document, con
st ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoa
derOptions& options) |
| 56 { | 56 { |
| 57 // The loader will be deleted as soon as this function exits. | 57 // The loader will be deleted as soon as this function exits. |
| 58 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, &client, LoadSynchronously, request, options)); | 58 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, &client, LoadSynchronously, request, options)); |
| 59 ASSERT(loader->hasOneRef()); | 59 ASSERT(loader->hasOneRef()); |
| 60 } | 60 } |
| 61 | 61 |
| 62 PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document*
document, ThreadableLoaderClient* client, const ResourceRequest& request, const
ThreadableLoaderOptions& options) | 62 PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document&
document, ThreadableLoaderClient* client, const ResourceRequest& request, const
ThreadableLoaderOptions& options) |
| 63 { | 63 { |
| 64 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, client, LoadAsynchronously, request, options)); | 64 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoa
der(document, client, LoadAsynchronously, request, options)); |
| 65 if (!loader->resource()) | 65 if (!loader->resource()) |
| 66 loader = nullptr; | 66 loader = nullptr; |
| 67 return loader.release(); | 67 return loader.release(); |
| 68 } | 68 } |
| 69 | 69 |
| 70 DocumentThreadableLoader::DocumentThreadableLoader(Document* document, Threadabl
eLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest&
request, const ThreadableLoaderOptions& options) | 70 DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
eLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest&
request, const ThreadableLoaderOptions& options) |
| 71 : m_client(client) | 71 : m_client(client) |
| 72 , m_document(document) | 72 , m_document(document) |
| 73 , m_options(options) | 73 , m_options(options) |
| 74 , m_sameOriginRequest(securityOrigin()->canRequest(request.url())) | 74 , m_sameOriginRequest(securityOrigin()->canRequest(request.url())) |
| 75 , m_simpleRequest(true) | 75 , m_simpleRequest(true) |
| 76 , m_async(blockingBehavior == LoadAsynchronously) | 76 , m_async(blockingBehavior == LoadAsynchronously) |
| 77 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) | 77 , m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout) |
| 78 { | 78 { |
| 79 ASSERT(document); | |
| 80 ASSERT(client); | 79 ASSERT(client); |
| 81 // Setting an outgoing referer is only supported in the async code path. | 80 // Setting an outgoing referer is only supported in the async code path. |
| 82 ASSERT(m_async || request.httpReferrer().isEmpty()); | 81 ASSERT(m_async || request.httpReferrer().isEmpty()); |
| 83 | 82 |
| 84 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO
riginRequests) { | 83 if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossO
riginRequests) { |
| 85 loadRequest(request); | 84 loadRequest(request); |
| 86 return; | 85 return; |
| 87 } | 86 } |
| 88 | 87 |
| 89 if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { | 88 if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 if (m_client->isDocumentThreadableLoaderClient()) | 174 if (m_client->isDocumentThreadableLoaderClient()) |
| 176 static_cast<DocumentThreadableLoaderClient*>(m_client)->willSendRequ
est(request, redirectResponse); | 175 static_cast<DocumentThreadableLoaderClient*>(m_client)->willSendRequ
est(request, redirectResponse); |
| 177 return; | 176 return; |
| 178 } | 177 } |
| 179 | 178 |
| 180 // When using access control, only simple cross origin requests are allowed
to redirect. The new request URL must have a supported | 179 // When using access control, only simple cross origin requests are allowed
to redirect. The new request URL must have a supported |
| 181 // scheme and not contain the userinfo production. In addition, the redirect
response must pass the access control check if the | 180 // scheme and not contain the userinfo production. In addition, the redirect
response must pass the access control check if the |
| 182 // original request was not same-origin. | 181 // original request was not same-origin. |
| 183 if (m_options.crossOriginRequestPolicy == UseAccessControl) { | 182 if (m_options.crossOriginRequestPolicy == UseAccessControl) { |
| 184 | 183 |
| 185 InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document->fra
me(), resource->identifier(), m_document->frame()->loader().documentLoader(), re
directResponse, 0); | 184 InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document.fram
e(), resource->identifier(), m_document.frame()->loader().documentLoader(), redi
rectResponse, 0); |
| 186 | 185 |
| 187 bool allowRedirect = false; | 186 bool allowRedirect = false; |
| 188 String accessControlErrorDescription; | 187 String accessControlErrorDescription; |
| 189 | 188 |
| 190 if (m_simpleRequest) { | 189 if (m_simpleRequest) { |
| 191 allowRedirect = CrossOriginAccessControl::isLegalRedirectLocation(re
quest.url(), accessControlErrorDescription) | 190 allowRedirect = CrossOriginAccessControl::isLegalRedirectLocation(re
quest.url(), accessControlErrorDescription) |
| 192 && (m_sameOriginRequest || passesAccessControlCheck(
redirectResponse, m_options.allowCredentials, securityOrigin(), accessControlErr
orDescription)); | 191 && (m_sameOriginRequest || passesAccessControlCheck(
redirectResponse, m_options.allowCredentials, securityOrigin(), accessControlErr
orDescription)); |
| 193 } else { | 192 } else { |
| 194 accessControlErrorDescription = "The request was redirected to '"+ r
equest.url().string() + "', which is disallowed for cross-origin requests that r
equire preflight."; | 193 accessControlErrorDescription = "The request was redirected to '"+ r
equest.url().string() + "', which is disallowed for cross-origin requests that r
equire preflight."; |
| 195 } | 194 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, cons
t ResourceResponse& response) | 256 void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, cons
t ResourceResponse& response) |
| 258 { | 257 { |
| 259 ASSERT(m_client); | 258 ASSERT(m_client); |
| 260 | 259 |
| 261 String accessControlErrorDescription; | 260 String accessControlErrorDescription; |
| 262 if (m_actualRequest) { | 261 if (m_actualRequest) { |
| 263 // Notifying the inspector here is necessary because a call to preflight
Failure() might synchronously | 262 // Notifying the inspector here is necessary because a call to preflight
Failure() might synchronously |
| 264 // cause the underlying ResourceLoader to be cancelled before it tells t
he inspector about the response. | 263 // cause the underlying ResourceLoader to be cancelled before it tells t
he inspector about the response. |
| 265 // In that case, if we don't tell the inspector about the response now,
the resource type in the inspector | 264 // In that case, if we don't tell the inspector about the response now,
the resource type in the inspector |
| 266 // will default to "other" instead of something more descriptive. | 265 // will default to "other" instead of something more descriptive. |
| 267 DocumentLoader* loader = m_document->frame()->loader().documentLoader(); | 266 DocumentLoader* loader = m_document.frame()->loader().documentLoader(); |
| 268 InspectorInstrumentation::didReceiveResourceResponse(m_document->frame()
, identifier, loader, response, resource() ? resource()->loader() : 0); | 267 InspectorInstrumentation::didReceiveResourceResponse(m_document.frame(),
identifier, loader, response, resource() ? resource()->loader() : 0); |
| 269 | 268 |
| 270 if (!passesAccessControlCheck(response, m_options.allowCredentials, secu
rityOrigin(), accessControlErrorDescription)) { | 269 if (!passesAccessControlCheck(response, m_options.allowCredentials, secu
rityOrigin(), accessControlErrorDescription)) { |
| 271 preflightFailure(response.url().string(), accessControlErrorDescript
ion); | 270 preflightFailure(response.url().string(), accessControlErrorDescript
ion); |
| 272 return; | 271 return; |
| 273 } | 272 } |
| 274 | 273 |
| 275 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)
) { | 274 if (!passesPreflightStatusCheck(response, accessControlErrorDescription)
) { |
| 276 preflightFailure(response.url().string(), accessControlErrorDescript
ion); | 275 preflightFailure(response.url().string(), accessControlErrorDescript
ion); |
| 277 return; | 276 return; |
| 278 } | 277 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 if (m_actualRequest) { | 377 if (m_actualRequest) { |
| 379 options.sniffContent = DoNotSniffContent; | 378 options.sniffContent = DoNotSniffContent; |
| 380 options.dataBufferingPolicy = BufferData; | 379 options.dataBufferingPolicy = BufferData; |
| 381 } | 380 } |
| 382 | 381 |
| 383 if (m_options.timeoutMilliseconds > 0) | 382 if (m_options.timeoutMilliseconds > 0) |
| 384 m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0,
FROM_HERE); | 383 m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0,
FROM_HERE); |
| 385 | 384 |
| 386 FetchRequest newRequest(request, m_options.initiator, options); | 385 FetchRequest newRequest(request, m_options.initiator, options); |
| 387 ASSERT(!resource()); | 386 ASSERT(!resource()); |
| 388 setResource(m_document->fetcher()->fetchRawResource(newRequest)); | 387 setResource(m_document.fetcher()->fetchRawResource(newRequest)); |
| 389 if (resource() && resource()->loader()) { | 388 if (resource() && resource()->loader()) { |
| 390 unsigned long identifier = resource()->identifier(); | 389 unsigned long identifier = resource()->identifier(); |
| 391 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForC
lient(m_document, identifier, m_client); | 390 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForC
lient(&m_document, identifier, m_client); |
| 392 } | 391 } |
| 393 return; | 392 return; |
| 394 } | 393 } |
| 395 | 394 |
| 396 FetchRequest fetchRequest(request, m_options.initiator, options); | 395 FetchRequest fetchRequest(request, m_options.initiator, options); |
| 397 ResourcePtr<Resource> resource = m_document->fetcher()->fetchSynchronously(f
etchRequest); | 396 ResourcePtr<Resource> resource = m_document.fetcher()->fetchSynchronously(fe
tchRequest); |
| 398 ResourceResponse response = resource ? resource->response() : ResourceRespon
se(); | 397 ResourceResponse response = resource ? resource->response() : ResourceRespon
se(); |
| 399 unsigned long identifier = resource ? resource->identifier() : std::numeric_
limits<unsigned long>::max(); | 398 unsigned long identifier = resource ? resource->identifier() : std::numeric_
limits<unsigned long>::max(); |
| 400 ResourceError error = resource ? resource->resourceError() : ResourceError()
; | 399 ResourceError error = resource ? resource->resourceError() : ResourceError()
; |
| 401 | 400 |
| 402 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_
document, identifier, m_client); | 401 InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(&m
_document, identifier, m_client); |
| 403 | 402 |
| 404 if (!resource) { | 403 if (!resource) { |
| 405 m_client->didFail(error); | 404 m_client->didFail(error); |
| 406 return; | 405 return; |
| 407 } | 406 } |
| 408 | 407 |
| 409 // No exception for file:/// resources, see <rdar://problem/4962298>. | 408 // No exception for file:/// resources, see <rdar://problem/4962298>. |
| 410 // Also, if we have an HTTP response, then it wasn't a network error in fact
. | 409 // Also, if we have an HTTP response, then it wasn't a network error in fact
. |
| 411 if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode(
) <= 0) { | 410 if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode(
) <= 0) { |
| 412 m_client->didFail(error); | 411 m_client->didFail(error); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 435 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) | 434 if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) |
| 436 return true; | 435 return true; |
| 437 | 436 |
| 438 return m_sameOriginRequest && securityOrigin()->canRequest(url); | 437 return m_sameOriginRequest && securityOrigin()->canRequest(url); |
| 439 } | 438 } |
| 440 | 439 |
| 441 bool DocumentThreadableLoader::isAllowedByPolicy(const KURL& url) const | 440 bool DocumentThreadableLoader::isAllowedByPolicy(const KURL& url) const |
| 442 { | 441 { |
| 443 if (m_options.contentSecurityPolicyEnforcement != EnforceConnectSrcDirective
) | 442 if (m_options.contentSecurityPolicyEnforcement != EnforceConnectSrcDirective
) |
| 444 return true; | 443 return true; |
| 445 return m_document->contentSecurityPolicy()->allowConnectToSource(url); | 444 return m_document.contentSecurityPolicy()->allowConnectToSource(url); |
| 446 } | 445 } |
| 447 | 446 |
| 448 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const | 447 SecurityOrigin* DocumentThreadableLoader::securityOrigin() const |
| 449 { | 448 { |
| 450 return m_options.securityOrigin ? m_options.securityOrigin.get() : m_documen
t->securityOrigin(); | 449 return m_options.securityOrigin ? m_options.securityOrigin.get() : m_documen
t.securityOrigin(); |
| 451 } | 450 } |
| 452 | 451 |
| 453 } // namespace WebCore | 452 } // namespace WebCore |
| OLD | NEW |