Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 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 16 matching lines...) Expand all Loading... | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 * | 29 * |
| 30 */ | 30 */ |
| 31 | 31 |
| 32 #include "core/loader/LinkLoader.h" | 32 #include "core/loader/LinkLoader.h" |
| 33 | 33 |
| 34 #include "core/css/MediaList.h" | 34 #include "core/css/MediaList.h" |
| 35 #include "core/css/MediaQueryEvaluator.h" | 35 #include "core/css/MediaQueryEvaluator.h" |
| 36 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
| 37 #include "core/frame/FrameConsole.h" | |
| 38 #include "core/frame/LocalFrame.h" | |
| 37 #include "core/frame/Settings.h" | 39 #include "core/frame/Settings.h" |
| 38 #include "core/frame/UseCounter.h" | 40 #include "core/frame/UseCounter.h" |
| 39 #include "core/html/CrossOriginAttribute.h" | 41 #include "core/html/CrossOriginAttribute.h" |
| 40 #include "core/html/LinkRelAttribute.h" | 42 #include "core/html/LinkRelAttribute.h" |
| 41 #include "core/html/parser/HTMLPreloadScanner.h" | 43 #include "core/html/parser/HTMLPreloadScanner.h" |
| 42 #include "core/inspector/ConsoleMessage.h" | 44 #include "core/inspector/ConsoleMessage.h" |
| 43 #include "core/loader/DocumentLoader.h" | 45 #include "core/loader/DocumentLoader.h" |
| 44 #include "core/loader/NetworkHintsInterface.h" | 46 #include "core/loader/NetworkHintsInterface.h" |
| 45 #include "core/loader/private/PrerenderHandle.h" | 47 #include "core/loader/private/PrerenderHandle.h" |
| 46 #include "core/loader/resource/LinkFetchResource.h" | 48 #include "core/loader/resource/LinkFetchResource.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 | 123 |
| 122 void LinkLoader::DidSendDOMContentLoadedForPrerender() { | 124 void LinkLoader::DidSendDOMContentLoadedForPrerender() { |
| 123 client_->DidSendDOMContentLoadedForLinkPrerender(); | 125 client_->DidSendDOMContentLoadedForLinkPrerender(); |
| 124 } | 126 } |
| 125 | 127 |
| 126 enum LinkCaller { | 128 enum LinkCaller { |
| 127 kLinkCalledFromHeader, | 129 kLinkCalledFromHeader, |
| 128 kLinkCalledFromMarkup, | 130 kLinkCalledFromMarkup, |
| 129 }; | 131 }; |
| 130 | 132 |
| 133 static void SendMessageToConsoleForPossiblyNullDocument( | |
|
Nate Chapin
2017/04/28 21:33:31
I hate this name, but I don't have a better idea.
kinuko
2017/04/29 14:10:20
Maybe add the same comment with the one in FrameFe
| |
| 134 ConsoleMessage* console_message, | |
| 135 Document* document, | |
| 136 LocalFrame* frame) { | |
| 137 DCHECK(document || frame); | |
| 138 DCHECK(!document || document->GetFrame() == frame); | |
| 139 if (document) | |
| 140 document->AddConsoleMessage(console_message); | |
| 141 else | |
| 142 frame->Console().AddMessage(console_message); | |
| 143 } | |
| 144 | |
| 131 static void DnsPrefetchIfNeeded( | 145 static void DnsPrefetchIfNeeded( |
| 132 const LinkRelAttribute& rel_attribute, | 146 const LinkRelAttribute& rel_attribute, |
| 133 const KURL& href, | 147 const KURL& href, |
| 134 Document& document, | 148 Document* document, |
| 149 LocalFrame* frame, | |
| 135 const NetworkHintsInterface& network_hints_interface, | 150 const NetworkHintsInterface& network_hints_interface, |
| 136 LinkCaller caller) { | 151 LinkCaller caller) { |
| 137 if (rel_attribute.IsDNSPrefetch()) { | 152 if (rel_attribute.IsDNSPrefetch()) { |
| 138 UseCounter::Count(document, UseCounter::kLinkRelDnsPrefetch); | 153 UseCounter::Count(frame, UseCounter::kLinkRelDnsPrefetch); |
| 139 if (caller == kLinkCalledFromHeader) | 154 if (caller == kLinkCalledFromHeader) |
| 140 UseCounter::Count(document, UseCounter::kLinkHeaderDnsPrefetch); | 155 UseCounter::Count(frame, UseCounter::kLinkHeaderDnsPrefetch); |
| 141 Settings* settings = document.GetSettings(); | 156 Settings* settings = frame ? frame->GetSettings() : nullptr; |
| 142 // FIXME: The href attribute of the link element can be in "//hostname" | 157 // FIXME: The href attribute of the link element can be in "//hostname" |
| 143 // form, and we shouldn't attempt to complete that as URL | 158 // form, and we shouldn't attempt to complete that as URL |
| 144 // <https://bugs.webkit.org/show_bug.cgi?id=48857>. | 159 // <https://bugs.webkit.org/show_bug.cgi?id=48857>. |
| 145 if (settings && settings->GetDNSPrefetchingEnabled() && href.IsValid() && | 160 if (settings && settings->GetDNSPrefetchingEnabled() && href.IsValid() && |
| 146 !href.IsEmpty()) { | 161 !href.IsEmpty()) { |
| 147 if (settings->GetLogDnsPrefetchAndPreconnect()) { | 162 if (settings->GetLogDnsPrefetchAndPreconnect()) { |
| 148 document.AddConsoleMessage(ConsoleMessage::Create( | 163 SendMessageToConsoleForPossiblyNullDocument( |
| 149 kOtherMessageSource, kVerboseMessageLevel, | 164 ConsoleMessage::Create( |
| 150 String("DNS prefetch triggered for " + href.Host()))); | 165 kOtherMessageSource, kVerboseMessageLevel, |
| 166 String("DNS prefetch triggered for " + href.Host())), | |
| 167 document, frame); | |
| 151 } | 168 } |
| 152 network_hints_interface.DnsPrefetchHost(href.Host()); | 169 network_hints_interface.DnsPrefetchHost(href.Host()); |
| 153 } | 170 } |
| 154 } | 171 } |
| 155 } | 172 } |
| 156 | 173 |
| 157 static void PreconnectIfNeeded( | 174 static void PreconnectIfNeeded( |
| 158 const LinkRelAttribute& rel_attribute, | 175 const LinkRelAttribute& rel_attribute, |
| 159 const KURL& href, | 176 const KURL& href, |
| 160 Document& document, | 177 Document* document, |
| 178 LocalFrame* frame, | |
| 161 const CrossOriginAttributeValue cross_origin, | 179 const CrossOriginAttributeValue cross_origin, |
| 162 const NetworkHintsInterface& network_hints_interface, | 180 const NetworkHintsInterface& network_hints_interface, |
| 163 LinkCaller caller) { | 181 LinkCaller caller) { |
| 164 if (rel_attribute.IsPreconnect() && href.IsValid() && | 182 if (rel_attribute.IsPreconnect() && href.IsValid() && |
| 165 href.ProtocolIsInHTTPFamily()) { | 183 href.ProtocolIsInHTTPFamily()) { |
| 166 UseCounter::Count(document, UseCounter::kLinkRelPreconnect); | 184 UseCounter::Count(frame, UseCounter::kLinkRelPreconnect); |
| 167 if (caller == kLinkCalledFromHeader) | 185 if (caller == kLinkCalledFromHeader) |
| 168 UseCounter::Count(document, UseCounter::kLinkHeaderPreconnect); | 186 UseCounter::Count(frame, UseCounter::kLinkHeaderPreconnect); |
| 169 Settings* settings = document.GetSettings(); | 187 Settings* settings = frame ? frame->GetSettings() : nullptr; |
| 170 if (settings && settings->GetLogDnsPrefetchAndPreconnect()) { | 188 if (settings && settings->GetLogDnsPrefetchAndPreconnect()) { |
| 171 document.AddConsoleMessage(ConsoleMessage::Create( | 189 SendMessageToConsoleForPossiblyNullDocument( |
| 172 kOtherMessageSource, kVerboseMessageLevel, | 190 ConsoleMessage::Create( |
| 173 String("Preconnect triggered for ") + href.GetString())); | 191 kOtherMessageSource, kVerboseMessageLevel, |
| 192 String("Preconnect triggered for ") + href.GetString()), | |
| 193 document, frame); | |
| 174 if (cross_origin != kCrossOriginAttributeNotSet) { | 194 if (cross_origin != kCrossOriginAttributeNotSet) { |
| 175 document.AddConsoleMessage(ConsoleMessage::Create( | 195 SendMessageToConsoleForPossiblyNullDocument( |
| 176 kOtherMessageSource, kVerboseMessageLevel, | 196 ConsoleMessage::Create( |
| 177 String("Preconnect CORS setting is ") + | 197 kOtherMessageSource, kVerboseMessageLevel, |
| 178 String((cross_origin == kCrossOriginAttributeAnonymous) | 198 String("Preconnect CORS setting is ") + |
| 179 ? "anonymous" | 199 String((cross_origin == kCrossOriginAttributeAnonymous) |
| 180 : "use-credentials"))); | 200 ? "anonymous" |
| 201 : "use-credentials")), | |
| 202 document, frame); | |
| 181 } | 203 } |
| 182 } | 204 } |
| 183 network_hints_interface.PreconnectHost(href, cross_origin); | 205 network_hints_interface.PreconnectHost(href, cross_origin); |
| 184 } | 206 } |
| 185 } | 207 } |
| 186 | 208 |
| 187 WTF::Optional<Resource::Type> LinkLoader::GetResourceTypeFromAsAttribute( | 209 WTF::Optional<Resource::Type> LinkLoader::GetResourceTypeFromAsAttribute( |
| 188 const String& as) { | 210 const String& as) { |
| 189 DCHECK_EQ(as.DeprecatedLower(), as); | 211 DCHECK_EQ(as.DeprecatedLower(), as); |
| 190 if (as == "image") { | 212 if (as == "image") { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 } | 395 } |
| 374 return LinkFetchResource::Fetch(Resource::kLinkPrefetch, link_fetch_params, | 396 return LinkFetchResource::Fetch(Resource::kLinkPrefetch, link_fetch_params, |
| 375 document.Fetcher()); | 397 document.Fetcher()); |
| 376 } | 398 } |
| 377 return nullptr; | 399 return nullptr; |
| 378 } | 400 } |
| 379 | 401 |
| 380 void LinkLoader::LoadLinksFromHeader( | 402 void LinkLoader::LoadLinksFromHeader( |
| 381 const String& header_value, | 403 const String& header_value, |
| 382 const KURL& base_url, | 404 const KURL& base_url, |
| 405 LocalFrame& frame, | |
| 383 Document* document, | 406 Document* document, |
| 384 const NetworkHintsInterface& network_hints_interface, | 407 const NetworkHintsInterface& network_hints_interface, |
| 385 CanLoadResources can_load_resources, | 408 CanLoadResources can_load_resources, |
| 386 MediaPreloadPolicy media_policy, | 409 MediaPreloadPolicy media_policy, |
| 387 ViewportDescriptionWrapper* viewport_description_wrapper) { | 410 ViewportDescriptionWrapper* viewport_description_wrapper) { |
| 388 if (!document || header_value.IsEmpty()) | 411 if (header_value.IsEmpty()) |
| 389 return; | 412 return; |
| 390 LinkHeaderSet header_set(header_value); | 413 LinkHeaderSet header_set(header_value); |
| 391 for (auto& header : header_set) { | 414 for (auto& header : header_set) { |
| 392 if (!header.Valid() || header.Url().IsEmpty() || header.Rel().IsEmpty()) | 415 if (!header.Valid() || header.Url().IsEmpty() || header.Rel().IsEmpty()) |
| 393 continue; | 416 continue; |
| 394 | 417 |
| 395 if (media_policy == kOnlyLoadMedia && header.Media().IsEmpty()) | 418 if (media_policy == kOnlyLoadMedia && header.Media().IsEmpty()) |
| 396 continue; | 419 continue; |
| 397 if (media_policy == kOnlyLoadNonMedia && !header.Media().IsEmpty()) | 420 if (media_policy == kOnlyLoadNonMedia && !header.Media().IsEmpty()) |
| 398 continue; | 421 continue; |
| 399 | 422 |
| 400 LinkRelAttribute rel_attribute(header.Rel()); | 423 LinkRelAttribute rel_attribute(header.Rel()); |
| 401 KURL url(base_url, header.Url()); | 424 KURL url(base_url, header.Url()); |
| 402 // Sanity check to avoid re-entrancy here. | 425 // Sanity check to avoid re-entrancy here. |
| 403 if (url == base_url) | 426 if (url == base_url) |
| 404 continue; | 427 continue; |
| 405 if (can_load_resources != kOnlyLoadResources) { | 428 if (can_load_resources != kOnlyLoadResources) { |
| 406 DnsPrefetchIfNeeded(rel_attribute, url, *document, | 429 DnsPrefetchIfNeeded(rel_attribute, url, document, &frame, |
| 407 network_hints_interface, kLinkCalledFromHeader); | 430 network_hints_interface, kLinkCalledFromHeader); |
| 408 | 431 |
| 409 PreconnectIfNeeded(rel_attribute, url, *document, | 432 PreconnectIfNeeded(rel_attribute, url, document, &frame, |
| 410 GetCrossOriginAttributeValue(header.CrossOrigin()), | 433 GetCrossOriginAttributeValue(header.CrossOrigin()), |
| 411 network_hints_interface, kLinkCalledFromHeader); | 434 network_hints_interface, kLinkCalledFromHeader); |
| 412 } | 435 } |
| 413 if (can_load_resources != kDoNotLoadResources) { | 436 if (can_load_resources != kDoNotLoadResources) { |
| 437 DCHECK(document); | |
| 414 bool error_occurred = false; | 438 bool error_occurred = false; |
| 415 ViewportDescription* viewport_description = | 439 ViewportDescription* viewport_description = |
| 416 (viewport_description_wrapper && viewport_description_wrapper->set) | 440 (viewport_description_wrapper && viewport_description_wrapper->set) |
| 417 ? &(viewport_description_wrapper->description) | 441 ? &(viewport_description_wrapper->description) |
| 418 : nullptr; | 442 : nullptr; |
| 419 | 443 |
| 420 CrossOriginAttributeValue cross_origin = | 444 CrossOriginAttributeValue cross_origin = |
| 421 GetCrossOriginAttributeValue(header.CrossOrigin()); | 445 GetCrossOriginAttributeValue(header.CrossOrigin()); |
| 422 PreloadIfNeeded(rel_attribute, url, *document, header.As(), | 446 PreloadIfNeeded(rel_attribute, url, *document, header.As(), |
| 423 header.MimeType(), header.Media(), cross_origin, | 447 header.MimeType(), header.Media(), cross_origin, |
| 424 kLinkCalledFromHeader, error_occurred, | 448 kLinkCalledFromHeader, error_occurred, |
| 425 viewport_description, kReferrerPolicyDefault); | 449 viewport_description, kReferrerPolicyDefault); |
| 426 PrefetchIfNeeded(*document, url, rel_attribute, cross_origin, | 450 PrefetchIfNeeded(*document, url, rel_attribute, cross_origin, |
| 427 kReferrerPolicyDefault); | 451 kReferrerPolicyDefault); |
| 428 } | 452 } |
| 429 if (rel_attribute.IsServiceWorker()) { | 453 if (rel_attribute.IsServiceWorker()) { |
| 430 UseCounter::Count(*document, UseCounter::kLinkHeaderServiceWorker); | 454 UseCounter::Count(&frame, UseCounter::kLinkHeaderServiceWorker); |
| 431 } | 455 } |
| 432 // TODO(yoav): Add more supported headers as needed. | 456 // TODO(yoav): Add more supported headers as needed. |
| 433 } | 457 } |
| 434 } | 458 } |
| 435 | 459 |
| 436 bool LinkLoader::LoadLink( | 460 bool LinkLoader::LoadLink( |
| 437 const LinkRelAttribute& rel_attribute, | 461 const LinkRelAttribute& rel_attribute, |
| 438 CrossOriginAttributeValue cross_origin, | 462 CrossOriginAttributeValue cross_origin, |
| 439 const String& type, | 463 const String& type, |
| 440 const String& as, | 464 const String& as, |
| 441 const String& media, | 465 const String& media, |
| 442 ReferrerPolicy referrer_policy, | 466 ReferrerPolicy referrer_policy, |
| 443 const KURL& href, | 467 const KURL& href, |
| 444 Document& document, | 468 Document& document, |
| 445 const NetworkHintsInterface& network_hints_interface) { | 469 const NetworkHintsInterface& network_hints_interface) { |
| 446 if (!client_->ShouldLoadLink()) | 470 if (!client_->ShouldLoadLink()) |
| 447 return false; | 471 return false; |
| 448 | 472 |
| 449 DnsPrefetchIfNeeded(rel_attribute, href, document, network_hints_interface, | 473 DnsPrefetchIfNeeded(rel_attribute, href, &document, document.GetFrame(), |
| 450 kLinkCalledFromMarkup); | 474 network_hints_interface, kLinkCalledFromMarkup); |
| 451 | 475 |
| 452 PreconnectIfNeeded(rel_attribute, href, document, cross_origin, | 476 PreconnectIfNeeded(rel_attribute, href, &document, document.GetFrame(), |
| 453 network_hints_interface, kLinkCalledFromMarkup); | 477 cross_origin, network_hints_interface, |
| 478 kLinkCalledFromMarkup); | |
| 454 | 479 |
| 455 bool error_occurred = false; | 480 bool error_occurred = false; |
| 456 CreateLinkPreloadResourceClient(PreloadIfNeeded( | 481 CreateLinkPreloadResourceClient(PreloadIfNeeded( |
| 457 rel_attribute, href, document, as, type, media, cross_origin, | 482 rel_attribute, href, document, as, type, media, cross_origin, |
| 458 kLinkCalledFromMarkup, error_occurred, nullptr, referrer_policy)); | 483 kLinkCalledFromMarkup, error_occurred, nullptr, referrer_policy)); |
| 459 if (error_occurred) | 484 if (error_occurred) |
| 460 link_loading_error_timer_.StartOneShot(0, BLINK_FROM_HERE); | 485 link_loading_error_timer_.StartOneShot(0, BLINK_FROM_HERE); |
| 461 | 486 |
| 462 if (href.IsEmpty() || !href.IsValid()) | 487 if (href.IsEmpty() || !href.IsValid()) |
| 463 Released(); | 488 Released(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 | 523 |
| 499 DEFINE_TRACE(LinkLoader) { | 524 DEFINE_TRACE(LinkLoader) { |
| 500 visitor->Trace(client_); | 525 visitor->Trace(client_); |
| 501 visitor->Trace(prerender_); | 526 visitor->Trace(prerender_); |
| 502 visitor->Trace(link_preload_resource_client_); | 527 visitor->Trace(link_preload_resource_client_); |
| 503 ResourceOwner<Resource, ResourceClient>::Trace(visitor); | 528 ResourceOwner<Resource, ResourceClient>::Trace(visitor); |
| 504 PrerenderClient::Trace(visitor); | 529 PrerenderClient::Trace(visitor); |
| 505 } | 530 } |
| 506 | 531 |
| 507 } // namespace blink | 532 } // namespace blink |
| OLD | NEW |