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 |