| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 | 151 |
| 152 return disallowFetch; | 152 return disallowFetch; |
| 153 } | 153 } |
| 154 | 154 |
| 155 } // namespace | 155 } // namespace |
| 156 | 156 |
| 157 FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document) | 157 FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document) |
| 158 : m_document(document) | 158 : m_document(document) |
| 159 , m_documentLoader(loader) | 159 , m_documentLoader(loader) |
| 160 { | 160 { |
| 161 ASSERT(frame()); | 161 DCHECK(frame()); |
| 162 } | 162 } |
| 163 | 163 |
| 164 FrameFetchContext::~FrameFetchContext() | 164 FrameFetchContext::~FrameFetchContext() |
| 165 { | 165 { |
| 166 m_document = nullptr; | 166 m_document = nullptr; |
| 167 m_documentLoader = nullptr; | 167 m_documentLoader = nullptr; |
| 168 } | 168 } |
| 169 | 169 |
| 170 LocalFrame* FrameFetchContext::frame() const | 170 LocalFrame* FrameFetchContext::frame() const |
| 171 { | 171 { |
| 172 LocalFrame* frame = nullptr; | 172 LocalFrame* frame = nullptr; |
| 173 if (m_documentLoader) | 173 if (m_documentLoader) |
| 174 frame = m_documentLoader->frame(); | 174 frame = m_documentLoader->frame(); |
| 175 else if (m_document && m_document->importsController()) | 175 else if (m_document && m_document->importsController()) |
| 176 frame = m_document->importsController()->master()->frame(); | 176 frame = m_document->importsController()->master()->frame(); |
| 177 ASSERT(frame); | 177 DCHECK(frame); |
| 178 return frame; | 178 return frame; |
| 179 } | 179 } |
| 180 | 180 |
| 181 void FrameFetchContext::addAdditionalRequestHeaders(ResourceRequest& request, Fe
tchResourceType type) | 181 void FrameFetchContext::addAdditionalRequestHeaders(ResourceRequest& request, Fe
tchResourceType type) |
| 182 { | 182 { |
| 183 bool isMainResource = type == FetchMainResource; | 183 bool isMainResource = type == FetchMainResource; |
| 184 if (!isMainResource) { | 184 if (!isMainResource) { |
| 185 RefPtr<SecurityOrigin> outgoingOrigin; | 185 RefPtr<SecurityOrigin> outgoingOrigin; |
| 186 if (!request.didSetHTTPReferrer()) { | 186 if (!request.didSetHTTPReferrer()) { |
| 187 ASSERT(m_document); | 187 DCHECK(m_document); |
| 188 outgoingOrigin = m_document->getSecurityOrigin(); | 188 outgoingOrigin = m_document->getSecurityOrigin(); |
| 189 request.setHTTPReferrer(SecurityPolicy::generateReferrer(m_document-
>getReferrerPolicy(), request.url(), m_document->outgoingReferrer())); | 189 request.setHTTPReferrer(SecurityPolicy::generateReferrer(m_document-
>getReferrerPolicy(), request.url(), m_document->outgoingReferrer())); |
| 190 } else { | 190 } else { |
| 191 RELEASE_ASSERT(SecurityPolicy::generateReferrer(request.getReferrerP
olicy(), request.url(), request.httpReferrer()).referrer == request.httpReferrer
()); | 191 CHECK(SecurityPolicy::generateReferrer(request.getReferrerPolicy(),
request.url(), request.httpReferrer()).referrer == request.httpReferrer()); |
| 192 outgoingOrigin = SecurityOrigin::createFromString(request.httpReferr
er()); | 192 outgoingOrigin = SecurityOrigin::createFromString(request.httpReferr
er()); |
| 193 } | 193 } |
| 194 | 194 |
| 195 request.addHTTPOriginIfNeeded(outgoingOrigin.get()); | 195 request.addHTTPOriginIfNeeded(outgoingOrigin.get()); |
| 196 } | 196 } |
| 197 | 197 |
| 198 if (m_document) | 198 if (m_document) |
| 199 request.setExternalRequestStateFromRequestorAddressSpace(m_document->add
ressSpace()); | 199 request.setExternalRequestStateFromRequestorAddressSpace(m_document->add
ressSpace()); |
| 200 | 200 |
| 201 // The remaining modifications are only necessary for HTTP and HTTPS. | 201 // The remaining modifications are only necessary for HTTP and HTTPS. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 return WebCachePolicy::ValidatingCacheData; | 247 return WebCachePolicy::ValidatingCacheData; |
| 248 if (policy == CachePolicyReload) | 248 if (policy == CachePolicyReload) |
| 249 return WebCachePolicy::BypassingCache; | 249 return WebCachePolicy::BypassingCache; |
| 250 if (policy == CachePolicyHistoryBuffer) | 250 if (policy == CachePolicyHistoryBuffer) |
| 251 return WebCachePolicy::ReturnCacheDataElseLoad; | 251 return WebCachePolicy::ReturnCacheDataElseLoad; |
| 252 return WebCachePolicy::UseProtocolCachePolicy; | 252 return WebCachePolicy::UseProtocolCachePolicy; |
| 253 } | 253 } |
| 254 | 254 |
| 255 WebCachePolicy FrameFetchContext::resourceRequestCachePolicy(const ResourceReque
st& request, Resource::Type type, FetchRequest::DeferOption defer) const | 255 WebCachePolicy FrameFetchContext::resourceRequestCachePolicy(const ResourceReque
st& request, Resource::Type type, FetchRequest::DeferOption defer) const |
| 256 { | 256 { |
| 257 ASSERT(frame()); | 257 DCHECK(frame()); |
| 258 if (type == Resource::MainResource) { | 258 if (type == Resource::MainResource) { |
| 259 FrameLoadType frameLoadType = frame()->loader().loadType(); | 259 FrameLoadType frameLoadType = frame()->loader().loadType(); |
| 260 if (request.httpMethod() == "POST" && frameLoadType == FrameLoadTypeBack
Forward) | 260 if (request.httpMethod() == "POST" && frameLoadType == FrameLoadTypeBack
Forward) |
| 261 return WebCachePolicy::ReturnCacheDataDontLoad; | 261 return WebCachePolicy::ReturnCacheDataDontLoad; |
| 262 if (frameLoadType == FrameLoadTypeReloadMainResource || request.isCondit
ional() || request.httpMethod() == "POST") | 262 if (frameLoadType == FrameLoadTypeReloadMainResource || request.isCondit
ional() || request.httpMethod() == "POST") |
| 263 return WebCachePolicy::ValidatingCacheData; | 263 return WebCachePolicy::ValidatingCacheData; |
| 264 | 264 |
| 265 for (Frame* f = frame(); f; f = f->tree().parent()) { | 265 for (Frame* f = frame(); f; f = f->tree().parent()) { |
| 266 if (!f->isLocalFrame()) | 266 if (!f->isLocalFrame()) |
| 267 continue; | 267 continue; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 case Resource::Media: | 516 case Resource::Media: |
| 517 case Resource::Manifest: | 517 case Resource::Manifest: |
| 518 // By default these types of resources can be loaded from any origin. | 518 // By default these types of resources can be loaded from any origin. |
| 519 // FIXME: Are we sure about Resource::Font? | 519 // FIXME: Are we sure about Resource::Font? |
| 520 if (originRestriction == FetchRequest::RestrictToSameOrigin && !security
Origin->canRequest(url)) { | 520 if (originRestriction == FetchRequest::RestrictToSameOrigin && !security
Origin->canRequest(url)) { |
| 521 printAccessDeniedMessage(url); | 521 printAccessDeniedMessage(url); |
| 522 return ResourceRequestBlockedReasonOrigin; | 522 return ResourceRequestBlockedReasonOrigin; |
| 523 } | 523 } |
| 524 break; | 524 break; |
| 525 case Resource::XSLStyleSheet: | 525 case Resource::XSLStyleSheet: |
| 526 ASSERT(RuntimeEnabledFeatures::xsltEnabled()); | 526 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); |
| 527 case Resource::SVGDocument: | 527 case Resource::SVGDocument: |
| 528 if (!securityOrigin->canRequest(url)) { | 528 if (!securityOrigin->canRequest(url)) { |
| 529 printAccessDeniedMessage(url); | 529 printAccessDeniedMessage(url); |
| 530 return ResourceRequestBlockedReasonOrigin; | 530 return ResourceRequestBlockedReasonOrigin; |
| 531 } | 531 } |
| 532 break; | 532 break; |
| 533 } | 533 } |
| 534 | 534 |
| 535 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. | 535 // FIXME: Convert this to check the isolated world's Content Security Policy
once webkit.org/b/104520 is solved. |
| 536 bool shouldBypassMainWorldCSP = frame()->script().shouldBypassMainWorldCSP()
|| options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy; | 536 bool shouldBypassMainWorldCSP = frame()->script().shouldBypassMainWorldCSP()
|| options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy; |
| 537 | 537 |
| 538 // Don't send CSP messages for preloads, we might never actually display tho
se items. | 538 // Don't send CSP messages for preloads, we might never actually display tho
se items. |
| 539 ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ? | 539 ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ? |
| 540 ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendRepor
t; | 540 ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendRepor
t; |
| 541 | 541 |
| 542 if (m_document) { | 542 if (m_document) { |
| 543 DCHECK(m_document->contentSecurityPolicy()); | 543 DCHECK(m_document->contentSecurityPolicy()); |
| 544 if (!shouldBypassMainWorldCSP && !m_document->contentSecurityPolicy()->a
llowRequest(resourceRequest.requestContext(), url, options.contentSecurityPolicy
Nonce, options.integrityMetadata, redirectStatus, cspReporting)) | 544 if (!shouldBypassMainWorldCSP && !m_document->contentSecurityPolicy()->a
llowRequest(resourceRequest.requestContext(), url, options.contentSecurityPolicy
Nonce, options.integrityMetadata, redirectStatus, cspReporting)) |
| 545 return ResourceRequestBlockedReasonCSP; | 545 return ResourceRequestBlockedReasonCSP; |
| 546 } | 546 } |
| 547 | 547 |
| 548 if (type == Resource::Script || type == Resource::ImportResource) { | 548 if (type == Resource::Script || type == Resource::ImportResource) { |
| 549 ASSERT(frame()); | 549 DCHECK(frame()); |
| 550 if (!frame()->loader().client()->allowScriptFromSource(!frame()->setting
s() || frame()->settings()->scriptEnabled(), url)) { | 550 if (!frame()->loader().client()->allowScriptFromSource(!frame()->setting
s() || frame()->settings()->scriptEnabled(), url)) { |
| 551 frame()->loader().client()->didNotAllowScript(); | 551 frame()->loader().client()->didNotAllowScript(); |
| 552 // TODO(estark): Use a different ResourceRequestBlockedReason | 552 // TODO(estark): Use a different ResourceRequestBlockedReason |
| 553 // here, since this check has nothing to do with | 553 // here, since this check has nothing to do with |
| 554 // CSP. https://crbug.com/600795 | 554 // CSP. https://crbug.com/600795 |
| 555 return ResourceRequestBlockedReasonCSP; | 555 return ResourceRequestBlockedReasonCSP; |
| 556 } | 556 } |
| 557 } else if (type == Resource::Media || type == Resource::TextTrack) { | 557 } else if (type == Resource::Media || type == Resource::TextTrack) { |
| 558 ASSERT(frame()); | 558 DCHECK(frame()); |
| 559 if (!frame()->loader().client()->allowMedia(url)) | 559 if (!frame()->loader().client()->allowMedia(url)) |
| 560 return ResourceRequestBlockedReasonOther; | 560 return ResourceRequestBlockedReasonOther; |
| 561 } | 561 } |
| 562 | 562 |
| 563 // SVG Images have unique security rules that prevent all subresource reques
ts | 563 // SVG Images have unique security rules that prevent all subresource reques
ts |
| 564 // except for data urls. | 564 // except for data urls. |
| 565 if (type != Resource::MainResource && frame()->chromeClient().isSVGImageChro
meClient() && !url.protocolIsData()) | 565 if (type != Resource::MainResource && frame()->chromeClient().isSVGImageChro
meClient() && !url.protocolIsData()) |
| 566 return ResourceRequestBlockedReasonOrigin; | 566 return ResourceRequestBlockedReasonOrigin; |
| 567 | 567 |
| 568 // Measure the number of legacy URL schemes ('ftp://') and the number of emb
edded-credential | 568 // Measure the number of legacy URL schemes ('ftp://') and the number of emb
edded-credential |
| 569 // ('http://user:password@...') resources embedded as subresources. in the h
opes that we can | 569 // ('http://user:password@...') resources embedded as subresources. in the h
opes that we can |
| 570 // block them at some point in the future. | 570 // block them at some point in the future. |
| 571 if (resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel) { | 571 if (resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel) { |
| 572 ASSERT(frame()->document()); | 572 DCHECK(frame()->document()); |
| 573 if (SchemeRegistry::shouldTreatURLSchemeAsLegacy(url.protocol()) && !Sch
emeRegistry::shouldTreatURLSchemeAsLegacy(frame()->document()->getSecurityOrigin
()->protocol())) | 573 if (SchemeRegistry::shouldTreatURLSchemeAsLegacy(url.protocol()) && !Sch
emeRegistry::shouldTreatURLSchemeAsLegacy(frame()->document()->getSecurityOrigin
()->protocol())) |
| 574 UseCounter::count(frame()->document(), UseCounter::LegacyProtocolEmb
eddedAsSubresource); | 574 UseCounter::count(frame()->document(), UseCounter::LegacyProtocolEmb
eddedAsSubresource); |
| 575 if (!url.user().isEmpty() || !url.pass().isEmpty()) | 575 if (!url.user().isEmpty() || !url.pass().isEmpty()) |
| 576 UseCounter::count(frame()->document(), UseCounter::RequestedSubresou
rceWithEmbeddedCredentials); | 576 UseCounter::count(frame()->document(), UseCounter::RequestedSubresou
rceWithEmbeddedCredentials); |
| 577 } | 577 } |
| 578 | 578 |
| 579 // Check for mixed content. We do this second-to-last so that when folks blo
ck | 579 // Check for mixed content. We do this second-to-last so that when folks blo
ck |
| 580 // mixed content with a CSP policy, they don't get a warning. They'll still | 580 // mixed content with a CSP policy, they don't get a warning. They'll still |
| 581 // get a warning in the console about CSP blocking the load. | 581 // get a warning in the console about CSP blocking the load. |
| 582 MixedContentChecker::ReportingStatus mixedContentReporting = forPreload ? | 582 MixedContentChecker::ReportingStatus mixedContentReporting = forPreload ? |
| 583 MixedContentChecker::SuppressReport : MixedContentChecker::SendReport; | 583 MixedContentChecker::SuppressReport : MixedContentChecker::SendReport; |
| 584 if (MixedContentChecker::shouldBlockFetch(frame(), resourceRequest, url, mix
edContentReporting)) | 584 if (MixedContentChecker::shouldBlockFetch(frame(), resourceRequest, url, mix
edContentReporting)) |
| 585 return ResourceRequestBlockedReasonMixedContent; | 585 return ResourceRequestBlockedReasonMixedContent; |
| 586 | 586 |
| 587 // Let the client have the final say into whether or not the load should pro
ceed. | 587 // Let the client have the final say into whether or not the load should pro
ceed. |
| 588 DocumentLoader* documentLoader = masterDocumentLoader(); | 588 DocumentLoader* documentLoader = masterDocumentLoader(); |
| 589 if (documentLoader && documentLoader->subresourceFilter() && type != Resourc
e::MainResource && type != Resource::ImportResource && !documentLoader->subresou
rceFilter()->allowLoad(url, resourceRequest.requestContext())) | 589 if (documentLoader && documentLoader->subresourceFilter() && type != Resourc
e::MainResource && type != Resource::ImportResource && !documentLoader->subresou
rceFilter()->allowLoad(url, resourceRequest.requestContext())) |
| 590 return ResourceRequestBlockedReasonSubresourceFilter; | 590 return ResourceRequestBlockedReasonSubresourceFilter; |
| 591 | 591 |
| 592 return ResourceRequestBlockedReasonNone; | 592 return ResourceRequestBlockedReasonNone; |
| 593 } | 593 } |
| 594 | 594 |
| 595 bool FrameFetchContext::isControlledByServiceWorker() const | 595 bool FrameFetchContext::isControlledByServiceWorker() const |
| 596 { | 596 { |
| 597 ASSERT(m_documentLoader || frame()->loader().documentLoader()); | 597 DCHECK(m_documentLoader || frame()->loader().documentLoader()); |
| 598 if (m_documentLoader) | 598 if (m_documentLoader) |
| 599 return frame()->loader().client()->isControlledByServiceWorker(*m_docume
ntLoader); | 599 return frame()->loader().client()->isControlledByServiceWorker(*m_docume
ntLoader); |
| 600 // m_documentLoader is null while loading resources from an HTML import. | 600 // m_documentLoader is null while loading resources from an HTML import. |
| 601 // In such cases whether the request is controlled by ServiceWorker or not | 601 // In such cases whether the request is controlled by ServiceWorker or not |
| 602 // is determined by the document loader of the frame. | 602 // is determined by the document loader of the frame. |
| 603 return frame()->loader().client()->isControlledByServiceWorker(*frame()->loa
der().documentLoader()); | 603 return frame()->loader().client()->isControlledByServiceWorker(*frame()->loa
der().documentLoader()); |
| 604 } | 604 } |
| 605 | 605 |
| 606 int64_t FrameFetchContext::serviceWorkerID() const | 606 int64_t FrameFetchContext::serviceWorkerID() const |
| 607 { | 607 { |
| 608 ASSERT(m_documentLoader || frame()->loader().documentLoader()); | 608 DCHECK(m_documentLoader || frame()->loader().documentLoader()); |
| 609 if (m_documentLoader) | 609 if (m_documentLoader) |
| 610 return frame()->loader().client()->serviceWorkerID(*m_documentLoader); | 610 return frame()->loader().client()->serviceWorkerID(*m_documentLoader); |
| 611 // m_documentLoader is null while loading resources from an HTML import. | 611 // m_documentLoader is null while loading resources from an HTML import. |
| 612 // In such cases a service worker ID could be retrieved from the document | 612 // In such cases a service worker ID could be retrieved from the document |
| 613 // loader of the frame. | 613 // loader of the frame. |
| 614 return frame()->loader().client()->serviceWorkerID(*frame()->loader().docume
ntLoader()); | 614 return frame()->loader().client()->serviceWorkerID(*frame()->loader().docume
ntLoader()); |
| 615 } | 615 } |
| 616 | 616 |
| 617 bool FrameFetchContext::isMainFrame() const | 617 bool FrameFetchContext::isMainFrame() const |
| 618 { | 618 { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 // Auxiliary frame types in 'createWindow()' and 'FrameLoader::load'. | 753 // Auxiliary frame types in 'createWindow()' and 'FrameLoader::load'. |
| 754 if (request.frameType() == WebURLRequest::FrameTypeNone && !request.requesto
rOrigin()) { | 754 if (request.frameType() == WebURLRequest::FrameTypeNone && !request.requesto
rOrigin()) { |
| 755 request.setRequestorOrigin(m_document->isSandboxed(SandboxOrigin) | 755 request.setRequestorOrigin(m_document->isSandboxed(SandboxOrigin) |
| 756 ? SecurityOrigin::create(m_document->url()) | 756 ? SecurityOrigin::create(m_document->url()) |
| 757 : m_document->getSecurityOrigin()); | 757 : m_document->getSecurityOrigin()); |
| 758 } | 758 } |
| 759 } | 759 } |
| 760 | 760 |
| 761 MHTMLArchive* FrameFetchContext::archive() const | 761 MHTMLArchive* FrameFetchContext::archive() const |
| 762 { | 762 { |
| 763 ASSERT(!isMainFrame()); | 763 DCHECK(!isMainFrame()); |
| 764 // TODO(nasko): How should this work with OOPIF? | 764 // TODO(nasko): How should this work with OOPIF? |
| 765 // The MHTMLArchive is parsed as a whole, but can be constructed from | 765 // The MHTMLArchive is parsed as a whole, but can be constructed from |
| 766 // frames in mutliple processes. In that case, which process should parse | 766 // frames in mutliple processes. In that case, which process should parse |
| 767 // it and how should the output be spread back across multiple processes? | 767 // it and how should the output be spread back across multiple processes? |
| 768 if (!frame()->tree().parent()->isLocalFrame()) | 768 if (!frame()->tree().parent()->isLocalFrame()) |
| 769 return nullptr; | 769 return nullptr; |
| 770 return toLocalFrame(frame()->tree().parent())->loader().documentLoader()->fe
tcher()->archive(); | 770 return toLocalFrame(frame()->tree().parent())->loader().documentLoader()->fe
tcher()->archive(); |
| 771 } | 771 } |
| 772 | 772 |
| 773 void FrameFetchContext::countClientHintsDPR() | 773 void FrameFetchContext::countClientHintsDPR() |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 } | 829 } |
| 830 | 830 |
| 831 DEFINE_TRACE(FrameFetchContext) | 831 DEFINE_TRACE(FrameFetchContext) |
| 832 { | 832 { |
| 833 visitor->trace(m_document); | 833 visitor->trace(m_document); |
| 834 visitor->trace(m_documentLoader); | 834 visitor->trace(m_documentLoader); |
| 835 FetchContext::trace(visitor); | 835 FetchContext::trace(visitor); |
| 836 } | 836 } |
| 837 | 837 |
| 838 } // namespace blink | 838 } // namespace blink |
| OLD | NEW |