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 |