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( |
| 134 ConsoleMessage* console_message, |
| 135 Document* document, |
| 136 LocalFrame* frame) { |
| 137 DCHECK(document || frame); |
| 138 DCHECK(!document || document->GetFrame() == frame); |
| 139 // Route the console message through Document if possible, so that script line |
| 140 // numbers can be included. Otherwise, route directly to the FrameConsole, to |
| 141 // ensure we never drop a message. |
| 142 if (document) |
| 143 document->AddConsoleMessage(console_message); |
| 144 else |
| 145 frame->Console().AddMessage(console_message); |
| 146 } |
| 147 |
131 static void DnsPrefetchIfNeeded( | 148 static void DnsPrefetchIfNeeded( |
132 const LinkRelAttribute& rel_attribute, | 149 const LinkRelAttribute& rel_attribute, |
133 const KURL& href, | 150 const KURL& href, |
134 Document& document, | 151 Document* document, |
| 152 LocalFrame* frame, |
135 const NetworkHintsInterface& network_hints_interface, | 153 const NetworkHintsInterface& network_hints_interface, |
136 LinkCaller caller) { | 154 LinkCaller caller) { |
137 if (rel_attribute.IsDNSPrefetch()) { | 155 if (rel_attribute.IsDNSPrefetch()) { |
138 UseCounter::Count(document, UseCounter::kLinkRelDnsPrefetch); | 156 UseCounter::Count(frame, UseCounter::kLinkRelDnsPrefetch); |
139 if (caller == kLinkCalledFromHeader) | 157 if (caller == kLinkCalledFromHeader) |
140 UseCounter::Count(document, UseCounter::kLinkHeaderDnsPrefetch); | 158 UseCounter::Count(frame, UseCounter::kLinkHeaderDnsPrefetch); |
141 Settings* settings = document.GetSettings(); | 159 Settings* settings = frame ? frame->GetSettings() : nullptr; |
142 // FIXME: The href attribute of the link element can be in "//hostname" | 160 // FIXME: The href attribute of the link element can be in "//hostname" |
143 // form, and we shouldn't attempt to complete that as URL | 161 // form, and we shouldn't attempt to complete that as URL |
144 // <https://bugs.webkit.org/show_bug.cgi?id=48857>. | 162 // <https://bugs.webkit.org/show_bug.cgi?id=48857>. |
145 if (settings && settings->GetDNSPrefetchingEnabled() && href.IsValid() && | 163 if (settings && settings->GetDNSPrefetchingEnabled() && href.IsValid() && |
146 !href.IsEmpty()) { | 164 !href.IsEmpty()) { |
147 if (settings->GetLogDnsPrefetchAndPreconnect()) { | 165 if (settings->GetLogDnsPrefetchAndPreconnect()) { |
148 document.AddConsoleMessage(ConsoleMessage::Create( | 166 SendMessageToConsoleForPossiblyNullDocument( |
149 kOtherMessageSource, kVerboseMessageLevel, | 167 ConsoleMessage::Create( |
150 String("DNS prefetch triggered for " + href.Host()))); | 168 kOtherMessageSource, kVerboseMessageLevel, |
| 169 String("DNS prefetch triggered for " + href.Host())), |
| 170 document, frame); |
151 } | 171 } |
152 network_hints_interface.DnsPrefetchHost(href.Host()); | 172 network_hints_interface.DnsPrefetchHost(href.Host()); |
153 } | 173 } |
154 } | 174 } |
155 } | 175 } |
156 | 176 |
157 static void PreconnectIfNeeded( | 177 static void PreconnectIfNeeded( |
158 const LinkRelAttribute& rel_attribute, | 178 const LinkRelAttribute& rel_attribute, |
159 const KURL& href, | 179 const KURL& href, |
160 Document& document, | 180 Document* document, |
| 181 LocalFrame* frame, |
161 const CrossOriginAttributeValue cross_origin, | 182 const CrossOriginAttributeValue cross_origin, |
162 const NetworkHintsInterface& network_hints_interface, | 183 const NetworkHintsInterface& network_hints_interface, |
163 LinkCaller caller) { | 184 LinkCaller caller) { |
164 if (rel_attribute.IsPreconnect() && href.IsValid() && | 185 if (rel_attribute.IsPreconnect() && href.IsValid() && |
165 href.ProtocolIsInHTTPFamily()) { | 186 href.ProtocolIsInHTTPFamily()) { |
166 UseCounter::Count(document, UseCounter::kLinkRelPreconnect); | 187 UseCounter::Count(frame, UseCounter::kLinkRelPreconnect); |
167 if (caller == kLinkCalledFromHeader) | 188 if (caller == kLinkCalledFromHeader) |
168 UseCounter::Count(document, UseCounter::kLinkHeaderPreconnect); | 189 UseCounter::Count(frame, UseCounter::kLinkHeaderPreconnect); |
169 Settings* settings = document.GetSettings(); | 190 Settings* settings = frame ? frame->GetSettings() : nullptr; |
170 if (settings && settings->GetLogDnsPrefetchAndPreconnect()) { | 191 if (settings && settings->GetLogDnsPrefetchAndPreconnect()) { |
171 document.AddConsoleMessage(ConsoleMessage::Create( | 192 SendMessageToConsoleForPossiblyNullDocument( |
172 kOtherMessageSource, kVerboseMessageLevel, | 193 ConsoleMessage::Create( |
173 String("Preconnect triggered for ") + href.GetString())); | 194 kOtherMessageSource, kVerboseMessageLevel, |
| 195 String("Preconnect triggered for ") + href.GetString()), |
| 196 document, frame); |
174 if (cross_origin != kCrossOriginAttributeNotSet) { | 197 if (cross_origin != kCrossOriginAttributeNotSet) { |
175 document.AddConsoleMessage(ConsoleMessage::Create( | 198 SendMessageToConsoleForPossiblyNullDocument( |
176 kOtherMessageSource, kVerboseMessageLevel, | 199 ConsoleMessage::Create( |
177 String("Preconnect CORS setting is ") + | 200 kOtherMessageSource, kVerboseMessageLevel, |
178 String((cross_origin == kCrossOriginAttributeAnonymous) | 201 String("Preconnect CORS setting is ") + |
179 ? "anonymous" | 202 String((cross_origin == kCrossOriginAttributeAnonymous) |
180 : "use-credentials"))); | 203 ? "anonymous" |
| 204 : "use-credentials")), |
| 205 document, frame); |
181 } | 206 } |
182 } | 207 } |
183 network_hints_interface.PreconnectHost(href, cross_origin); | 208 network_hints_interface.PreconnectHost(href, cross_origin); |
184 } | 209 } |
185 } | 210 } |
186 | 211 |
187 WTF::Optional<Resource::Type> LinkLoader::GetResourceTypeFromAsAttribute( | 212 WTF::Optional<Resource::Type> LinkLoader::GetResourceTypeFromAsAttribute( |
188 const String& as) { | 213 const String& as) { |
189 DCHECK_EQ(as.DeprecatedLower(), as); | 214 DCHECK_EQ(as.DeprecatedLower(), as); |
190 if (as == "image") { | 215 if (as == "image") { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 } | 398 } |
374 return LinkFetchResource::Fetch(Resource::kLinkPrefetch, link_fetch_params, | 399 return LinkFetchResource::Fetch(Resource::kLinkPrefetch, link_fetch_params, |
375 document.Fetcher()); | 400 document.Fetcher()); |
376 } | 401 } |
377 return nullptr; | 402 return nullptr; |
378 } | 403 } |
379 | 404 |
380 void LinkLoader::LoadLinksFromHeader( | 405 void LinkLoader::LoadLinksFromHeader( |
381 const String& header_value, | 406 const String& header_value, |
382 const KURL& base_url, | 407 const KURL& base_url, |
| 408 LocalFrame& frame, |
383 Document* document, | 409 Document* document, |
384 const NetworkHintsInterface& network_hints_interface, | 410 const NetworkHintsInterface& network_hints_interface, |
385 CanLoadResources can_load_resources, | 411 CanLoadResources can_load_resources, |
386 MediaPreloadPolicy media_policy, | 412 MediaPreloadPolicy media_policy, |
387 ViewportDescriptionWrapper* viewport_description_wrapper) { | 413 ViewportDescriptionWrapper* viewport_description_wrapper) { |
388 if (!document || header_value.IsEmpty()) | 414 if (header_value.IsEmpty()) |
389 return; | 415 return; |
390 LinkHeaderSet header_set(header_value); | 416 LinkHeaderSet header_set(header_value); |
391 for (auto& header : header_set) { | 417 for (auto& header : header_set) { |
392 if (!header.Valid() || header.Url().IsEmpty() || header.Rel().IsEmpty()) | 418 if (!header.Valid() || header.Url().IsEmpty() || header.Rel().IsEmpty()) |
393 continue; | 419 continue; |
394 | 420 |
395 if (media_policy == kOnlyLoadMedia && header.Media().IsEmpty()) | 421 if (media_policy == kOnlyLoadMedia && header.Media().IsEmpty()) |
396 continue; | 422 continue; |
397 if (media_policy == kOnlyLoadNonMedia && !header.Media().IsEmpty()) | 423 if (media_policy == kOnlyLoadNonMedia && !header.Media().IsEmpty()) |
398 continue; | 424 continue; |
399 | 425 |
400 LinkRelAttribute rel_attribute(header.Rel()); | 426 LinkRelAttribute rel_attribute(header.Rel()); |
401 KURL url(base_url, header.Url()); | 427 KURL url(base_url, header.Url()); |
402 // Sanity check to avoid re-entrancy here. | 428 // Sanity check to avoid re-entrancy here. |
403 if (url == base_url) | 429 if (url == base_url) |
404 continue; | 430 continue; |
405 if (can_load_resources != kOnlyLoadResources) { | 431 if (can_load_resources != kOnlyLoadResources) { |
406 DnsPrefetchIfNeeded(rel_attribute, url, *document, | 432 DnsPrefetchIfNeeded(rel_attribute, url, document, &frame, |
407 network_hints_interface, kLinkCalledFromHeader); | 433 network_hints_interface, kLinkCalledFromHeader); |
408 | 434 |
409 PreconnectIfNeeded(rel_attribute, url, *document, | 435 PreconnectIfNeeded(rel_attribute, url, document, &frame, |
410 GetCrossOriginAttributeValue(header.CrossOrigin()), | 436 GetCrossOriginAttributeValue(header.CrossOrigin()), |
411 network_hints_interface, kLinkCalledFromHeader); | 437 network_hints_interface, kLinkCalledFromHeader); |
412 } | 438 } |
413 if (can_load_resources != kDoNotLoadResources) { | 439 if (can_load_resources != kDoNotLoadResources) { |
| 440 DCHECK(document); |
414 bool error_occurred = false; | 441 bool error_occurred = false; |
415 ViewportDescription* viewport_description = | 442 ViewportDescription* viewport_description = |
416 (viewport_description_wrapper && viewport_description_wrapper->set) | 443 (viewport_description_wrapper && viewport_description_wrapper->set) |
417 ? &(viewport_description_wrapper->description) | 444 ? &(viewport_description_wrapper->description) |
418 : nullptr; | 445 : nullptr; |
419 | 446 |
420 CrossOriginAttributeValue cross_origin = | 447 CrossOriginAttributeValue cross_origin = |
421 GetCrossOriginAttributeValue(header.CrossOrigin()); | 448 GetCrossOriginAttributeValue(header.CrossOrigin()); |
422 PreloadIfNeeded(rel_attribute, url, *document, header.As(), | 449 PreloadIfNeeded(rel_attribute, url, *document, header.As(), |
423 header.MimeType(), header.Media(), cross_origin, | 450 header.MimeType(), header.Media(), cross_origin, |
424 kLinkCalledFromHeader, error_occurred, | 451 kLinkCalledFromHeader, error_occurred, |
425 viewport_description, kReferrerPolicyDefault); | 452 viewport_description, kReferrerPolicyDefault); |
426 PrefetchIfNeeded(*document, url, rel_attribute, cross_origin, | 453 PrefetchIfNeeded(*document, url, rel_attribute, cross_origin, |
427 kReferrerPolicyDefault); | 454 kReferrerPolicyDefault); |
428 } | 455 } |
429 if (rel_attribute.IsServiceWorker()) { | 456 if (rel_attribute.IsServiceWorker()) { |
430 UseCounter::Count(*document, UseCounter::kLinkHeaderServiceWorker); | 457 UseCounter::Count(&frame, UseCounter::kLinkHeaderServiceWorker); |
431 } | 458 } |
432 // TODO(yoav): Add more supported headers as needed. | 459 // TODO(yoav): Add more supported headers as needed. |
433 } | 460 } |
434 } | 461 } |
435 | 462 |
436 bool LinkLoader::LoadLink( | 463 bool LinkLoader::LoadLink( |
437 const LinkRelAttribute& rel_attribute, | 464 const LinkRelAttribute& rel_attribute, |
438 CrossOriginAttributeValue cross_origin, | 465 CrossOriginAttributeValue cross_origin, |
439 const String& type, | 466 const String& type, |
440 const String& as, | 467 const String& as, |
441 const String& media, | 468 const String& media, |
442 ReferrerPolicy referrer_policy, | 469 ReferrerPolicy referrer_policy, |
443 const KURL& href, | 470 const KURL& href, |
444 Document& document, | 471 Document& document, |
445 const NetworkHintsInterface& network_hints_interface) { | 472 const NetworkHintsInterface& network_hints_interface) { |
446 if (!client_->ShouldLoadLink()) | 473 if (!client_->ShouldLoadLink()) |
447 return false; | 474 return false; |
448 | 475 |
449 DnsPrefetchIfNeeded(rel_attribute, href, document, network_hints_interface, | 476 DnsPrefetchIfNeeded(rel_attribute, href, &document, document.GetFrame(), |
450 kLinkCalledFromMarkup); | 477 network_hints_interface, kLinkCalledFromMarkup); |
451 | 478 |
452 PreconnectIfNeeded(rel_attribute, href, document, cross_origin, | 479 PreconnectIfNeeded(rel_attribute, href, &document, document.GetFrame(), |
453 network_hints_interface, kLinkCalledFromMarkup); | 480 cross_origin, network_hints_interface, |
| 481 kLinkCalledFromMarkup); |
454 | 482 |
455 bool error_occurred = false; | 483 bool error_occurred = false; |
456 CreateLinkPreloadResourceClient(PreloadIfNeeded( | 484 CreateLinkPreloadResourceClient(PreloadIfNeeded( |
457 rel_attribute, href, document, as, type, media, cross_origin, | 485 rel_attribute, href, document, as, type, media, cross_origin, |
458 kLinkCalledFromMarkup, error_occurred, nullptr, referrer_policy)); | 486 kLinkCalledFromMarkup, error_occurred, nullptr, referrer_policy)); |
459 if (error_occurred) | 487 if (error_occurred) |
460 link_loading_error_timer_.StartOneShot(0, BLINK_FROM_HERE); | 488 link_loading_error_timer_.StartOneShot(0, BLINK_FROM_HERE); |
461 | 489 |
462 if (href.IsEmpty() || !href.IsValid()) | 490 if (href.IsEmpty() || !href.IsValid()) |
463 Released(); | 491 Released(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 | 526 |
499 DEFINE_TRACE(LinkLoader) { | 527 DEFINE_TRACE(LinkLoader) { |
500 visitor->Trace(client_); | 528 visitor->Trace(client_); |
501 visitor->Trace(prerender_); | 529 visitor->Trace(prerender_); |
502 visitor->Trace(link_preload_resource_client_); | 530 visitor->Trace(link_preload_resource_client_); |
503 ResourceOwner<Resource, ResourceClient>::Trace(visitor); | 531 ResourceOwner<Resource, ResourceClient>::Trace(visitor); |
504 PrerenderClient::Trace(visitor); | 532 PrerenderClient::Trace(visitor); |
505 } | 533 } |
506 | 534 |
507 } // namespace blink | 535 } // namespace blink |
OLD | NEW |