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