OLD | NEW |
1 /* | 1 /* |
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
rights reserved. | 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
rights reserved. |
6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
7 | 7 |
8 This library is free software; you can redistribute it and/or | 8 This library is free software; you can redistribute it and/or |
9 modify it under the terms of the GNU Library General Public | 9 modify it under the terms of the GNU Library General Public |
10 License as published by the Free Software Foundation; either | 10 License as published by the Free Software Foundation; either |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 return 0; | 258 return 0; |
259 } | 259 } |
260 | 260 |
261 FetchContext& ResourceFetcher::context() const | 261 FetchContext& ResourceFetcher::context() const |
262 { | 262 { |
263 if (Frame* frame = this->frame()) | 263 if (Frame* frame = this->frame()) |
264 return frame->fetchContext(); | 264 return frame->fetchContext(); |
265 return FetchContext::nullInstance(); | 265 return FetchContext::nullInstance(); |
266 } | 266 } |
267 | 267 |
268 ResourcePtr<Resource> ResourceFetcher::fetchSynchronously(FetchRequest& request) | 268 ResourcePtr<Resource> ResourceFetcher::fetchSynchronously(FetchRequest& request,
OriginRestriction originRestriction) |
269 { | 269 { |
270 ASSERT(document()); | 270 ASSERT(document()); |
271 request.mutableResourceRequest().setTimeoutInterval(10); | 271 request.mutableResourceRequest().setTimeoutInterval(10); |
272 ResourceLoaderOptions options(request.options()); | 272 ResourceLoaderOptions options(request.options()); |
273 options.synchronousPolicy = RequestSynchronously; | 273 options.synchronousPolicy = RequestSynchronously; |
274 request.setOptions(options); | 274 request.setOptions(options); |
275 return requestResource(Resource::Raw, request); | 275 return requestResource(Resource::Raw, request, originRestriction); |
276 } | 276 } |
277 | 277 |
278 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request) | 278 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request, Or
iginRestriction originRestriction) |
279 { | 279 { |
280 if (Frame* f = frame()) { | 280 if (Frame* f = frame()) { |
281 if (f->document()->pageDismissalEventBeingDispatched() != Document::NoDi
smissal) { | 281 if (f->document()->pageDismissalEventBeingDispatched() != Document::NoDi
smissal) { |
282 KURL requestURL = request.resourceRequest().url(); | 282 KURL requestURL = request.resourceRequest().url(); |
283 if (requestURL.isValid() && canRequest(Resource::Image, requestURL,
request.options(), request.forPreload())) | 283 if (requestURL.isValid() && canRequest(Resource::Image, requestURL,
request.options(), request.forPreload(), originRestriction)) |
284 PingLoader::loadImage(f, requestURL); | 284 PingLoader::loadImage(f, requestURL); |
285 return 0; | 285 return 0; |
286 } | 286 } |
287 } | 287 } |
288 | 288 |
289 if (request.resourceRequest().url().protocolIsData()) | 289 if (request.resourceRequest().url().protocolIsData()) |
290 preCacheDataURIImage(request); | 290 preCacheDataURIImage(request); |
291 | 291 |
292 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? FetchR
equest::DeferredByClient : FetchRequest::NoDefer); | 292 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? FetchR
equest::DeferredByClient : FetchRequest::NoDefer); |
293 return static_cast<ImageResource*>(requestResource(Resource::Image, request)
.get()); | 293 return static_cast<ImageResource*>(requestResource(Resource::Image, request)
.get()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 ResourcePtr<CSSStyleSheetResource> ResourceFetcher::fetchUserCSSStyleSheet(Fetch
Request& request) | 333 ResourcePtr<CSSStyleSheetResource> ResourceFetcher::fetchUserCSSStyleSheet(Fetch
Request& request) |
334 { | 334 { |
335 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.resourceReq
uest().url()); | 335 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.resourceReq
uest().url()); |
336 | 336 |
337 if (Resource* existing = memoryCache()->resourceForURL(url)) { | 337 if (Resource* existing = memoryCache()->resourceForURL(url)) { |
338 if (existing->type() == Resource::CSSStyleSheet) | 338 if (existing->type() == Resource::CSSStyleSheet) |
339 return static_cast<CSSStyleSheetResource*>(existing); | 339 return static_cast<CSSStyleSheetResource*>(existing); |
340 memoryCache()->remove(existing); | 340 memoryCache()->remove(existing); |
341 } | 341 } |
342 | 342 |
343 request.setOptions(ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, B
ufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientForCross
OriginCredentials, SkipSecurityCheck, CheckContentSecurityPolicy, UseDefaultOrig
inRestrictionsForType, DocumentContext)); | 343 request.setOptions(ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, B
ufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientForCross
OriginCredentials, SkipSecurityCheck, CheckContentSecurityPolicy, DocumentContex
t)); |
344 return static_cast<CSSStyleSheetResource*>(requestResource(Resource::CSSStyl
eSheet, request).get()); | 344 return static_cast<CSSStyleSheetResource*>(requestResource(Resource::CSSStyl
eSheet, request).get()); |
345 } | 345 } |
346 | 346 |
347 ResourcePtr<ScriptResource> ResourceFetcher::fetchScript(FetchRequest& request) | 347 ResourcePtr<ScriptResource> ResourceFetcher::fetchScript(FetchRequest& request) |
348 { | 348 { |
349 return static_cast<ScriptResource*>(requestResource(Resource::Script, reques
t).get()); | 349 return static_cast<ScriptResource*>(requestResource(Resource::Script, reques
t).get()); |
350 } | 350 } |
351 | 351 |
352 ResourcePtr<XSLStyleSheetResource> ResourceFetcher::fetchXSLStyleSheet(FetchRequ
est& request) | 352 ResourcePtr<XSLStyleSheetResource> ResourceFetcher::fetchXSLStyleSheet(FetchRequ
est& request) |
353 { | 353 { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 Frame* top = f->tree().top(); | 422 Frame* top = f->tree().top(); |
423 if (!top->loader().mixedContentChecker()->canDisplayInsecureContent(
top->document()->securityOrigin(), url)) | 423 if (!top->loader().mixedContentChecker()->canDisplayInsecureContent(
top->document()->securityOrigin(), url)) |
424 return false; | 424 return false; |
425 } | 425 } |
426 } else { | 426 } else { |
427 ASSERT(treatment == TreatAsAlwaysAllowedContent); | 427 ASSERT(treatment == TreatAsAlwaysAllowedContent); |
428 } | 428 } |
429 return true; | 429 return true; |
430 } | 430 } |
431 | 431 |
432 bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res
ourceLoaderOptions& options, bool forPreload) | 432 bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res
ourceLoaderOptions& options, bool forPreload, OriginRestriction originRestrictio
n) |
433 { | 433 { |
434 if (document() && !document()->securityOrigin()->canDisplay(url)) { | 434 if (document() && !document()->securityOrigin()->canDisplay(url)) { |
435 if (!forPreload) | 435 if (!forPreload) |
436 context().reportLocalLoadFailed(url); | 436 context().reportLocalLoadFailed(url); |
437 LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not allow
ed by SecurityOrigin::canDisplay"); | 437 LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not allow
ed by SecurityOrigin::canDisplay"); |
438 return 0; | 438 return 0; |
439 } | 439 } |
440 | 440 |
441 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. | 441 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. |
442 bool shouldBypassMainWorldContentSecurityPolicy = (frame() && frame()->scrip
t().shouldBypassMainWorldContentSecurityPolicy()) || (options.contentSecurityPol
icyOption == DoNotCheckContentSecurityPolicy); | 442 bool shouldBypassMainWorldContentSecurityPolicy = (frame() && frame()->scrip
t().shouldBypassMainWorldContentSecurityPolicy()) || (options.contentSecurityPol
icyOption == DoNotCheckContentSecurityPolicy); |
443 | 443 |
444 // Some types of resources can be loaded only from the same origin. Other | 444 // Some types of resources can be loaded only from the same origin. Other |
445 // types of resources, like Images, Scripts, and CSS, can be loaded from | 445 // types of resources, like Images, Scripts, and CSS, can be loaded from |
446 // any URL. | 446 // any URL. |
447 switch (type) { | 447 switch (type) { |
448 case Resource::MainResource: | 448 case Resource::MainResource: |
449 case Resource::Image: | 449 case Resource::Image: |
450 case Resource::CSSStyleSheet: | 450 case Resource::CSSStyleSheet: |
451 case Resource::Script: | 451 case Resource::Script: |
452 case Resource::Font: | 452 case Resource::Font: |
453 case Resource::Raw: | 453 case Resource::Raw: |
454 case Resource::LinkPrefetch: | 454 case Resource::LinkPrefetch: |
455 case Resource::LinkSubresource: | 455 case Resource::LinkSubresource: |
456 case Resource::TextTrack: | 456 case Resource::TextTrack: |
457 case Resource::Shader: | 457 case Resource::Shader: |
458 case Resource::ImportResource: | 458 case Resource::ImportResource: |
459 // By default these types of resources can be loaded from any origin. | 459 // By default these types of resources can be loaded from any origin. |
460 // FIXME: Are we sure about Resource::Font? | 460 // FIXME: Are we sure about Resource::Font? |
461 if (options.requestOriginPolicy == RestrictToSameOrigin && !m_document->
securityOrigin()->canRequest(url)) { | 461 if (originRestriction == RestrictToSameOrigin && !m_document->securityOr
igin()->canRequest(url)) { |
462 printAccessDeniedMessage(url); | 462 printAccessDeniedMessage(url); |
463 return false; | 463 return false; |
464 } | 464 } |
465 break; | 465 break; |
466 case Resource::XSLStyleSheet: | 466 case Resource::XSLStyleSheet: |
467 ASSERT(RuntimeEnabledFeatures::xsltEnabled()); | 467 ASSERT(RuntimeEnabledFeatures::xsltEnabled()); |
468 case Resource::SVGDocument: | 468 case Resource::SVGDocument: |
469 if (!m_document->securityOrigin()->canRequest(url)) { | 469 if (!m_document->securityOrigin()->canRequest(url)) { |
470 printAccessDeniedMessage(url); | 470 printAccessDeniedMessage(url); |
471 return false; | 471 return false; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 // folks block insecure content with a CSP policy, they don't get a warning. | 525 // folks block insecure content with a CSP policy, they don't get a warning. |
526 // They'll still get a warning in the console about CSP blocking the load. | 526 // They'll still get a warning in the console about CSP blocking the load. |
527 | 527 |
528 // FIXME: Should we consider forPreload here? | 528 // FIXME: Should we consider forPreload here? |
529 if (!checkInsecureContent(type, url, options.mixedContentBlockingTreatment)) | 529 if (!checkInsecureContent(type, url, options.mixedContentBlockingTreatment)) |
530 return false; | 530 return false; |
531 | 531 |
532 return true; | 532 return true; |
533 } | 533 } |
534 | 534 |
535 bool ResourceFetcher::canAccess(Resource* resource) | 535 bool ResourceFetcher::canAccess(Resource* resource, CrossOriginEnabled crossOrig
inEnabled, OriginRestriction originRestriction) |
536 { | 536 { |
537 // Redirects can change the response URL different from one of request. | 537 // Redirects can change the response URL different from one of request. |
538 if (!canRequest(resource->type(), resource->response().url(), resource->opti
ons(), false)) | 538 if (!canRequest(resource->type(), resource->response().url(), resource->opti
ons(), false, originRestriction)) |
539 return false; | 539 return false; |
540 | 540 |
541 String error; | 541 String error; |
542 switch (resource->type()) { | 542 switch (resource->type()) { |
543 case Resource::Script: | 543 case Resource::Script: |
544 case Resource::ImportResource: | 544 case Resource::ImportResource: |
545 if (resource->options().requestOriginPolicy == PotentiallyCrossOriginEna
bled | 545 if (crossOriginEnabled == PotentiallyCrossOriginEnabled |
546 && !m_document->securityOrigin()->canRequest(resource->response().ur
l()) | 546 && !m_document->securityOrigin()->canRequest(resource->response().ur
l()) |
547 && !resource->passesAccessControlCheck(m_document->securityOrigin(),
error)) { | 547 && !resource->passesAccessControlCheck(m_document->securityOrigin(),
error)) { |
548 if (frame() && frame()->document()) | 548 if (frame() && frame()->document()) |
549 frame()->document()->addConsoleMessage(JSMessageSource, ErrorMes
sageLevel, "Script from origin '" + SecurityOrigin::create(resource->response().
url())->toString() + "' has been blocked from loading by Cross-Origin Resource S
haring policy: " + error); | 549 frame()->document()->addConsoleMessage(JSMessageSource, ErrorMes
sageLevel, "Script from origin '" + SecurityOrigin::create(resource->response().
url())->toString() + "' has been blocked from loading by Cross-Origin Resource S
haring policy: " + error); |
550 return false; | 550 return false; |
551 } | 551 } |
552 | 552 |
553 break; | 553 break; |
554 default: | 554 default: |
555 ASSERT_NOT_REACHED(); // FIXME: generalize to non-script resources | 555 ASSERT_NOT_REACHED(); // FIXME: generalize to non-script resources |
(...skipping 16 matching lines...) Expand all Loading... |
572 { | 572 { |
573 if (FetchRequest::DeferredByClient == request.defer()) | 573 if (FetchRequest::DeferredByClient == request.defer()) |
574 return false; | 574 return false; |
575 if (policy != Use) | 575 if (policy != Use) |
576 return true; | 576 return true; |
577 if (resource->stillNeedsLoad()) | 577 if (resource->stillNeedsLoad()) |
578 return true; | 578 return true; |
579 return request.options().synchronousPolicy == RequestSynchronously && resour
ce->isLoading(); | 579 return request.options().synchronousPolicy == RequestSynchronously && resour
ce->isLoading(); |
580 } | 580 } |
581 | 581 |
582 ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
hRequest& request) | 582 ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
hRequest& request, OriginRestriction originRestriction) |
583 { | 583 { |
584 ASSERT(request.options().synchronousPolicy == RequestAsynchronously || type
== Resource::Raw); | 584 ASSERT(request.options().synchronousPolicy == RequestAsynchronously || type
== Resource::Raw); |
585 | 585 |
586 KURL url = request.resourceRequest().url(); | 586 KURL url = request.resourceRequest().url(); |
587 | 587 |
588 LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s', p
riority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), request
.charset().latin1().data(), request.priority(), request.forPreload(), ResourceTy
peName(type)); | 588 LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s', p
riority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), request
.charset().latin1().data(), request.priority(), request.forPreload(), ResourceTy
peName(type)); |
589 | 589 |
590 // If only the fragment identifiers differ, it is the same resource. | 590 // If only the fragment identifiers differ, it is the same resource. |
591 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); | 591 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); |
592 | 592 |
593 if (!url.isValid()) | 593 if (!url.isValid()) |
594 return 0; | 594 return 0; |
595 | 595 |
596 if (!canRequest(type, url, request.options(), request.forPreload())) | 596 if (!canRequest(type, url, request.options(), request.forPreload(), originRe
striction)) |
597 return 0; | 597 return 0; |
598 | 598 |
599 if (Frame* f = frame()) | 599 if (Frame* f = frame()) |
600 f->loader().client()->dispatchWillRequestResource(&request); | 600 f->loader().client()->dispatchWillRequestResource(&request); |
601 | 601 |
602 // See if we can use an existing resource from the cache. | 602 // See if we can use an existing resource from the cache. |
603 ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url); | 603 ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url); |
604 | 604 |
605 const RevalidationPolicy policy = determineRevalidationPolicy(type, request.
mutableResourceRequest(), request.forPreload(), resource.get(), request.defer())
; | 605 const RevalidationPolicy policy = determineRevalidationPolicy(type, request.
mutableResourceRequest(), request.forPreload(), resource.get(), request.defer())
; |
606 switch (policy) { | 606 switch (policy) { |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 return false; | 1254 return false; |
1255 } | 1255 } |
1256 | 1256 |
1257 bool ResourceFetcher::isLoadedBy(ResourceLoaderHost* possibleOwner) const | 1257 bool ResourceFetcher::isLoadedBy(ResourceLoaderHost* possibleOwner) const |
1258 { | 1258 { |
1259 return this == possibleOwner; | 1259 return this == possibleOwner; |
1260 } | 1260 } |
1261 | 1261 |
1262 bool ResourceFetcher::shouldRequest(Resource* resource, const ResourceRequest& r
equest, const ResourceLoaderOptions& options) | 1262 bool ResourceFetcher::shouldRequest(Resource* resource, const ResourceRequest& r
equest, const ResourceLoaderOptions& options) |
1263 { | 1263 { |
1264 if (!canRequest(resource->type(), request.url(), options)) | 1264 if (!canRequest(resource->type(), request.url(), options, false, UseDefaultO
riginRestrictionForType)) |
1265 return false; | 1265 return false; |
1266 if (resource->type() == Resource::Image && shouldDeferImageLoad(request.url(
))) | 1266 if (resource->type() == Resource::Image && shouldDeferImageLoad(request.url(
))) |
1267 return false; | 1267 return false; |
1268 return true; | 1268 return true; |
1269 } | 1269 } |
1270 | 1270 |
1271 void ResourceFetcher::refResourceLoaderHost() | 1271 void ResourceFetcher::refResourceLoaderHost() |
1272 { | 1272 { |
1273 ref(); | 1273 ref(); |
1274 } | 1274 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 printf("SCRIPTS: %d (%d hits, hit rate %d%%)\n", scripts, scripts - scri
ptMisses, (scripts - scriptMisses) * 100 / scripts); | 1322 printf("SCRIPTS: %d (%d hits, hit rate %d%%)\n", scripts, scripts - scri
ptMisses, (scripts - scriptMisses) * 100 / scripts); |
1323 if (stylesheets) | 1323 if (stylesheets) |
1324 printf("STYLESHEETS: %d (%d hits, hit rate %d%%)\n", stylesheets, styles
heets - stylesheetMisses, (stylesheets - stylesheetMisses) * 100 / stylesheets); | 1324 printf("STYLESHEETS: %d (%d hits, hit rate %d%%)\n", stylesheets, styles
heets - stylesheetMisses, (stylesheets - stylesheetMisses) * 100 / stylesheets); |
1325 if (images) | 1325 if (images) |
1326 printf("IMAGES: %d (%d hits, hit rate %d%%)\n", images, images - imageM
isses, (images - imageMisses) * 100 / images); | 1326 printf("IMAGES: %d (%d hits, hit rate %d%%)\n", images, images - imageM
isses, (images - imageMisses) * 100 / images); |
1327 } | 1327 } |
1328 #endif | 1328 #endif |
1329 | 1329 |
1330 const ResourceLoaderOptions& ResourceFetcher::defaultResourceOptions() | 1330 const ResourceLoaderOptions& ResourceFetcher::defaultResourceOptions() |
1331 { | 1331 { |
1332 DEFINE_STATIC_LOCAL(ResourceLoaderOptions, options, (SendCallbacks, SniffCon
tent, BufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientF
orCrossOriginCredentials, DoSecurityCheck, CheckContentSecurityPolicy, UseDefaul
tOriginRestrictionsForType, DocumentContext)); | 1332 DEFINE_STATIC_LOCAL(ResourceLoaderOptions, options, (SendCallbacks, SniffCon
tent, BufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientF
orCrossOriginCredentials, DoSecurityCheck, CheckContentSecurityPolicy, DocumentC
ontext)); |
1333 return options; | 1333 return options; |
1334 } | 1334 } |
1335 | 1335 |
1336 } | 1336 } |
OLD | NEW |