Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
| 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
| 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
| 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
| 6 rights reserved. | |
|
Yoav Weiss
2016/10/03 08:52:20
indentation
Charlie Harrison
2016/10/03 12:36:54
Done.
| |
| 6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
| 7 | 8 |
| 8 This library is free software; you can redistribute it and/or | 9 This library is free software; you can redistribute it and/or |
| 9 modify it under the terms of the GNU Library General Public | 10 modify it under the terms of the GNU Library General Public |
| 10 License as published by the Free Software Foundation; either | 11 License as published by the Free Software Foundation; either |
| 11 version 2 of the License, or (at your option) any later version. | 12 version 2 of the License, or (at your option) any later version. |
| 12 | 13 |
| 13 This library is distributed in the hope that it will be useful, | 14 This library is distributed in the hope that it will be useful, |
| 14 but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 Library General Public License for more details. | 17 Library General Public License for more details. |
| 17 | 18 |
| 18 You should have received a copy of the GNU Library General Public License | 19 You should have received a copy of the GNU Library General Public License |
| 19 along with this library; see the file COPYING.LIB. If not, write to | 20 along with this library; see the file COPYING.LIB. If not, write to |
| 20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 21 Boston, MA 02110-1301, USA. | 22 Boston, MA 02110-1301, USA. |
| 22 | 23 |
| 23 This class provides all functionality needed for loading images, style sheet s and html | 24 This class provides all functionality needed for loading images, style |
| 24 pages from the web. It has a memory cache for these objects. | 25 sheets and html pages from the web. It has a memory cache for these objects. |
| 25 */ | 26 */ |
| 26 | 27 |
| 27 #include "core/fetch/ResourceFetcher.h" | 28 #include "core/fetch/ResourceFetcher.h" |
| 28 | 29 |
| 29 #include "bindings/core/v8/V8DOMActivityLogger.h" | 30 #include "bindings/core/v8/V8DOMActivityLogger.h" |
| 30 #include "core/fetch/CrossOriginAccessControl.h" | 31 #include "core/fetch/CrossOriginAccessControl.h" |
| 31 #include "core/fetch/FetchContext.h" | 32 #include "core/fetch/FetchContext.h" |
| 32 #include "core/fetch/FetchInitiatorTypeNames.h" | 33 #include "core/fetch/FetchInitiatorTypeNames.h" |
| 33 #include "core/fetch/ImageResource.h" | 34 #include "core/fetch/ImageResource.h" |
| 34 #include "core/fetch/MemoryCache.h" | 35 #include "core/fetch/MemoryCache.h" |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 // Also parser-blocking scripts (set explicitly in loadPriority) | 114 // Also parser-blocking scripts (set explicitly in loadPriority) |
| 114 return ResourceLoadPriorityVeryHigh; | 115 return ResourceLoadPriorityVeryHigh; |
| 115 case Resource::XSLStyleSheet: | 116 case Resource::XSLStyleSheet: |
| 116 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); | 117 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); |
| 117 case Resource::Raw: | 118 case Resource::Raw: |
| 118 case Resource::ImportResource: | 119 case Resource::ImportResource: |
| 119 case Resource::Script: | 120 case Resource::Script: |
| 120 // Also visible resources/images (set explicitly in loadPriority) | 121 // Also visible resources/images (set explicitly in loadPriority) |
| 121 return ResourceLoadPriorityHigh; | 122 return ResourceLoadPriorityHigh; |
| 122 case Resource::Manifest: | 123 case Resource::Manifest: |
| 123 // Also late-body scripts discovered by the preload scanner (set explicitl y in loadPriority) | 124 // Also late-body scripts discovered by the preload scanner (set |
| 125 // explicitly in loadPriority) | |
| 124 return ResourceLoadPriorityMedium; | 126 return ResourceLoadPriorityMedium; |
| 125 case Resource::Image: | 127 case Resource::Image: |
| 126 case Resource::TextTrack: | 128 case Resource::TextTrack: |
| 127 case Resource::Media: | 129 case Resource::Media: |
| 128 case Resource::SVGDocument: | 130 case Resource::SVGDocument: |
| 129 // Also async scripts (set explicitly in loadPriority) | 131 // Also async scripts (set explicitly in loadPriority) |
| 130 return ResourceLoadPriorityLow; | 132 return ResourceLoadPriorityLow; |
| 131 case Resource::LinkPrefetch: | 133 case Resource::LinkPrefetch: |
| 132 return ResourceLoadPriorityVeryLow; | 134 return ResourceLoadPriorityVeryLow; |
| 133 } | 135 } |
| 134 | 136 |
| 135 NOTREACHED(); | 137 NOTREACHED(); |
| 136 return ResourceLoadPriorityUnresolved; | 138 return ResourceLoadPriorityUnresolved; |
| 137 } | 139 } |
| 138 | 140 |
| 139 ResourceLoadPriority ResourceFetcher::computeLoadPriority( | 141 ResourceLoadPriority ResourceFetcher::computeLoadPriority( |
| 140 Resource::Type type, | 142 Resource::Type type, |
| 141 const FetchRequest& request, | 143 const FetchRequest& request, |
| 142 ResourcePriority::VisibilityStatus visibility) { | 144 ResourcePriority::VisibilityStatus visibility) { |
| 143 ResourceLoadPriority priority = typeToPriority(type); | 145 ResourceLoadPriority priority = typeToPriority(type); |
| 144 | 146 |
| 145 // Visible resources (images in practice) get a boost to High priority. | 147 // Visible resources (images in practice) get a boost to High priority. |
| 146 if (visibility == ResourcePriority::Visible) | 148 if (visibility == ResourcePriority::Visible) |
| 147 priority = ResourceLoadPriorityHigh; | 149 priority = ResourceLoadPriorityHigh; |
| 148 | 150 |
| 149 // Resources before the first image are considered "early" in the document | 151 // Resources before the first image are considered "early" in the document and |
| 150 // and resources after the first image are "late" in the document. Important to | 152 // resources after the first image are "late" in the document. Important to |
| 151 // note that this is based on when the preload scanner discovers a resource | 153 // note that this is based on when the preload scanner discovers a resource |
| 152 // for the most part so the main parser may not have reached the image element yet. | 154 // for the most part so the main parser may not have reached the image element |
| 155 // yet. | |
| 153 if (type == Resource::Image) | 156 if (type == Resource::Image) |
| 154 m_imageFetched = true; | 157 m_imageFetched = true; |
| 155 | 158 |
| 156 if (FetchRequest::IdleLoad == request.defer()) { | 159 if (FetchRequest::IdleLoad == request.defer()) { |
| 157 priority = ResourceLoadPriorityVeryLow; | 160 priority = ResourceLoadPriorityVeryLow; |
| 158 } else if (type == Resource::Script) { | 161 } else if (type == Resource::Script) { |
| 159 // Special handling for scripts. | 162 // Special handling for scripts. |
| 160 // Default/Parser-Blocking/Preload early in document: High (set in typeToPri ority) | 163 // Default/Parser-Blocking/Preload early in document: High (set in |
| 164 // typeToPriority) | |
| 161 // Async/Defer: Low Priority (applies to both preload and parser-inserted) | 165 // Async/Defer: Low Priority (applies to both preload and parser-inserted) |
| 162 // Preload late in document: Medium | 166 // Preload late in document: Medium |
| 163 if (FetchRequest::LazyLoad == request.defer()) | 167 if (FetchRequest::LazyLoad == request.defer()) |
| 164 priority = ResourceLoadPriorityLow; | 168 priority = ResourceLoadPriorityLow; |
| 165 else if (request.forPreload() && m_imageFetched) | 169 else if (request.forPreload() && m_imageFetched) |
| 166 priority = ResourceLoadPriorityMedium; | 170 priority = ResourceLoadPriorityMedium; |
| 167 } else if (FetchRequest::LazyLoad == request.defer()) { | 171 } else if (FetchRequest::LazyLoad == request.defer()) { |
| 168 priority = ResourceLoadPriorityVeryLow; | 172 priority = ResourceLoadPriorityVeryLow; |
| 169 } | 173 } |
| 170 | 174 |
| 171 // A manually set priority acts as a floor. This is used to ensure that synchr onous requests | 175 // A manually set priority acts as a floor. This is used to ensure that |
| 172 // are always given the highest possible priority, as well as to ensure that t here isn't priority | 176 // synchronous requests are always given the highest possible priority, as |
| 173 // churn if images move in and out of the viewport, or is displayed more than once, both in and out | 177 // well as to ensure that there isn't priority churn if images move in and out |
| 174 // of the viewport. | 178 // of the viewport, or is displayed more than once, both in and out of the |
| 179 // viewport. | |
| 175 return std::max(context().modifyPriorityForExperiments(priority), | 180 return std::max(context().modifyPriorityForExperiments(priority), |
| 176 request.resourceRequest().priority()); | 181 request.resourceRequest().priority()); |
| 177 } | 182 } |
| 178 | 183 |
| 179 static void populateResourceTiming(ResourceTimingInfo* info, | 184 static void populateResourceTiming(ResourceTimingInfo* info, |
| 180 Resource* resource) { | 185 Resource* resource) { |
| 181 info->setInitialRequest(resource->resourceRequest()); | 186 info->setInitialRequest(resource->resourceRequest()); |
| 182 info->setFinalResponse(resource->response()); | 187 info->setFinalResponse(resource->response()); |
| 183 } | 188 } |
| 184 | 189 |
| 185 static WebURLRequest::RequestContext requestContextFromType( | 190 static WebURLRequest::RequestContext requestContextFromType( |
| 186 bool isMainFrame, | 191 bool isMainFrame, |
| 187 Resource::Type type) { | 192 Resource::Type type) { |
| 188 switch (type) { | 193 switch (type) { |
| 189 case Resource::MainResource: | 194 case Resource::MainResource: |
| 190 if (!isMainFrame) | 195 if (!isMainFrame) |
| 191 return WebURLRequest::RequestContextIframe; | 196 return WebURLRequest::RequestContextIframe; |
| 192 // FIXME: Change this to a context frame type (once we introduce them): ht tp://fetch.spec.whatwg.org/#concept-request-context-frame-type | 197 // FIXME: Change this to a context frame type (once we introduce them): |
| 198 // http://fetch.spec.whatwg.org/#concept-request-context-frame-type | |
| 193 return WebURLRequest::RequestContextHyperlink; | 199 return WebURLRequest::RequestContextHyperlink; |
| 194 case Resource::XSLStyleSheet: | 200 case Resource::XSLStyleSheet: |
| 195 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); | 201 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); |
| 196 case Resource::CSSStyleSheet: | 202 case Resource::CSSStyleSheet: |
| 197 return WebURLRequest::RequestContextStyle; | 203 return WebURLRequest::RequestContextStyle; |
| 198 case Resource::Script: | 204 case Resource::Script: |
| 199 return WebURLRequest::RequestContextScript; | 205 return WebURLRequest::RequestContextScript; |
| 200 case Resource::Font: | 206 case Resource::Font: |
| 201 return WebURLRequest::RequestContextFont; | 207 return WebURLRequest::RequestContextFont; |
| 202 case Resource::Image: | 208 case Resource::Image: |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 FetchRequest::UseDefaultOriginRestrictionForType)) | 257 FetchRequest::UseDefaultOriginRestrictionForType)) |
| 252 return false; | 258 return false; |
| 253 | 259 |
| 254 SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get(); | 260 SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get(); |
| 255 if (!sourceOrigin) | 261 if (!sourceOrigin) |
| 256 sourceOrigin = context().getSecurityOrigin(); | 262 sourceOrigin = context().getSecurityOrigin(); |
| 257 | 263 |
| 258 if (sourceOrigin->canRequestNoSuborigin(response.url())) | 264 if (sourceOrigin->canRequestNoSuborigin(response.url())) |
| 259 return true; | 265 return true; |
| 260 | 266 |
| 261 // Use the original response instead of the 304 response for a successful reva ldiation. | 267 // Use the original response instead of the 304 response for a successful |
| 268 // revaldiation. | |
| 262 const ResourceResponse& responseForAccessControl = | 269 const ResourceResponse& responseForAccessControl = |
| 263 (resource->isCacheValidator() && response.httpStatusCode() == 304) | 270 (resource->isCacheValidator() && response.httpStatusCode() == 304) |
| 264 ? resource->response() | 271 ? resource->response() |
| 265 : response; | 272 : response; |
| 266 String errorDescription; | 273 String errorDescription; |
| 267 if (!passesAccessControlCheck( | 274 if (!passesAccessControlCheck( |
| 268 responseForAccessControl, resource->options().allowCredentials, | 275 responseForAccessControl, resource->options().allowCredentials, |
| 269 sourceOrigin, errorDescription, | 276 sourceOrigin, errorDescription, |
| 270 resource->lastResourceRequest().requestContext())) { | 277 resource->lastResourceRequest().requestContext())) { |
| 271 resource->setCORSFailed(); | 278 resource->setCORSFailed(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 !m_validatedURLs.contains(resource->url())) | 318 !m_validatedURLs.contains(resource->url())) |
| 312 context().dispatchDidLoadResourceFromMemoryCache( | 319 context().dispatchDidLoadResourceFromMemoryCache( |
| 313 identifier, resource, request.resourceRequest().frameType(), | 320 identifier, resource, request.resourceRequest().frameType(), |
| 314 request.resourceRequest().requestContext()); | 321 request.resourceRequest().requestContext()); |
| 315 | 322 |
| 316 if (isStaticData) | 323 if (isStaticData) |
| 317 return; | 324 return; |
| 318 | 325 |
| 319 if (type == ResourceLoadingFromCache && !resource->stillNeedsLoad() && | 326 if (type == ResourceLoadingFromCache && !resource->stillNeedsLoad() && |
| 320 !m_validatedURLs.contains(request.resourceRequest().url())) { | 327 !m_validatedURLs.contains(request.resourceRequest().url())) { |
| 321 // Resources loaded from memory cache should be reported the first time they 're used. | 328 // Resources loaded from memory cache should be reported the first time |
| 329 // they're used. | |
| 322 std::unique_ptr<ResourceTimingInfo> info = ResourceTimingInfo::create( | 330 std::unique_ptr<ResourceTimingInfo> info = ResourceTimingInfo::create( |
| 323 request.options().initiatorInfo.name, monotonicallyIncreasingTime(), | 331 request.options().initiatorInfo.name, monotonicallyIncreasingTime(), |
| 324 resource->getType() == Resource::MainResource); | 332 resource->getType() == Resource::MainResource); |
| 325 populateResourceTiming(info.get(), resource); | 333 populateResourceTiming(info.get(), resource); |
| 326 info->clearLoadTimings(); | 334 info->clearLoadTimings(); |
| 327 info->setLoadFinishTime(info->initialTime()); | 335 info->setLoadFinishTime(info->initialTime()); |
| 328 m_scheduledResourceTimingReports.append(std::move(info)); | 336 m_scheduledResourceTimingReports.append(std::move(info)); |
| 329 if (!m_resourceTimingReportTimer.isActive()) | 337 if (!m_resourceTimingReportTimer.isActive()) |
| 330 m_resourceTimingReportTimer.startOneShot(0, BLINK_FROM_HERE); | 338 m_resourceTimingReportTimer.startOneShot(0, BLINK_FROM_HERE); |
| 331 } | 339 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 342 return value; | 350 return value; |
| 343 } | 351 } |
| 344 | 352 |
| 345 Resource* ResourceFetcher::resourceForStaticData( | 353 Resource* ResourceFetcher::resourceForStaticData( |
| 346 const FetchRequest& request, | 354 const FetchRequest& request, |
| 347 const ResourceFactory& factory, | 355 const ResourceFactory& factory, |
| 348 const SubstituteData& substituteData) { | 356 const SubstituteData& substituteData) { |
| 349 const KURL& url = request.resourceRequest().url(); | 357 const KURL& url = request.resourceRequest().url(); |
| 350 DCHECK(url.protocolIsData() || substituteData.isValid() || m_archive); | 358 DCHECK(url.protocolIsData() || substituteData.isValid() || m_archive); |
| 351 | 359 |
| 352 // TODO(japhet): We only send main resource data: urls through WebURLLoader fo r the benefit of | 360 // TODO(japhet): We only send main resource data: urls through WebURLLoader |
| 353 // a service worker test (RenderViewImplTest.ServiceWorkerNetworkProviderSetup ), which is at a | 361 // for the benefit of a service worker test |
| 354 // layer where it isn't easy to mock out a network load. It uses data: urls to emulate the | 362 // (RenderViewImplTest.ServiceWorkerNetworkProviderSetup), which is at a layer |
| 355 // behavior it wants to test, which would otherwise be reserved for network lo ads. | 363 // where it isn't easy to mock out a network load. It uses data: urls to |
| 364 // emulate the behavior it wants to test, which would otherwise be reserved | |
| 365 // for network loads. | |
| 356 if (!m_archive && !substituteData.isValid() && | 366 if (!m_archive && !substituteData.isValid() && |
| 357 (factory.type() == Resource::MainResource || | 367 (factory.type() == Resource::MainResource || |
| 358 factory.type() == Resource::Raw)) | 368 factory.type() == Resource::Raw)) |
| 359 return nullptr; | 369 return nullptr; |
| 360 | 370 |
| 361 const String cacheIdentifier = getCacheIdentifier(); | 371 const String cacheIdentifier = getCacheIdentifier(); |
| 362 if (Resource* oldResource = | 372 if (Resource* oldResource = |
| 363 memoryCache()->resourceForURL(url, cacheIdentifier)) { | 373 memoryCache()->resourceForURL(url, cacheIdentifier)) { |
| 364 // There's no reason to re-parse if we saved the data from the previous pars e. | 374 // There's no reason to re-parse if we saved the data from the previous |
| 375 // parse. | |
| 365 if (request.options().dataBufferingPolicy != DoNotBufferData) | 376 if (request.options().dataBufferingPolicy != DoNotBufferData) |
| 366 return oldResource; | 377 return oldResource; |
| 367 memoryCache()->remove(oldResource); | 378 memoryCache()->remove(oldResource); |
| 368 } | 379 } |
| 369 | 380 |
| 370 WebString mimetype; | 381 WebString mimetype; |
| 371 WebString charset; | 382 WebString charset; |
| 372 RefPtr<SharedBuffer> data; | 383 RefPtr<SharedBuffer> data; |
| 373 if (substituteData.isValid()) { | 384 if (substituteData.isValid()) { |
| 374 mimetype = substituteData.mimeType(); | 385 mimetype = substituteData.mimeType(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 | 419 |
| 409 if (!substituteData.isValid()) | 420 if (!substituteData.isValid()) |
| 410 memoryCache()->add(resource); | 421 memoryCache()->add(resource); |
| 411 | 422 |
| 412 return resource; | 423 return resource; |
| 413 } | 424 } |
| 414 | 425 |
| 415 void ResourceFetcher::moveCachedNonBlockingResourceToBlocking( | 426 void ResourceFetcher::moveCachedNonBlockingResourceToBlocking( |
| 416 Resource* resource, | 427 Resource* resource, |
| 417 const FetchRequest& request) { | 428 const FetchRequest& request) { |
| 418 // TODO(yoav): Test that non-blocking resources (video/audio/track) continue t o not-block even after being preloaded and discovered. | 429 // TODO(yoav): Test that non-blocking resources (video/audio/track) continue |
| 430 // to not-block even after being preloaded and discovered. | |
| 419 if (resource && resource->loader() && | 431 if (resource && resource->loader() && |
| 420 resource->isLoadEventBlockingResourceType() && | 432 resource->isLoadEventBlockingResourceType() && |
| 421 resource->isLinkPreload() && !request.forPreload()) { | 433 resource->isLinkPreload() && !request.forPreload()) { |
| 422 m_nonBlockingLoaders.remove(resource->loader()); | 434 m_nonBlockingLoaders.remove(resource->loader()); |
| 423 m_loaders.add(resource->loader()); | 435 m_loaders.add(resource->loader()); |
| 424 } | 436 } |
| 425 } | 437 } |
| 426 | 438 |
| 427 void ResourceFetcher::updateMemoryCacheStats(Resource* resource, | 439 void ResourceFetcher::updateMemoryCacheStats(Resource* resource, |
| 428 RevalidationPolicy policy, | 440 RevalidationPolicy policy, |
| 429 const FetchRequest& request, | 441 const FetchRequest& request, |
| 430 const ResourceFactory& factory, | 442 const ResourceFactory& factory, |
| 431 bool isStaticData) const { | 443 bool isStaticData) const { |
| 432 if (isStaticData) | 444 if (isStaticData) |
| 433 return; | 445 return; |
| 434 | 446 |
| 435 if (request.forPreload()) { | 447 if (request.forPreload()) { |
| 436 DEFINE_RESOURCE_HISTOGRAM("Preload."); | 448 DEFINE_RESOURCE_HISTOGRAM("Preload."); |
| 437 } else { | 449 } else { |
| 438 DEFINE_RESOURCE_HISTOGRAM(""); | 450 DEFINE_RESOURCE_HISTOGRAM(""); |
| 439 } | 451 } |
| 440 | 452 |
| 441 // Aims to count Resource only referenced from MemoryCache (i.e. what | 453 // Aims to count Resource only referenced from MemoryCache (i.e. what would be |
| 442 // would be dead if MemoryCache holds weak references to Resource). | 454 // dead if MemoryCache holds weak references to Resource). Currently we check |
| 443 // Currently we check references to Resource from ResourceClient and | 455 // references to Resource from ResourceClient and |m_preloads| only, because |
| 444 // |m_preloads| only, because they are major sources of references. | 456 // they are major sources of references. |
| 445 if (resource && !resource->isAlive() && | 457 if (resource && !resource->isAlive() && |
| 446 (!m_preloads || !m_preloads->contains(resource))) { | 458 (!m_preloads || !m_preloads->contains(resource))) { |
| 447 DEFINE_RESOURCE_HISTOGRAM("Dead."); | 459 DEFINE_RESOURCE_HISTOGRAM("Dead."); |
| 448 } | 460 } |
| 449 } | 461 } |
| 450 | 462 |
| 451 Resource* ResourceFetcher::requestResource( | 463 Resource* ResourceFetcher::requestResource( |
| 452 FetchRequest& request, | 464 FetchRequest& request, |
| 453 const ResourceFactory& factory, | 465 const ResourceFactory& factory, |
| 454 const SubstituteData& substituteData) { | 466 const SubstituteData& substituteData) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 activityLogger->logEvent("blinkRequestResource", argv.size(), | 515 activityLogger->logEvent("blinkRequestResource", argv.size(), |
| 504 argv.data()); | 516 argv.data()); |
| 505 } | 517 } |
| 506 } | 518 } |
| 507 | 519 |
| 508 bool isDataUrl = request.resourceRequest().url().protocolIsData(); | 520 bool isDataUrl = request.resourceRequest().url().protocolIsData(); |
| 509 bool isStaticData = isDataUrl || substituteData.isValid() || m_archive; | 521 bool isStaticData = isDataUrl || substituteData.isValid() || m_archive; |
| 510 Resource* resource(nullptr); | 522 Resource* resource(nullptr); |
| 511 if (isStaticData) { | 523 if (isStaticData) { |
| 512 resource = resourceForStaticData(request, factory, substituteData); | 524 resource = resourceForStaticData(request, factory, substituteData); |
| 513 // Abort the request if the archive doesn't contain the resource, except | 525 // Abort the request if the archive doesn't contain the resource, except in |
| 514 // in the case of data URLs which might have resources such as fonts | 526 // the case of data URLs which might have resources such as fonts that need |
| 515 // that need to be decoded only on demand. These data URLs are allowed | 527 // to be decoded only on demand. These data URLs are allowed to be |
| 516 // to be processed using the normal ResourceFetcher machinery. | 528 // processed using the normal ResourceFetcher machinery. |
| 517 if (!resource && !isDataUrl && m_archive) | 529 if (!resource && !isDataUrl && m_archive) |
| 518 return nullptr; | 530 return nullptr; |
| 519 } | 531 } |
| 520 if (!resource) | 532 if (!resource) |
| 521 resource = | 533 resource = |
| 522 memoryCache()->resourceForURL(request.url(), getCacheIdentifier()); | 534 memoryCache()->resourceForURL(request.url(), getCacheIdentifier()); |
| 523 | 535 |
| 524 // See if we can use an existing resource from the cache. If so, we need to mo ve it to be load blocking. | 536 // See if we can use an existing resource from the cache. If so, we need to |
| 537 // move it to be load blocking. | |
| 525 moveCachedNonBlockingResourceToBlocking(resource, request); | 538 moveCachedNonBlockingResourceToBlocking(resource, request); |
| 526 | 539 |
| 527 const RevalidationPolicy policy = determineRevalidationPolicy( | 540 const RevalidationPolicy policy = determineRevalidationPolicy( |
| 528 factory.type(), request, resource, isStaticData); | 541 factory.type(), request, resource, isStaticData); |
| 529 TRACE_EVENT_INSTANT1("blink", "ResourceFetcher::determineRevalidationPolicy", | 542 TRACE_EVENT_INSTANT1("blink", "ResourceFetcher::determineRevalidationPolicy", |
| 530 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy); | 543 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy); |
| 531 | 544 |
| 532 updateMemoryCacheStats(resource, policy, request, factory, isStaticData); | 545 updateMemoryCacheStats(resource, policy, request, factory, isStaticData); |
| 533 | 546 |
| 534 request.mutableResourceRequest().setAllowStoredCredentials( | 547 request.mutableResourceRequest().setAllowStoredCredentials( |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 558 return nullptr; | 571 return nullptr; |
| 559 } | 572 } |
| 560 | 573 |
| 561 if (!resource->isAlive()) | 574 if (!resource->isAlive()) |
| 562 m_deadStatsRecorder.update(policy); | 575 m_deadStatsRecorder.update(policy); |
| 563 | 576 |
| 564 if (policy != Use) | 577 if (policy != Use) |
| 565 resource->setIdentifier(identifier); | 578 resource->setIdentifier(identifier); |
| 566 | 579 |
| 567 if (!request.forPreload() || policy != Use) { | 580 if (!request.forPreload() || policy != Use) { |
| 568 // When issuing another request for a resource that is already in-flight mak e | 581 // When issuing another request for a resource that is already in-flight |
| 569 // sure to not demote the priority of the in-flight request. If the new requ est | 582 // make sure to not demote the priority of the in-flight request. If the new |
| 570 // isn't at the same priority as the in-flight request, only allow promotion s. | 583 // request isn't at the same priority as the in-flight request, only allow |
| 571 // This can happen when a visible image's priority is increased and then ano ther | 584 // promotions. This can happen when a visible image's priority is increased |
| 572 // reference to the image is parsed (which would be at a lower priority). | 585 // and then another reference to the image is parsed (which would be at a |
| 586 // lower priority). | |
| 573 if (request.resourceRequest().priority() > | 587 if (request.resourceRequest().priority() > |
| 574 resource->resourceRequest().priority()) | 588 resource->resourceRequest().priority()) |
| 575 resource->didChangePriority(request.resourceRequest().priority(), 0); | 589 resource->didChangePriority(request.resourceRequest().priority(), 0); |
| 576 } | 590 } |
| 577 | 591 |
| 578 // If only the fragment identifiers differ, it is the same resource. | 592 // If only the fragment identifiers differ, it is the same resource. |
| 579 DCHECK(equalIgnoringFragmentIdentifier(resource->url(), request.url())); | 593 DCHECK(equalIgnoringFragmentIdentifier(resource->url(), request.url())); |
| 580 requestLoadStarted( | 594 requestLoadStarted( |
| 581 identifier, resource, request, | 595 identifier, resource, request, |
| 582 policy == Use ? ResourceLoadingFromCache : ResourceLoadingFromNetwork, | 596 policy == Use ? ResourceLoadingFromCache : ResourceLoadingFromNetwork, |
| 583 isStaticData); | 597 isStaticData); |
| 584 m_documentResources.set( | 598 m_documentResources.set( |
| 585 MemoryCache::removeFragmentIdentifierIfNeeded(request.url()), resource); | 599 MemoryCache::removeFragmentIdentifierIfNeeded(request.url()), resource); |
| 586 | 600 |
| 587 // Returns with an existing resource if the resource does not need to start | 601 // Returns with an existing resource if the resource does not need to start |
| 588 // loading immediately. | 602 // loading immediately. If revalidation policy was determined as |Revalidate|, |
| 589 // If revalidation policy was determined as |Revalidate|, the resource was | 603 // the resource was already initialized for the revalidation here, but won't |
| 590 // already initialized for the revalidation here, but won't start loading. | 604 // start loading. |
| 591 if (!resourceNeedsLoad(resource, request, policy)) | 605 if (!resourceNeedsLoad(resource, request, policy)) |
| 592 return resource; | 606 return resource; |
| 593 | 607 |
| 594 if (!startLoad(resource)) | 608 if (!startLoad(resource)) |
| 595 return nullptr; | 609 return nullptr; |
| 596 DCHECK(!resource->errorOccurred() || | 610 DCHECK(!resource->errorOccurred() || |
| 597 request.options().synchronousPolicy == RequestSynchronously); | 611 request.options().synchronousPolicy == RequestSynchronously); |
| 598 return resource; | 612 return resource; |
| 599 } | 613 } |
| 600 | 614 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 728 Resource* existingResource, | 742 Resource* existingResource, |
| 729 bool isStaticData) const { | 743 bool isStaticData) const { |
| 730 const ResourceRequest& request = fetchRequest.resourceRequest(); | 744 const ResourceRequest& request = fetchRequest.resourceRequest(); |
| 731 | 745 |
| 732 if (!existingResource) | 746 if (!existingResource) |
| 733 return Load; | 747 return Load; |
| 734 | 748 |
| 735 // Checks if the resource has an explicit policy about integrity metadata. | 749 // Checks if the resource has an explicit policy about integrity metadata. |
| 736 // Currently only applies to ScriptResources. | 750 // Currently only applies to ScriptResources. |
| 737 // | 751 // |
| 738 // This is necessary because ScriptResource objects do not keep the raw | 752 // This is necessary because ScriptResource objects do not keep the raw data |
| 739 // data around after the source is accessed once, so if the resource is | 753 // around after the source is accessed once, so if the resource is accessed |
| 740 // accessed from the MemoryCache for a second time, there is no way to redo | 754 // from the MemoryCache for a second time, there is no way to redo an |
| 741 // an integrity check. | 755 // integrity check. |
| 742 // | 756 // |
| 743 // Thus, Blink implements a scheme where it caches the integrity | 757 // Thus, Blink implements a scheme where it caches the integrity information |
| 744 // information for a ScriptResource after the first time it is checked, and | 758 // for a ScriptResource after the first time it is checked, and if there is |
| 745 // if there is another request for that resource, with the same integrity | 759 // another request for that resource, with the same integrity metadata, Blink |
| 746 // metadata, Blink skips the integrity calculation. However, if the | 760 // skips the integrity calculation. However, if the integrity metadata is a |
| 747 // integrity metadata is a mismatch, the MemoryCache must be skipped here, | 761 // mismatch, the MemoryCache must be skipped here, and a new request for the |
| 748 // and a new request for the resource must be made to get the raw data. | 762 // resource must be made to get the raw data. This is expected to be an |
| 749 // This is expected to be an uncommon case, however, as it implies two | 763 // uncommon case, however, as it implies two same-origin requests to the same |
| 750 // same-origin requests to the same resource, but with different integrity | 764 // resource, but with different integrity metadata. |
| 751 // metadata. | |
| 752 RecordSriResourceIntegrityMismatchEvent(CheckingForIntegrityMismatch); | 765 RecordSriResourceIntegrityMismatchEvent(CheckingForIntegrityMismatch); |
| 753 if (existingResource->mustRefetchDueToIntegrityMetadata(fetchRequest)) { | 766 if (existingResource->mustRefetchDueToIntegrityMetadata(fetchRequest)) { |
| 754 RecordSriResourceIntegrityMismatchEvent(RefetchDueToIntegrityMismatch); | 767 RecordSriResourceIntegrityMismatchEvent(RefetchDueToIntegrityMismatch); |
| 755 return Reload; | 768 return Reload; |
| 756 } | 769 } |
| 757 | 770 |
| 758 // Service Worker's CORS fallback message must not be cached. | 771 // Service Worker's CORS fallback message must not be cached. |
| 759 if (existingResource->response().wasFallbackRequiredByServiceWorker()) | 772 if (existingResource->response().wasFallbackRequiredByServiceWorker()) |
| 760 return Reload; | 773 return Reload; |
| 761 | 774 |
| 762 // We already have a preload going for this URL. | 775 // We already have a preload going for this URL. |
| 763 if (fetchRequest.forPreload() && existingResource->isPreloaded()) | 776 if (fetchRequest.forPreload() && existingResource->isPreloaded()) |
| 764 return Use; | 777 return Use; |
| 765 | 778 |
| 766 // If the same URL has been loaded as a different type, we need to reload. | 779 // If the same URL has been loaded as a different type, we need to reload. |
| 767 if (existingResource->getType() != type) { | 780 if (existingResource->getType() != type) { |
| 768 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch | 781 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch |
| 769 // We really should discard the new prefetch since the preload has more | 782 // We really should discard the new prefetch since the preload has more |
| 770 // specific type information! crbug.com/379893 | 783 // specific type information! crbug.com/379893 |
| 771 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. | 784 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. |
| 772 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 785 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 773 "reloading due to type mismatch."; | 786 "reloading due to type mismatch."; |
| 774 return Reload; | 787 return Reload; |
| 775 } | 788 } |
| 776 | 789 |
| 777 // Do not load from cache if images are not enabled. | 790 // Do not load from cache if images are not enabled. There are two general |
| 778 // There are two general cases: | 791 // cases: |
| 779 // 1. Images are disabled. Don't ever load images, even if the image is | 792 // |
| 780 // cached or it is a data: url. In this case, we "Reload" the image, | 793 // 1. Images are disabled. Don't ever load images, even if the image is cached |
| 781 // then defer it with resourceNeedsLoad() so that it never actually | 794 // or it is a data: url. In this case, we "Reload" the image, then defer it |
| 782 // goes to the network. | 795 // with resourceNeedsLoad() so that it never actually goes to the network. |
| 783 // 2. Images are enabled, but not loaded automatically. In this case, we | 796 // |
| 784 // will Use cached resources or data: urls, but will similarly fall back | 797 // 2. Images are enabled, but not loaded automatically. In this case, we will |
| 785 // to a deferred network load if we don't have the data available | 798 // Use cached resources or data: urls, but will similarly fall back to a |
| 786 // without a network request. We check allowImage() here, which is | 799 // deferred network load if we don't have the data available without a network |
| 787 // affected by m_imagesEnabled but not m_autoLoadImages, in order to | 800 // request. We check allowImage() here, which is affected by m_imagesEnabled |
| 788 // allow for this differing behavior. | 801 // but not m_autoLoadImages, in order to allow for this differing behavior. |
| 802 // | |
| 789 // TODO(japhet): Can we get rid of one of these settings? | 803 // TODO(japhet): Can we get rid of one of these settings? |
| 790 if (existingResource->isImage() && | 804 if (existingResource->isImage() && |
| 791 !context().allowImage(m_imagesEnabled, existingResource->url())) | 805 !context().allowImage(m_imagesEnabled, existingResource->url())) |
| 792 return Reload; | 806 return Reload; |
| 793 | 807 |
| 794 // Never use cache entries for downloadToFile / useStreamOnResponse | 808 // Never use cache entries for downloadToFile / useStreamOnResponse requests. |
| 795 // requests. The data will be delivered through other paths. | 809 // The data will be delivered through other paths. |
| 796 if (request.downloadToFile() || request.useStreamOnResponse()) | 810 if (request.downloadToFile() || request.useStreamOnResponse()) |
| 797 return Reload; | 811 return Reload; |
| 798 | 812 |
| 799 // Never reuse opaque responses from a service worker for requests that | 813 // Never reuse opaque responses from a service worker for requests that are |
| 800 // are not no-cors. https://crbug.com/625575 | 814 // not no-cors. https://crbug.com/625575 |
| 801 if (existingResource->response().wasFetchedViaServiceWorker() && | 815 if (existingResource->response().wasFetchedViaServiceWorker() && |
| 802 existingResource->response().serviceWorkerResponseType() == | 816 existingResource->response().serviceWorkerResponseType() == |
| 803 WebServiceWorkerResponseTypeOpaque && | 817 WebServiceWorkerResponseTypeOpaque && |
| 804 request.fetchRequestMode() != WebURLRequest::FetchRequestModeNoCORS) | 818 request.fetchRequestMode() != WebURLRequest::FetchRequestModeNoCORS) |
| 805 return Reload; | 819 return Reload; |
| 806 | 820 |
| 807 // If resource was populated from a SubstituteData load or data: url, use it. | 821 // If resource was populated from a SubstituteData load or data: url, use it. |
| 808 if (isStaticData) | 822 if (isStaticData) |
| 809 return Use; | 823 return Use; |
| 810 | 824 |
| 811 if (!existingResource->canReuse(request)) | 825 if (!existingResource->canReuse(request)) |
| 812 return Reload; | 826 return Reload; |
| 813 | 827 |
| 814 // Certain requests (e.g., XHRs) might have manually set headers that require revalidation. | 828 // Certain requests (e.g., XHRs) might have manually set headers that require |
| 815 // In theory, this should be a Revalidate case. In practice, the MemoryCache r evalidation path assumes a whole bunch | 829 // revalidation. In theory, this should be a Revalidate case. In practice, the |
| 816 // of things about how revalidation works that manual headers violate, so punt to Reload instead. | 830 // MemoryCache revalidation path assumes a whole bunch of things about how |
| 831 // revalidation works that manual headers violate, so punt to Reload instead. | |
| 817 // | 832 // |
| 818 // Similarly, a request with manually added revalidation headers can lead | 833 // Similarly, a request with manually added revalidation headers can lead to a |
| 819 // to a 304 response for a request that wasn't flagged as a revalidation | 834 // 304 response for a request that wasn't flagged as a revalidation attempt. |
| 820 // attempt. Normally, successful revalidation will maintain the original | 835 // Normally, successful revalidation will maintain the original response's |
| 821 // response's status code, but for a manual revalidation the response code | 836 // status code, but for a manual revalidation the response code remains 304. |
| 822 // remains 304. In this case, the Resource likely has insufficient context | 837 // In this case, the Resource likely has insufficient context to provide a |
| 823 // to provide a useful cache hit or revalidation. | 838 // useful cache hit or revalidation. See http://crbug.com/643659 |
| 824 // See http://crbug.com/643659 | |
| 825 if (request.isConditional() || | 839 if (request.isConditional() || |
| 826 existingResource->response().httpStatusCode() == 304) | 840 existingResource->response().httpStatusCode() == 304) |
| 827 return Reload; | 841 return Reload; |
| 828 | 842 |
| 829 // Don't try to reuse an in-progress async request for a new sync request. | 843 // Don't try to reuse an in-progress async request for a new sync request. |
| 830 if (fetchRequest.options().synchronousPolicy == RequestSynchronously && | 844 if (fetchRequest.options().synchronousPolicy == RequestSynchronously && |
| 831 existingResource->isLoading()) | 845 existingResource->isLoading()) |
| 832 return Reload; | 846 return Reload; |
| 833 | 847 |
| 834 // Don't reload resources while pasting. | 848 // Don't reload resources while pasting. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 847 if (cachePolicy == CachePolicyHistoryBuffer) | 861 if (cachePolicy == CachePolicyHistoryBuffer) |
| 848 return Use; | 862 return Use; |
| 849 | 863 |
| 850 // Don't reuse resources with Cache-control: no-store. | 864 // Don't reuse resources with Cache-control: no-store. |
| 851 if (existingResource->hasCacheControlNoStoreHeader()) { | 865 if (existingResource->hasCacheControlNoStoreHeader()) { |
| 852 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 866 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 853 "reloading due to Cache-control: no-store."; | 867 "reloading due to Cache-control: no-store."; |
| 854 return Reload; | 868 return Reload; |
| 855 } | 869 } |
| 856 | 870 |
| 857 // If credentials were sent with the previous request and won't be | 871 // If credentials were sent with the previous request and won't be with this |
| 858 // with this one, or vice versa, re-fetch the resource. | 872 // one, or vice versa, re-fetch the resource. |
| 859 // | 873 // |
| 860 // This helps with the case where the server sends back | 874 // This helps with the case where the server sends back |
| 861 // "Access-Control-Allow-Origin: *" all the time, but some of the | 875 // "Access-Control-Allow-Origin: *" all the time, but some of the client's |
| 862 // client's requests are made without CORS and some with. | 876 // requests are made without CORS and some with. |
| 863 if (existingResource->resourceRequest().allowStoredCredentials() != | 877 if (existingResource->resourceRequest().allowStoredCredentials() != |
| 864 request.allowStoredCredentials()) { | 878 request.allowStoredCredentials()) { |
| 865 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 879 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 866 "reloading due to difference in credentials " | 880 "reloading due to difference in credentials " |
| 867 "settings."; | 881 "settings."; |
| 868 return Reload; | 882 return Reload; |
| 869 } | 883 } |
| 870 | 884 |
| 871 // During the initial load, avoid loading the same resource multiple times for a single document, | 885 // During the initial load, avoid loading the same resource multiple times for |
| 872 // even if the cache policies would tell us to. | 886 // a single document, even if the cache policies would tell us to. We also |
| 873 // We also group loads of the same resource together. | 887 // group loads of the same resource together. Raw resources are exempted, as |
| 874 // Raw resources are exempted, as XHRs fall into this category and may have us er-set Cache-Control: | 888 // XHRs fall into this category and may have user-set Cache-Control: headers |
| 875 // headers or other factors that require separate requests. | 889 // or other factors that require separate requests. |
| 876 if (type != Resource::Raw) { | 890 if (type != Resource::Raw) { |
| 877 if (!context().isLoadComplete() && | 891 if (!context().isLoadComplete() && |
| 878 m_validatedURLs.contains(existingResource->url())) | 892 m_validatedURLs.contains(existingResource->url())) |
| 879 return Use; | 893 return Use; |
| 880 if (existingResource->isLoading()) | 894 if (existingResource->isLoading()) |
| 881 return Use; | 895 return Use; |
| 882 } | 896 } |
| 883 | 897 |
| 884 if (request.getCachePolicy() == WebCachePolicy::BypassingCache) | 898 if (request.getCachePolicy() == WebCachePolicy::BypassingCache) |
| 885 return Reload; | 899 return Reload; |
| 886 | 900 |
| 887 // CachePolicyReload always reloads | 901 // CachePolicyReload always reloads |
| 888 if (cachePolicy == CachePolicyReload) { | 902 if (cachePolicy == CachePolicyReload) { |
| 889 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 903 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 890 "reloading due to CachePolicyReload."; | 904 "reloading due to CachePolicyReload."; |
| 891 return Reload; | 905 return Reload; |
| 892 } | 906 } |
| 893 | 907 |
| 894 // We'll try to reload the resource if it failed last time. | 908 // We'll try to reload the resource if it failed last time. |
| 895 if (existingResource->errorOccurred()) { | 909 if (existingResource->errorOccurred()) { |
| 896 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::" | 910 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::" |
| 897 "determineRevalidationPolicye reloading due " | 911 "determineRevalidationPolicye reloading due " |
| 898 "to resource being in the error state"; | 912 "to resource being in the error state"; |
| 899 return Reload; | 913 return Reload; |
| 900 } | 914 } |
| 901 | 915 |
| 902 // List of available images logic allows images to be re-used without cache va lidation. We restrict this only to images | 916 // List of available images logic allows images to be re-used without cache |
| 903 // from memory cache which are the same as the version in the current document . | 917 // validation. We restrict this only to images from memory cache which are the |
| 918 // same as the version in the current document. | |
| 904 if (type == Resource::Image && | 919 if (type == Resource::Image && |
| 905 existingResource == cachedResource(request.url())) | 920 existingResource == cachedResource(request.url())) |
| 906 return Use; | 921 return Use; |
| 907 | 922 |
| 908 // Defer to the browser process cache for Vary header handling. | 923 // Defer to the browser process cache for Vary header handling. |
| 909 if (existingResource->hasVaryHeader()) | 924 if (existingResource->hasVaryHeader()) |
| 910 return Reload; | 925 return Reload; |
| 911 | 926 |
| 912 // If any of the redirects in the chain to loading the resource were not cache able, we cannot reuse our cached resource. | 927 // If any of the redirects in the chain to loading the resource were not |
| 928 // cacheable, we cannot reuse our cached resource. | |
| 913 if (!existingResource->canReuseRedirectChain()) { | 929 if (!existingResource->canReuseRedirectChain()) { |
| 914 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 930 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 915 "reloading due to an uncacheable redirect"; | 931 "reloading due to an uncacheable redirect"; |
| 916 return Reload; | 932 return Reload; |
| 917 } | 933 } |
| 918 | 934 |
| 919 // Check if the cache headers requires us to revalidate (cache expiration for example). | 935 // Check if the cache headers requires us to revalidate (cache expiration for |
| 936 // example). | |
| 920 if (cachePolicy == CachePolicyRevalidate || | 937 if (cachePolicy == CachePolicyRevalidate || |
| 921 existingResource->mustRevalidateDueToCacheHeaders() || | 938 existingResource->mustRevalidateDueToCacheHeaders() || |
| 922 request.cacheControlContainsNoCache()) { | 939 request.cacheControlContainsNoCache()) { |
| 923 // See if the resource has usable ETag or Last-modified headers. | 940 // See if the resource has usable ETag or Last-modified headers. If the page |
| 924 // If the page is controlled by the ServiceWorker, we choose the Reload poli cy because the revalidation headers should not be exposed to the ServiceWorker.( crbug.com/429570) | 941 // is controlled by the ServiceWorker, we choose the Reload policy because |
| 942 // the revalidation headers should not be exposed to the | |
| 943 // ServiceWorker.(crbug.com/429570) | |
| 925 if (existingResource->canUseCacheValidator() && | 944 if (existingResource->canUseCacheValidator() && |
| 926 !context().isControlledByServiceWorker()) { | 945 !context().isControlledByServiceWorker()) { |
| 927 // If the resource is already a cache validator but not started yet, | 946 // If the resource is already a cache validator but not started yet, the |
| 928 // the |Use| policy should be applied to subsequent requests. | 947 // |Use| policy should be applied to subsequent requests. |
| 929 if (existingResource->isCacheValidator()) { | 948 if (existingResource->isCacheValidator()) { |
| 930 DCHECK(existingResource->stillNeedsLoad()); | 949 DCHECK(existingResource->stillNeedsLoad()); |
| 931 return Use; | 950 return Use; |
| 932 } | 951 } |
| 933 return Revalidate; | 952 return Revalidate; |
| 934 } | 953 } |
| 935 | 954 |
| 936 // No, must reload. | 955 // No, must reload. |
| 937 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 956 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 938 "reloading due to missing cache validators."; | 957 "reloading due to missing cache validators."; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1064 return m_archive ? m_archive->mainResource() : nullptr; | 1083 return m_archive ? m_archive->mainResource() : nullptr; |
| 1065 } | 1084 } |
| 1066 | 1085 |
| 1067 void ResourceFetcher::didFinishLoading(Resource* resource, | 1086 void ResourceFetcher::didFinishLoading(Resource* resource, |
| 1068 double finishTime, | 1087 double finishTime, |
| 1069 int64_t encodedDataLength, | 1088 int64_t encodedDataLength, |
| 1070 DidFinishLoadingReason finishReason) { | 1089 DidFinishLoadingReason finishReason) { |
| 1071 TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier()); | 1090 TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier()); |
| 1072 DCHECK(resource); | 1091 DCHECK(resource); |
| 1073 | 1092 |
| 1074 // When loading a multipart resource, make the loader non-block when | 1093 // When loading a multipart resource, make the loader non-block when finishing |
| 1075 // finishing loading the first part. | 1094 // loading the first part. |
| 1076 if (finishReason == DidFinishFirstPartInMultipart) | 1095 if (finishReason == DidFinishFirstPartInMultipart) |
| 1077 moveResourceLoaderToNonBlocking(resource->loader()); | 1096 moveResourceLoaderToNonBlocking(resource->loader()); |
| 1078 else | 1097 else |
| 1079 removeResourceLoader(resource->loader()); | 1098 removeResourceLoader(resource->loader()); |
| 1080 DCHECK(!m_loaders.contains(resource->loader())); | 1099 DCHECK(!m_loaders.contains(resource->loader())); |
| 1081 DCHECK(finishReason == DidFinishFirstPartInMultipart || | 1100 DCHECK(finishReason == DidFinishFirstPartInMultipart || |
| 1082 !m_nonBlockingLoaders.contains(resource->loader())); | 1101 !m_nonBlockingLoaders.contains(resource->loader())); |
| 1083 | 1102 |
| 1084 if (std::unique_ptr<ResourceTimingInfo> info = | 1103 if (std::unique_ptr<ResourceTimingInfo> info = |
| 1085 m_resourceTimingInfoMap.take(resource)) { | 1104 m_resourceTimingInfoMap.take(resource)) { |
| 1086 if (resource->response().isHTTP() && | 1105 if (resource->response().isHTTP() && |
| 1087 resource->response().httpStatusCode() < 400) { | 1106 resource->response().httpStatusCode() < 400) { |
| 1088 populateResourceTiming(info.get(), resource); | 1107 populateResourceTiming(info.get(), resource); |
| 1089 info->setLoadFinishTime(finishTime); | 1108 info->setLoadFinishTime(finishTime); |
| 1090 // encodedDataLength == -1 means "not available". | 1109 // encodedDataLength == -1 means "not available". |
| 1091 // TODO(ricea): Find cases where it is not available but the | 1110 // TODO(ricea): Find cases where it is not available but the |
| 1092 // PerformanceResourceTiming spec requires it to be available and | 1111 // PerformanceResourceTiming spec requires it to be available and fix |
| 1093 // fix them. | 1112 // them. |
| 1094 info->addFinalTransferSize(encodedDataLength == -1 ? 0 | 1113 info->addFinalTransferSize(encodedDataLength == -1 ? 0 |
| 1095 : encodedDataLength); | 1114 : encodedDataLength); |
| 1096 if (resource->options().requestInitiatorContext == DocumentContext) | 1115 if (resource->options().requestInitiatorContext == DocumentContext) |
| 1097 context().addResourceTiming(*info); | 1116 context().addResourceTiming(*info); |
| 1098 resource->reportResourceTimingToClients(*info); | 1117 resource->reportResourceTimingToClients(*info); |
| 1099 } | 1118 } |
| 1100 } | 1119 } |
| 1101 context().dispatchDidFinishLoading(resource->identifier(), finishTime, | 1120 context().dispatchDidFinishLoading(resource->identifier(), finishTime, |
| 1102 encodedDataLength); | 1121 encodedDataLength); |
| 1103 if (finishReason == DidFinishLoading) | 1122 if (finishReason == DidFinishLoading) |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1123 // |rawHandle|'s ownership is transferred to the callee. | 1142 // |rawHandle|'s ownership is transferred to the callee. |
| 1124 std::unique_ptr<WebDataConsumerHandle> handle = wrapUnique(rawHandle); | 1143 std::unique_ptr<WebDataConsumerHandle> handle = wrapUnique(rawHandle); |
| 1125 | 1144 |
| 1126 if (response.wasFetchedViaServiceWorker()) { | 1145 if (response.wasFetchedViaServiceWorker()) { |
| 1127 if (resource->options().corsEnabled == IsCORSEnabled && | 1146 if (resource->options().corsEnabled == IsCORSEnabled && |
| 1128 response.wasFallbackRequiredByServiceWorker()) { | 1147 response.wasFallbackRequiredByServiceWorker()) { |
| 1129 ResourceRequest request = resource->lastResourceRequest(); | 1148 ResourceRequest request = resource->lastResourceRequest(); |
| 1130 DCHECK_EQ(request.skipServiceWorker(), | 1149 DCHECK_EQ(request.skipServiceWorker(), |
| 1131 WebURLRequest::SkipServiceWorker::None); | 1150 WebURLRequest::SkipServiceWorker::None); |
| 1132 // This code handles the case when a regular controlling service worker | 1151 // This code handles the case when a regular controlling service worker |
| 1133 // doesn't handle a cross origin request. When this happens we still | 1152 // doesn't handle a cross origin request. When this happens we still want |
| 1134 // want to give foreign fetch a chance to handle the request, so | 1153 // to give foreign fetch a chance to handle the request, so only skip the |
| 1135 // only skip the controlling service worker for the fallback request. | 1154 // controlling service worker for the fallback request. This is currently |
| 1136 // This is currently safe because of http://crbug.com/604084 the | 1155 // safe because of http://crbug.com/604084 the |
| 1137 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch | 1156 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch |
| 1138 // handled a request. | 1157 // handled a request. |
| 1139 request.setSkipServiceWorker( | 1158 request.setSkipServiceWorker( |
| 1140 WebURLRequest::SkipServiceWorker::Controlling); | 1159 WebURLRequest::SkipServiceWorker::Controlling); |
| 1141 resource->loader()->restartForServiceWorkerFallback(request); | 1160 resource->loader()->restartForServiceWorkerFallback(request); |
| 1142 return; | 1161 return; |
| 1143 } | 1162 } |
| 1144 | 1163 |
| 1145 // If the response is fetched via ServiceWorker, the original URL of the res ponse could be different from the URL of the request. | 1164 // If the response is fetched via ServiceWorker, the original URL of the |
| 1146 // We check the URL not to load the resources which are forbidden by the pag e CSP. | 1165 // response could be different from the URL of the request. We check the URL |
| 1166 // not to load the resources which are forbidden by the page CSP. | |
| 1147 // https://w3c.github.io/webappsec-csp/#should-block-response | 1167 // https://w3c.github.io/webappsec-csp/#should-block-response |
| 1148 const KURL& originalURL = response.originalURLViaServiceWorker(); | 1168 const KURL& originalURL = response.originalURLViaServiceWorker(); |
| 1149 if (!originalURL.isEmpty() && | 1169 if (!originalURL.isEmpty() && |
| 1150 !context().allowResponse(resource->getType(), | 1170 !context().allowResponse(resource->getType(), |
| 1151 resource->resourceRequest(), originalURL, | 1171 resource->resourceRequest(), originalURL, |
| 1152 resource->options())) { | 1172 resource->options())) { |
| 1153 resource->loader()->didFail( | 1173 resource->loader()->didFail( |
| 1154 nullptr, ResourceError::cancelledDueToAccessCheckError(originalURL)); | 1174 nullptr, ResourceError::cancelledDueToAccessCheckError(originalURL)); |
| 1155 return; | 1175 return; |
| 1156 } | 1176 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1204 DCHECK(resource->stillNeedsLoad()); | 1224 DCHECK(resource->stillNeedsLoad()); |
| 1205 if (!context().shouldLoadNewResource(resource->getType())) { | 1225 if (!context().shouldLoadNewResource(resource->getType())) { |
| 1206 memoryCache()->remove(resource); | 1226 memoryCache()->remove(resource); |
| 1207 return false; | 1227 return false; |
| 1208 } | 1228 } |
| 1209 | 1229 |
| 1210 ResourceRequest request(resource->resourceRequest()); | 1230 ResourceRequest request(resource->resourceRequest()); |
| 1211 willSendRequest(resource->identifier(), request, ResourceResponse(), | 1231 willSendRequest(resource->identifier(), request, ResourceResponse(), |
| 1212 resource->options()); | 1232 resource->options()); |
| 1213 | 1233 |
| 1214 // Resource requests from suborigins should not be intercepted by the | 1234 // Resource requests from suborigins should not be intercepted by the service |
| 1215 // service worker of the physical origin. This has the effect that, for | 1235 // worker of the physical origin. This has the effect that, for now, |
| 1216 // now, suborigins do not work with service workers. See | 1236 // suborigins do not work with service workers. See |
| 1217 // https://w3c.github.io/webappsec-suborigins/. | 1237 // https://w3c.github.io/webappsec-suborigins/. |
| 1218 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); | 1238 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); |
| 1219 if (sourceOrigin && sourceOrigin->hasSuborigin()) | 1239 if (sourceOrigin && sourceOrigin->hasSuborigin()) |
| 1220 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); | 1240 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); |
| 1221 | 1241 |
| 1222 ResourceLoader* loader = ResourceLoader::create(this, resource); | 1242 ResourceLoader* loader = ResourceLoader::create(this, resource); |
| 1223 if (resource->shouldBlockLoadEvent()) | 1243 if (resource->shouldBlockLoadEvent()) |
| 1224 m_loaders.add(loader); | 1244 m_loaders.add(loader); |
| 1225 else | 1245 else |
| 1226 m_nonBlockingLoaders.add(loader); | 1246 m_nonBlockingLoaders.add(loader); |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1555 visitor->trace(m_context); | 1575 visitor->trace(m_context); |
| 1556 visitor->trace(m_archive); | 1576 visitor->trace(m_archive); |
| 1557 visitor->trace(m_loaders); | 1577 visitor->trace(m_loaders); |
| 1558 visitor->trace(m_nonBlockingLoaders); | 1578 visitor->trace(m_nonBlockingLoaders); |
| 1559 visitor->trace(m_documentResources); | 1579 visitor->trace(m_documentResources); |
| 1560 visitor->trace(m_preloads); | 1580 visitor->trace(m_preloads); |
| 1561 visitor->trace(m_resourceTimingInfoMap); | 1581 visitor->trace(m_resourceTimingInfoMap); |
| 1562 } | 1582 } |
| 1563 | 1583 |
| 1564 } // namespace blink | 1584 } // namespace blink |
| OLD | NEW |