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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 UseCounter::count(document, UseCounter::LinkRelNext); | 64 UseCounter::count(document, UseCounter::LinkRelNext); |
| 65 } | 65 } |
| 66 | 66 |
| 67 return result; | 67 return result; |
| 68 } | 68 } |
| 69 | 69 |
| 70 LinkLoader::LinkLoader(LinkLoaderClient* client) | 70 LinkLoader::LinkLoader(LinkLoaderClient* client) |
| 71 : m_client(client) | 71 : m_client(client) |
| 72 , m_linkLoadTimer(this, &LinkLoader::linkLoadTimerFired) | 72 , m_linkLoadTimer(this, &LinkLoader::linkLoadTimerFired) |
| 73 , m_linkLoadingErrorTimer(this, &LinkLoader::linkLoadingErrorTimerFired) | 73 , m_linkLoadingErrorTimer(this, &LinkLoader::linkLoadingErrorTimerFired) |
| 74 , m_weakPtrFactory(this) | |
| 74 { | 75 { |
| 75 } | 76 } |
| 76 | 77 |
| 77 LinkLoader::~LinkLoader() | 78 LinkLoader::~LinkLoader() |
| 78 { | 79 { |
| 79 } | 80 } |
| 80 | 81 |
| 81 void LinkLoader::linkLoadTimerFired(Timer<LinkLoader>* timer) | 82 void LinkLoader::linkLoadTimerFired(Timer<LinkLoader>* timer) |
| 82 { | 83 { |
| 83 ASSERT_UNUSED(timer, timer == &m_linkLoadTimer); | 84 ASSERT_UNUSED(timer, timer == &m_linkLoadTimer); |
| 84 m_client->linkLoaded(); | 85 m_client->linkLoaded(); |
| 85 } | 86 } |
| 86 | 87 |
| 87 void LinkLoader::linkLoadingErrorTimerFired(Timer<LinkLoader>* timer) | 88 void LinkLoader::linkLoadingErrorTimerFired(Timer<LinkLoader>* timer) |
| 88 { | 89 { |
| 89 ASSERT_UNUSED(timer, timer == &m_linkLoadingErrorTimer); | 90 ASSERT_UNUSED(timer, timer == &m_linkLoadingErrorTimer); |
| 90 m_client->linkLoadingErrored(); | 91 m_client->linkLoadingErrored(); |
| 91 } | 92 } |
| 92 | 93 |
| 94 void LinkLoader::triggerEvents(Resource* resource) | |
| 95 { | |
| 96 if (resource->errorOccurred()) | |
| 97 m_linkLoadingErrorTimer.startOneShot(0, BLINK_FROM_HERE); | |
| 98 else | |
| 99 m_linkLoadTimer.startOneShot(0, BLINK_FROM_HERE); | |
| 100 } | |
| 101 | |
| 93 void LinkLoader::notifyFinished(Resource* resource) | 102 void LinkLoader::notifyFinished(Resource* resource) |
| 94 { | 103 { |
| 95 ASSERT(this->resource() == resource); | 104 ASSERT(this->resource() == resource); |
| 96 | 105 |
| 97 if (resource->errorOccurred()) | 106 triggerEvents(resource); |
| 98 m_linkLoadingErrorTimer.startOneShot(0, BLINK_FROM_HERE); | |
| 99 else | |
| 100 m_linkLoadTimer.startOneShot(0, BLINK_FROM_HERE); | |
| 101 | |
| 102 clearResource(); | 107 clearResource(); |
| 103 } | 108 } |
| 104 | 109 |
| 105 void LinkLoader::didStartPrerender() | 110 void LinkLoader::didStartPrerender() |
| 106 { | 111 { |
| 107 m_client->didStartLinkPrerender(); | 112 m_client->didStartLinkPrerender(); |
| 108 } | 113 } |
| 109 | 114 |
| 110 void LinkLoader::didStopPrerender() | 115 void LinkLoader::didStopPrerender() |
| 111 { | 116 { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 if (equalIgnoringCase(as, "font")) | 182 if (equalIgnoringCase(as, "font")) |
| 178 return Resource::Font; | 183 return Resource::Font; |
| 179 if (equalIgnoringCase(as, "track")) | 184 if (equalIgnoringCase(as, "track")) |
| 180 return Resource::TextTrack; | 185 return Resource::TextTrack; |
| 181 if (document && !as.isEmpty()) | 186 if (document && !as.isEmpty()) |
| 182 document->addConsoleMessage(ConsoleMessage::create(OtherMessageSource, W arningMessageLevel, String("<link rel=preload> must have a valid `as` value"))); | 187 document->addConsoleMessage(ConsoleMessage::create(OtherMessageSource, W arningMessageLevel, String("<link rel=preload> must have a valid `as` value"))); |
| 183 // TODO(yoav): Is this correct? If as is missing or invalid, it should be su bject to "connect-src" CSP directives. | 188 // TODO(yoav): Is this correct? If as is missing or invalid, it should be su bject to "connect-src" CSP directives. |
| 184 return Resource::LinkSubresource; | 189 return Resource::LinkSubresource; |
| 185 } | 190 } |
| 186 | 191 |
| 187 static void preloadIfNeeded(const LinkRelAttribute& relAttribute, const KURL& hr ef, Document& document, const String& as) | 192 static void preloadIfNeeded(const LinkRelAttribute& relAttribute, const KURL& hr ef, Document& document, const String& as, LinkLoader* linkLoader) |
|
Nate Chapin
2016/01/13 23:52:23
Should this be a private member of LinkLoader if w
Yoav Weiss
2016/01/14 10:10:02
This has to remain static since it's called from l
| |
| 188 { | 193 { |
| 189 if (!document.loader()) | 194 if (!document.loader() || !relAttribute.isLinkPreload()) |
| 190 return; | 195 return; |
| 191 | 196 |
| 192 if (relAttribute.isLinkPreload()) { | 197 UseCounter::count(document, UseCounter::LinkRelPreload); |
| 193 UseCounter::count(document, UseCounter::LinkRelPreload); | 198 ASSERT(RuntimeEnabledFeatures::linkPreloadEnabled()); |
| 194 ASSERT(RuntimeEnabledFeatures::linkPreloadEnabled()); | 199 if (!href.isValid() || href.isEmpty()) { |
| 195 if (!href.isValid() || href.isEmpty()) { | 200 document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, Wa rningMessageLevel, String("<link rel=preload> has an invalid `href` value"))); |
| 196 document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource , WarningMessageLevel, String("<link rel=preload> has an invalid `href` value")) ); | 201 return; |
| 197 return; | 202 } |
| 198 } | 203 Resource::Type type = LinkLoader::getTypeFromAsAttribute(as, &document); |
| 199 Resource::Type type = LinkLoader::getTypeFromAsAttribute(as, &document); | 204 ResourceRequest resourceRequest(document.completeURL(href)); |
| 200 ResourceRequest resourceRequest(document.completeURL(href)); | 205 ResourceFetcher::determineRequestContext(resourceRequest, type, false); |
| 201 ResourceFetcher::determineRequestContext(resourceRequest, type, false); | 206 FetchRequest linkRequest(resourceRequest, FetchInitiatorTypeNames::link); |
| 202 FetchRequest linkRequest(resourceRequest, FetchInitiatorTypeNames::link) ; | |
| 203 | 207 |
| 204 linkRequest.setPriority(document.fetcher()->loadPriority(type, linkReque st)); | 208 linkRequest.setPriority(document.fetcher()->loadPriority(type, linkRequest)) ; |
| 205 Settings* settings = document.settings(); | 209 Settings* settings = document.settings(); |
| 206 if (settings && settings->logPreload()) | 210 if (settings && settings->logPreload()) |
| 207 document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource , DebugMessageLevel, String("Preload triggered for " + href.host() + href.path() ))); | 211 document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, De bugMessageLevel, String("Preload triggered for " + href.host() + href.path()))); |
| 208 linkRequest.setForPreload(true); | 212 linkRequest.setForPreload(true); |
| 209 linkRequest.setAvoidBlockingOnLoad(true); | 213 linkRequest.setAvoidBlockingOnLoad(true); |
| 210 document.loader()->startPreload(type, linkRequest); | 214 document.loader()->startPreload(type, linkRequest, linkLoader); |
| 211 } | |
| 212 } | 215 } |
| 213 | 216 |
| 214 bool LinkLoader::loadLinkFromHeader(const String& headerValue, Document* documen t, const NetworkHintsInterface& networkHintsInterface, CanLoadResources canLoadR esources) | 217 bool LinkLoader::loadLinkFromHeader(const String& headerValue, Document* documen t, const NetworkHintsInterface& networkHintsInterface, CanLoadResources canLoadR esources) |
| 215 { | 218 { |
| 216 if (!document) | 219 if (!document) |
| 217 return false; | 220 return false; |
| 218 LinkHeaderSet headerSet(headerValue); | 221 LinkHeaderSet headerSet(headerValue); |
| 219 for (auto& header : headerSet) { | 222 for (auto& header : headerSet) { |
| 220 if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty()) | 223 if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty()) |
| 221 return false; | 224 return false; |
| 222 | 225 |
| 223 LinkRelAttribute relAttribute(header.rel()); | 226 LinkRelAttribute relAttribute(header.rel()); |
| 224 KURL url = document->completeURL(header.url()); | 227 KURL url = document->completeURL(header.url()); |
| 225 if (canLoadResources == DoNotLoadResources) { | 228 if (canLoadResources == DoNotLoadResources) { |
| 226 if (RuntimeEnabledFeatures::linkHeaderEnabled()) | 229 if (RuntimeEnabledFeatures::linkHeaderEnabled()) |
| 227 dnsPrefetchIfNeeded(relAttribute, url, *document, networkHintsIn terface, LinkCalledFromHeader); | 230 dnsPrefetchIfNeeded(relAttribute, url, *document, networkHintsIn terface, LinkCalledFromHeader); |
| 228 | 231 |
| 229 if (RuntimeEnabledFeatures::linkPreconnectEnabled()) | 232 if (RuntimeEnabledFeatures::linkPreconnectEnabled()) |
| 230 preconnectIfNeeded(relAttribute, url, *document, header.crossOri gin(), networkHintsInterface, LinkCalledFromHeader); | 233 preconnectIfNeeded(relAttribute, url, *document, header.crossOri gin(), networkHintsInterface, LinkCalledFromHeader); |
| 231 } else { | 234 } else { |
| 232 if (RuntimeEnabledFeatures::linkPreloadEnabled()) | 235 if (RuntimeEnabledFeatures::linkPreloadEnabled()) |
| 233 preloadIfNeeded(relAttribute, url, *document, header.as()); | 236 preloadIfNeeded(relAttribute, url, *document, header.as(), nullp tr); |
|
Nate Chapin
2016/01/13 23:52:23
Passing nullptr in this case is not immediately ob
Yoav Weiss
2016/01/14 10:10:02
If preloadIfNeeded would not be static, we wouldn'
| |
| 234 } | 237 } |
| 235 // TODO(yoav): Add more supported headers as needed. | 238 // TODO(yoav): Add more supported headers as needed. |
| 236 } | 239 } |
| 237 return true; | 240 return true; |
| 238 } | 241 } |
| 239 | 242 |
| 240 bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, CrossOriginAttri buteValue crossOrigin, const String& type, const String& as, const KURL& href, D ocument& document, const NetworkHintsInterface& networkHintsInterface) | 243 bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, CrossOriginAttri buteValue crossOrigin, const String& type, const String& as, const KURL& href, D ocument& document, const NetworkHintsInterface& networkHintsInterface) |
| 241 { | 244 { |
| 242 // TODO(yoav): Do all links need to load only after they're in document??? | 245 // TODO(yoav): Do all links need to load only after they're in document??? |
| 243 | 246 |
| 244 // TODO(yoav): Convert all uses of the CrossOriginAttribute to CrossOriginAt tributeValue. crbug.com/486689 | 247 // TODO(yoav): Convert all uses of the CrossOriginAttribute to CrossOriginAt tributeValue. crbug.com/486689 |
| 245 // FIXME(crbug.com/463266): We're ignoring type here. Maybe we shouldn't. | 248 // FIXME(crbug.com/463266): We're ignoring type here. Maybe we shouldn't. |
| 246 dnsPrefetchIfNeeded(relAttribute, href, document, networkHintsInterface, Lin kCalledFromMarkup); | 249 dnsPrefetchIfNeeded(relAttribute, href, document, networkHintsInterface, Lin kCalledFromMarkup); |
| 247 | 250 |
| 248 preconnectIfNeeded(relAttribute, href, document, crossOrigin, networkHintsIn terface, LinkCalledFromMarkup); | 251 preconnectIfNeeded(relAttribute, href, document, crossOrigin, networkHintsIn terface, LinkCalledFromMarkup); |
| 249 | 252 |
| 250 if (m_client->shouldLoadLink()) | 253 if (m_client->shouldLoadLink()) |
| 251 preloadIfNeeded(relAttribute, href, document, as); | 254 preloadIfNeeded(relAttribute, href, document, as, this); |
| 252 | 255 |
| 253 // FIXME(crbug.com/323096): Should take care of import. | 256 // FIXME(crbug.com/323096): Should take care of import. |
| 254 if ((relAttribute.isLinkPrefetch() || relAttribute.isLinkSubresource()) && h ref.isValid() && document.frame()) { | 257 if ((relAttribute.isLinkPrefetch() || relAttribute.isLinkSubresource()) && h ref.isValid() && document.frame()) { |
| 255 if (!m_client->shouldLoadLink()) | 258 if (!m_client->shouldLoadLink()) |
| 256 return false; | 259 return false; |
| 257 Resource::Type type = Resource::LinkPrefetch; | 260 Resource::Type type = Resource::LinkPrefetch; |
| 258 if (relAttribute.isLinkSubresource()) { | 261 if (relAttribute.isLinkSubresource()) { |
| 259 type = Resource::LinkSubresource; | 262 type = Resource::LinkSubresource; |
| 260 UseCounter::count(document, UseCounter::LinkRelSubresource); | 263 UseCounter::count(document, UseCounter::LinkRelSubresource); |
| 261 } else { | 264 } else { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 289 // atomic (dns prefetch). | 292 // atomic (dns prefetch). |
| 290 if (m_prerender) { | 293 if (m_prerender) { |
| 291 m_prerender->cancel(); | 294 m_prerender->cancel(); |
| 292 m_prerender.clear(); | 295 m_prerender.clear(); |
| 293 } | 296 } |
| 294 } | 297 } |
| 295 | 298 |
| 296 DEFINE_TRACE(LinkLoader) | 299 DEFINE_TRACE(LinkLoader) |
| 297 { | 300 { |
| 298 visitor->trace(m_prerender); | 301 visitor->trace(m_prerender); |
| 302 visitor->trace(m_linkPreloadResourceClient); | |
| 299 } | 303 } |
| 300 | 304 |
| 301 } | 305 } |
| OLD | NEW |