| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 #include "core/timing/ResourceTimingInfo.h" | 61 #include "core/timing/ResourceTimingInfo.h" |
| 62 #include "core/frame/Settings.h" | 62 #include "core/frame/Settings.h" |
| 63 #include "core/svg/graphics/SVGImageChromeClient.h" | 63 #include "core/svg/graphics/SVGImageChromeClient.h" |
| 64 #include "platform/Logging.h" | 64 #include "platform/Logging.h" |
| 65 #include "platform/RuntimeEnabledFeatures.h" | 65 #include "platform/RuntimeEnabledFeatures.h" |
| 66 #include "platform/TraceEvent.h" | 66 #include "platform/TraceEvent.h" |
| 67 #include "platform/weborigin/SecurityOrigin.h" | 67 #include "platform/weborigin/SecurityOrigin.h" |
| 68 #include "platform/weborigin/SecurityPolicy.h" | 68 #include "platform/weborigin/SecurityPolicy.h" |
| 69 #include "public/platform/Platform.h" | 69 #include "public/platform/Platform.h" |
| 70 #include "public/platform/WebURL.h" | 70 #include "public/platform/WebURL.h" |
| 71 #include "public/platform/WebURLRequest.h" | |
| 72 #include "wtf/text/CString.h" | 71 #include "wtf/text/CString.h" |
| 73 #include "wtf/text/WTFString.h" | 72 #include "wtf/text/WTFString.h" |
| 74 | 73 |
| 75 #define PRELOAD_DEBUG 0 | 74 #define PRELOAD_DEBUG 0 |
| 76 | 75 |
| 77 using blink::WebURLRequest; | 76 using blink::WebURLRequest; |
| 78 | 77 |
| 79 namespace blink { | 78 namespace blink { |
| 80 | 79 |
| 81 static Resource* createResource(Resource::Type type, const ResourceRequest& requ
est, const String& charset) | 80 static Resource* createResource(Resource::Type type, const ResourceRequest& requ
est, const String& charset) |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 ASSERT(document()); | 277 ASSERT(document()); |
| 279 request.mutableResourceRequest().setTimeoutInterval(10); | 278 request.mutableResourceRequest().setTimeoutInterval(10); |
| 280 ResourceLoaderOptions options(request.options()); | 279 ResourceLoaderOptions options(request.options()); |
| 281 options.synchronousPolicy = RequestSynchronously; | 280 options.synchronousPolicy = RequestSynchronously; |
| 282 request.setOptions(options); | 281 request.setOptions(options); |
| 283 return requestResource(Resource::Raw, request); | 282 return requestResource(Resource::Raw, request); |
| 284 } | 283 } |
| 285 | 284 |
| 286 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request) | 285 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request) |
| 287 { | 286 { |
| 287 request.mutableResourceRequest().setRequestContext(WebURLRequest::RequestCon
textImage); |
| 288 if (LocalFrame* f = frame()) { | 288 if (LocalFrame* f = frame()) { |
| 289 if (f->document()->pageDismissalEventBeingDispatched() != Document::NoDi
smissal) { | 289 if (f->document()->pageDismissalEventBeingDispatched() != Document::NoDi
smissal) { |
| 290 KURL requestURL = request.resourceRequest().url(); | 290 KURL requestURL = request.resourceRequest().url(); |
| 291 if (requestURL.isValid() && canRequest(Resource::Image, requestURL,
request.options(), request.forPreload(), request.originRestriction())) | 291 if (requestURL.isValid() && canRequest(Resource::Image, WebURLReques
t::RequestContextPing, requestURL, request.options(), request.forPreload(), requ
est.originRestriction())) |
| 292 PingLoader::loadImage(f, requestURL); | 292 PingLoader::loadImage(f, requestURL); |
| 293 return 0; | 293 return 0; |
| 294 } | 294 } |
| 295 } | 295 } |
| 296 | 296 |
| 297 if (request.resourceRequest().url().protocolIsData()) | 297 if (request.resourceRequest().url().protocolIsData()) |
| 298 preCacheDataURIImage(request); | 298 preCacheDataURIImage(request); |
| 299 | 299 |
| 300 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? FetchR
equest::DeferredByClient : FetchRequest::NoDefer); | 300 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? FetchR
equest::DeferredByClient : FetchRequest::NoDefer); |
| 301 ResourcePtr<Resource> resource = requestResource(Resource::Image, request); | 301 ResourcePtr<Resource> resource = requestResource(Resource::Image, request); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 ASSERT_NOT_REACHED(); | 497 ASSERT_NOT_REACHED(); |
| 498 } | 498 } |
| 499 } | 499 } |
| 500 } | 500 } |
| 501 } else { | 501 } else { |
| 502 ASSERT(treatment == TreatAsAlwaysAllowedContent); | 502 ASSERT(treatment == TreatAsAlwaysAllowedContent); |
| 503 } | 503 } |
| 504 return true; | 504 return true; |
| 505 } | 505 } |
| 506 | 506 |
| 507 bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res
ourceLoaderOptions& options, bool forPreload, FetchRequest::OriginRestriction or
iginRestriction) const | 507 bool ResourceFetcher::canRequest(Resource::Type type, WebURLRequest::RequestCont
ext requestContext, const KURL& url, const ResourceLoaderOptions& options, bool
forPreload, FetchRequest::OriginRestriction originRestriction) const |
| 508 { | 508 { |
| 509 ASSERT(requestContext != blink::WebURLRequest::RequestContextUnspecified); |
| 509 SecurityOrigin* securityOrigin = options.securityOrigin.get(); | 510 SecurityOrigin* securityOrigin = options.securityOrigin.get(); |
| 510 if (!securityOrigin && document()) | 511 if (!securityOrigin && document()) |
| 511 securityOrigin = document()->securityOrigin(); | 512 securityOrigin = document()->securityOrigin(); |
| 512 | 513 |
| 513 if (originRestriction != FetchRequest::NoOriginRestriction && securityOrigin
&& !securityOrigin->canDisplay(url)) { | 514 if (originRestriction != FetchRequest::NoOriginRestriction && securityOrigin
&& !securityOrigin->canDisplay(url)) { |
| 514 if (!forPreload) | 515 if (!forPreload) |
| 515 context().reportLocalLoadFailed(url); | 516 context().reportLocalLoadFailed(url); |
| 516 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not a
llowed by SecurityOrigin::canDisplay"); | 517 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not a
llowed by SecurityOrigin::canDisplay"); |
| 517 return 0; | 518 return 0; |
| 518 } | 519 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 549 break; | 550 break; |
| 550 } | 551 } |
| 551 | 552 |
| 552 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. | 553 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. |
| 553 bool shouldBypassMainWorldCSP = (frame() && frame()->script().shouldBypassMa
inWorldCSP()) || (options.contentSecurityPolicyOption == DoNotCheckContentSecuri
tyPolicy); | 554 bool shouldBypassMainWorldCSP = (frame() && frame()->script().shouldBypassMa
inWorldCSP()) || (options.contentSecurityPolicyOption == DoNotCheckContentSecuri
tyPolicy); |
| 554 | 555 |
| 555 // Don't send CSP messages for preloads, we might never actually display tho
se items. | 556 // Don't send CSP messages for preloads, we might never actually display tho
se items. |
| 556 ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ? | 557 ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ? |
| 557 ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendRepor
t; | 558 ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendRepor
t; |
| 558 | 559 |
| 559 // m_document can be null, but not in any of the cases where csp is actually
used below. | 560 if (!shouldBypassMainWorldCSP && m_document && !m_document->contentSecurityP
olicy()->allowFromSource(url, requestContext, cspReporting)) |
| 560 // ImageResourceTest.MultipartImage crashes w/o the m_document null check. | 561 return false; |
| 561 // I believe it's the Resource::Raw case. | |
| 562 const ContentSecurityPolicy* csp = m_document ? m_document->contentSecurityP
olicy() : nullptr; | |
| 563 | 562 |
| 564 // FIXME: This would be cleaner if moved this switch into an allowFromSource
() | 563 if (type == Resource::Script || type == Resource::ImportResource) { |
| 565 // helper on this object which took a Resource::Type, then this block would | |
| 566 // collapse to about 10 lines for handling Raw and Script special cases. | |
| 567 switch (type) { | |
| 568 case Resource::XSLStyleSheet: | |
| 569 ASSERT(RuntimeEnabledFeatures::xsltEnabled()); | |
| 570 if (!shouldBypassMainWorldCSP && !csp->allowScriptFromSource(url, cspRep
orting)) | |
| 571 return false; | |
| 572 break; | |
| 573 case Resource::Script: | |
| 574 case Resource::ImportResource: | |
| 575 if (!shouldBypassMainWorldCSP && !csp->allowScriptFromSource(url, cspRep
orting)) | |
| 576 return false; | |
| 577 | |
| 578 if (frame()) { | 564 if (frame()) { |
| 579 Settings* settings = frame()->settings(); | 565 Settings* settings = frame()->settings(); |
| 580 if (!frame()->loader().client()->allowScriptFromSource(!settings ||
settings->scriptEnabled(), url)) { | 566 if (!frame()->loader().client()->allowScriptFromSource(!settings ||
settings->scriptEnabled(), url)) { |
| 581 frame()->loader().client()->didNotAllowScript(); | 567 frame()->loader().client()->didNotAllowScript(); |
| 582 return false; | 568 return false; |
| 583 } | 569 } |
| 584 } | 570 } |
| 585 break; | |
| 586 case Resource::CSSStyleSheet: | |
| 587 if (!shouldBypassMainWorldCSP && !csp->allowStyleFromSource(url, cspRepo
rting)) | |
| 588 return false; | |
| 589 break; | |
| 590 case Resource::SVGDocument: | |
| 591 case Resource::Image: | |
| 592 if (!shouldBypassMainWorldCSP && !csp->allowImageFromSource(url, cspRepo
rting)) | |
| 593 return false; | |
| 594 break; | |
| 595 case Resource::Font: { | |
| 596 if (!shouldBypassMainWorldCSP && !csp->allowFontFromSource(url, cspRepor
ting)) | |
| 597 return false; | |
| 598 break; | |
| 599 } | 571 } |
| 600 case Resource::MainResource: | |
| 601 case Resource::Raw: | |
| 602 case Resource::LinkPrefetch: | |
| 603 case Resource::LinkSubresource: | |
| 604 break; | |
| 605 case Resource::Media: | |
| 606 case Resource::TextTrack: | |
| 607 if (!shouldBypassMainWorldCSP && !csp->allowMediaFromSource(url, cspRepo
rting)) | |
| 608 return false; | |
| 609 | 572 |
| 573 if (type == Resource::Media || type == Resource::TextTrack) { |
| 610 if (frame()) { | 574 if (frame()) { |
| 611 if (!frame()->loader().client()->allowMedia(url)) | 575 if (!frame()->loader().client()->allowMedia(url)) |
| 612 return false; | 576 return false; |
| 613 } | 577 } |
| 614 break; | |
| 615 } | 578 } |
| 616 | 579 |
| 617 // SVG Images have unique security rules that prevent all subresource reques
ts | 580 // SVG Images have unique security rules that prevent all subresource reques
ts |
| 618 // except for data urls. | 581 // except for data urls. |
| 619 if (type != Resource::MainResource) { | 582 if (type != Resource::MainResource) { |
| 620 if (frame() && frame()->chromeClient().isSVGImageChromeClient() && !url.
protocolIsData()) | 583 if (frame() && frame()->chromeClient().isSVGImageChromeClient() && !url.
protocolIsData()) |
| 621 return false; | 584 return false; |
| 622 } | 585 } |
| 623 | 586 |
| 624 // Last of all, check for insecure content. We do this last so that when | 587 // Last of all, check for insecure content. We do this last so that when |
| 625 // folks block insecure content with a CSP policy, they don't get a warning. | 588 // folks block insecure content with a CSP policy, they don't get a warning. |
| 626 // They'll still get a warning in the console about CSP blocking the load. | 589 // They'll still get a warning in the console about CSP blocking the load. |
| 627 | 590 |
| 628 // FIXME: Should we consider forPreload here? | 591 // FIXME: Should we consider forPreload here? |
| 629 if (!checkInsecureContent(type, url, options.mixedContentBlockingTreatment)) | 592 if (!checkInsecureContent(type, url, options.mixedContentBlockingTreatment)) |
| 630 return false; | 593 return false; |
| 631 | 594 |
| 632 return true; | 595 return true; |
| 633 } | 596 } |
| 634 | 597 |
| 635 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour
ceOrigin, const KURL& url) const | 598 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour
ceOrigin, const KURL& url) const |
| 636 { | 599 { |
| 637 // Redirects can change the response URL different from one of request. | 600 // Redirects can change the response URL different from one of request. |
| 638 if (!canRequest(resource->type(), url, resource->options(), resource->isUnus
edPreload(), FetchRequest::UseDefaultOriginRestrictionForType)) | 601 if (!canRequest(resource->type(), resource->resourceRequest().requestContext
(), url, resource->options(), resource->isUnusedPreload(), FetchRequest::UseDefa
ultOriginRestrictionForType)) |
| 639 return false; | 602 return false; |
| 640 | 603 |
| 641 if (!sourceOrigin && document()) | 604 if (!sourceOrigin && document()) |
| 642 sourceOrigin = document()->securityOrigin(); | 605 sourceOrigin = document()->securityOrigin(); |
| 643 | 606 |
| 644 if (sourceOrigin->canRequest(url)) | 607 if (sourceOrigin->canRequest(url)) |
| 645 return true; | 608 return true; |
| 646 | 609 |
| 647 String errorDescription; | 610 String errorDescription; |
| 648 if (!resource->passesAccessControlCheck(sourceOrigin, errorDescription)) { | 611 if (!resource->passesAccessControlCheck(sourceOrigin, errorDescription)) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 KURL url = request.resourceRequest().url(); | 671 KURL url = request.resourceRequest().url(); |
| 709 | 672 |
| 710 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s
', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), req
uest.charset().latin1().data(), request.priority(), request.forPreload(), Resour
ceTypeName(type)); | 673 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s
', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), req
uest.charset().latin1().data(), request.priority(), request.forPreload(), Resour
ceTypeName(type)); |
| 711 | 674 |
| 712 // If only the fragment identifiers differ, it is the same resource. | 675 // If only the fragment identifiers differ, it is the same resource. |
| 713 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); | 676 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); |
| 714 | 677 |
| 715 if (!url.isValid()) | 678 if (!url.isValid()) |
| 716 return 0; | 679 return 0; |
| 717 | 680 |
| 718 if (!canRequest(type, url, request.options(), request.forPreload(), request.
originRestriction())) | 681 if (!canRequest(type, request.resourceRequest().requestContext(), url, reque
st.options(), request.forPreload(), request.originRestriction())) |
| 719 return 0; | 682 return 0; |
| 720 | 683 |
| 721 if (LocalFrame* f = frame()) | 684 if (LocalFrame* f = frame()) |
| 722 f->loader().client()->dispatchWillRequestResource(&request); | 685 f->loader().client()->dispatchWillRequestResource(&request); |
| 723 | 686 |
| 724 if (!request.forPreload()) { | 687 if (!request.forPreload()) { |
| 725 V8DOMActivityLogger* activityLogger = 0; | 688 V8DOMActivityLogger* activityLogger = 0; |
| 726 if (request.options().initiatorInfo.name == FetchInitiatorTypeNames::xml
httprequest) | 689 if (request.options().initiatorInfo.name == FetchInitiatorTypeNames::xml
httprequest) |
| 727 activityLogger = V8DOMActivityLogger::currentActivityLogger(); | 690 activityLogger = V8DOMActivityLogger::currentActivityLogger(); |
| 728 else | 691 else |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1415 return false; | 1378 return false; |
| 1416 } | 1379 } |
| 1417 | 1380 |
| 1418 bool ResourceFetcher::isLoadedBy(ResourceLoaderHost* possibleOwner) const | 1381 bool ResourceFetcher::isLoadedBy(ResourceLoaderHost* possibleOwner) const |
| 1419 { | 1382 { |
| 1420 return this == possibleOwner; | 1383 return this == possibleOwner; |
| 1421 } | 1384 } |
| 1422 | 1385 |
| 1423 bool ResourceFetcher::canAccessRedirect(Resource* resource, ResourceRequest& req
uest, const ResourceResponse& redirectResponse, ResourceLoaderOptions& options) | 1386 bool ResourceFetcher::canAccessRedirect(Resource* resource, ResourceRequest& req
uest, const ResourceResponse& redirectResponse, ResourceLoaderOptions& options) |
| 1424 { | 1387 { |
| 1425 if (!canRequest(resource->type(), request.url(), options, resource->isUnused
Preload(), FetchRequest::UseDefaultOriginRestrictionForType)) | 1388 if (!canRequest(resource->type(), request.requestContext(), request.url(), o
ptions, resource->isUnusedPreload(), FetchRequest::UseDefaultOriginRestrictionFo
rType)) |
| 1426 return false; | 1389 return false; |
| 1427 if (options.corsEnabled == IsCORSEnabled) { | 1390 if (options.corsEnabled == IsCORSEnabled) { |
| 1428 SecurityOrigin* sourceOrigin = options.securityOrigin.get(); | 1391 SecurityOrigin* sourceOrigin = options.securityOrigin.get(); |
| 1429 if (!sourceOrigin && document()) | 1392 if (!sourceOrigin && document()) |
| 1430 sourceOrigin = document()->securityOrigin(); | 1393 sourceOrigin = document()->securityOrigin(); |
| 1431 | 1394 |
| 1432 String errorMessage; | 1395 String errorMessage; |
| 1433 if (!CrossOriginAccessControl::handleRedirect(resource, sourceOrigin, re
quest, redirectResponse, options, errorMessage)) { | 1396 if (!CrossOriginAccessControl::handleRedirect(resource, sourceOrigin, re
quest, redirectResponse, options, errorMessage)) { |
| 1434 if (resource->type() == Resource::Font) | 1397 if (resource->type() == Resource::Font) |
| 1435 toFontResource(resource)->setCORSFailed(); | 1398 toFontResource(resource)->setCORSFailed(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 } | 1509 } |
| 1547 } | 1510 } |
| 1548 | 1511 |
| 1549 void ResourceFetcher::trace(Visitor* visitor) | 1512 void ResourceFetcher::trace(Visitor* visitor) |
| 1550 { | 1513 { |
| 1551 visitor->trace(m_document); | 1514 visitor->trace(m_document); |
| 1552 ResourceLoaderHost::trace(visitor); | 1515 ResourceLoaderHost::trace(visitor); |
| 1553 } | 1516 } |
| 1554 | 1517 |
| 1555 } | 1518 } |
| OLD | NEW |