| 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. |
| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 activityLogger->logEvent("blinkRequestResource", argv.size(), | 516 activityLogger->logEvent("blinkRequestResource", argv.size(), |
| 505 argv.data()); | 517 argv.data()); |
| 506 } | 518 } |
| 507 } | 519 } |
| 508 | 520 |
| 509 bool isDataUrl = request.resourceRequest().url().protocolIsData(); | 521 bool isDataUrl = request.resourceRequest().url().protocolIsData(); |
| 510 bool isStaticData = isDataUrl || substituteData.isValid() || m_archive; | 522 bool isStaticData = isDataUrl || substituteData.isValid() || m_archive; |
| 511 Resource* resource(nullptr); | 523 Resource* resource(nullptr); |
| 512 if (isStaticData) { | 524 if (isStaticData) { |
| 513 resource = resourceForStaticData(request, factory, substituteData); | 525 resource = resourceForStaticData(request, factory, substituteData); |
| 514 // Abort the request if the archive doesn't contain the resource, except | 526 // Abort the request if the archive doesn't contain the resource, except in |
| 515 // in the case of data URLs which might have resources such as fonts | 527 // the case of data URLs which might have resources such as fonts that need |
| 516 // that need to be decoded only on demand. These data URLs are allowed | 528 // to be decoded only on demand. These data URLs are allowed to be |
| 517 // to be processed using the normal ResourceFetcher machinery. | 529 // processed using the normal ResourceFetcher machinery. |
| 518 if (!resource && !isDataUrl && m_archive) | 530 if (!resource && !isDataUrl && m_archive) |
| 519 return nullptr; | 531 return nullptr; |
| 520 } | 532 } |
| 521 if (!resource) | 533 if (!resource) |
| 522 resource = | 534 resource = |
| 523 memoryCache()->resourceForURL(request.url(), getCacheIdentifier()); | 535 memoryCache()->resourceForURL(request.url(), getCacheIdentifier()); |
| 524 | 536 |
| 525 // See if we can use an existing resource from the cache. If so, we need to mo
ve it to be load blocking. | 537 // See if we can use an existing resource from the cache. If so, we need to |
| 538 // move it to be load blocking. |
| 526 moveCachedNonBlockingResourceToBlocking(resource, request); | 539 moveCachedNonBlockingResourceToBlocking(resource, request); |
| 527 | 540 |
| 528 const RevalidationPolicy policy = determineRevalidationPolicy( | 541 const RevalidationPolicy policy = determineRevalidationPolicy( |
| 529 factory.type(), request, resource, isStaticData); | 542 factory.type(), request, resource, isStaticData); |
| 530 TRACE_EVENT_INSTANT1("blink", "ResourceFetcher::determineRevalidationPolicy", | 543 TRACE_EVENT_INSTANT1("blink", "ResourceFetcher::determineRevalidationPolicy", |
| 531 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy); | 544 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy); |
| 532 | 545 |
| 533 updateMemoryCacheStats(resource, policy, request, factory, isStaticData); | 546 updateMemoryCacheStats(resource, policy, request, factory, isStaticData); |
| 534 | 547 |
| 535 request.mutableResourceRequest().setAllowStoredCredentials( | 548 request.mutableResourceRequest().setAllowStoredCredentials( |
| (...skipping 23 matching lines...) Expand all Loading... |
| 559 return nullptr; | 572 return nullptr; |
| 560 } | 573 } |
| 561 | 574 |
| 562 if (!resource->isAlive()) | 575 if (!resource->isAlive()) |
| 563 m_deadStatsRecorder.update(policy); | 576 m_deadStatsRecorder.update(policy); |
| 564 | 577 |
| 565 if (policy != Use) | 578 if (policy != Use) |
| 566 resource->setIdentifier(identifier); | 579 resource->setIdentifier(identifier); |
| 567 | 580 |
| 568 if (!request.forPreload() || policy != Use) { | 581 if (!request.forPreload() || policy != Use) { |
| 569 // When issuing another request for a resource that is already in-flight mak
e | 582 // When issuing another request for a resource that is already in-flight |
| 570 // sure to not demote the priority of the in-flight request. If the new requ
est | 583 // make sure to not demote the priority of the in-flight request. If the new |
| 571 // isn't at the same priority as the in-flight request, only allow promotion
s. | 584 // request isn't at the same priority as the in-flight request, only allow |
| 572 // This can happen when a visible image's priority is increased and then ano
ther | 585 // promotions. This can happen when a visible image's priority is increased |
| 573 // reference to the image is parsed (which would be at a lower priority). | 586 // and then another reference to the image is parsed (which would be at a |
| 587 // lower priority). |
| 574 if (request.resourceRequest().priority() > | 588 if (request.resourceRequest().priority() > |
| 575 resource->resourceRequest().priority()) | 589 resource->resourceRequest().priority()) |
| 576 resource->didChangePriority(request.resourceRequest().priority(), 0); | 590 resource->didChangePriority(request.resourceRequest().priority(), 0); |
| 577 } | 591 } |
| 578 | 592 |
| 579 // If only the fragment identifiers differ, it is the same resource. | 593 // If only the fragment identifiers differ, it is the same resource. |
| 580 DCHECK(equalIgnoringFragmentIdentifier(resource->url(), request.url())); | 594 DCHECK(equalIgnoringFragmentIdentifier(resource->url(), request.url())); |
| 581 requestLoadStarted( | 595 requestLoadStarted( |
| 582 identifier, resource, request, | 596 identifier, resource, request, |
| 583 policy == Use ? ResourceLoadingFromCache : ResourceLoadingFromNetwork, | 597 policy == Use ? ResourceLoadingFromCache : ResourceLoadingFromNetwork, |
| 584 isStaticData); | 598 isStaticData); |
| 585 m_documentResources.set( | 599 m_documentResources.set( |
| 586 MemoryCache::removeFragmentIdentifierIfNeeded(request.url()), resource); | 600 MemoryCache::removeFragmentIdentifierIfNeeded(request.url()), resource); |
| 587 | 601 |
| 588 // Returns with an existing resource if the resource does not need to start | 602 // Returns with an existing resource if the resource does not need to start |
| 589 // loading immediately. | 603 // loading immediately. If revalidation policy was determined as |Revalidate|, |
| 590 // If revalidation policy was determined as |Revalidate|, the resource was | 604 // the resource was already initialized for the revalidation here, but won't |
| 591 // already initialized for the revalidation here, but won't start loading. | 605 // start loading. |
| 592 if (!resourceNeedsLoad(resource, request, policy)) | 606 if (!resourceNeedsLoad(resource, request, policy)) |
| 593 return resource; | 607 return resource; |
| 594 | 608 |
| 595 if (!startLoad(resource)) | 609 if (!startLoad(resource)) |
| 596 return nullptr; | 610 return nullptr; |
| 597 DCHECK(!resource->errorOccurred() || | 611 DCHECK(!resource->errorOccurred() || |
| 598 request.options().synchronousPolicy == RequestSynchronously); | 612 request.options().synchronousPolicy == RequestSynchronously); |
| 599 return resource; | 613 return resource; |
| 600 } | 614 } |
| 601 | 615 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 Resource* existingResource, | 743 Resource* existingResource, |
| 730 bool isStaticData) const { | 744 bool isStaticData) const { |
| 731 const ResourceRequest& request = fetchRequest.resourceRequest(); | 745 const ResourceRequest& request = fetchRequest.resourceRequest(); |
| 732 | 746 |
| 733 if (!existingResource) | 747 if (!existingResource) |
| 734 return Load; | 748 return Load; |
| 735 | 749 |
| 736 // Checks if the resource has an explicit policy about integrity metadata. | 750 // Checks if the resource has an explicit policy about integrity metadata. |
| 737 // Currently only applies to ScriptResources. | 751 // Currently only applies to ScriptResources. |
| 738 // | 752 // |
| 739 // This is necessary because ScriptResource objects do not keep the raw | 753 // This is necessary because ScriptResource objects do not keep the raw data |
| 740 // data around after the source is accessed once, so if the resource is | 754 // around after the source is accessed once, so if the resource is accessed |
| 741 // accessed from the MemoryCache for a second time, there is no way to redo | 755 // from the MemoryCache for a second time, there is no way to redo an |
| 742 // an integrity check. | 756 // integrity check. |
| 743 // | 757 // |
| 744 // Thus, Blink implements a scheme where it caches the integrity | 758 // Thus, Blink implements a scheme where it caches the integrity information |
| 745 // information for a ScriptResource after the first time it is checked, and | 759 // for a ScriptResource after the first time it is checked, and if there is |
| 746 // if there is another request for that resource, with the same integrity | 760 // another request for that resource, with the same integrity metadata, Blink |
| 747 // metadata, Blink skips the integrity calculation. However, if the | 761 // skips the integrity calculation. However, if the integrity metadata is a |
| 748 // integrity metadata is a mismatch, the MemoryCache must be skipped here, | 762 // mismatch, the MemoryCache must be skipped here, and a new request for the |
| 749 // and a new request for the resource must be made to get the raw data. | 763 // resource must be made to get the raw data. This is expected to be an |
| 750 // This is expected to be an uncommon case, however, as it implies two | 764 // uncommon case, however, as it implies two same-origin requests to the same |
| 751 // same-origin requests to the same resource, but with different integrity | 765 // resource, but with different integrity metadata. |
| 752 // metadata. | |
| 753 RecordSriResourceIntegrityMismatchEvent(CheckingForIntegrityMismatch); | 766 RecordSriResourceIntegrityMismatchEvent(CheckingForIntegrityMismatch); |
| 754 if (existingResource->mustRefetchDueToIntegrityMetadata(fetchRequest)) { | 767 if (existingResource->mustRefetchDueToIntegrityMetadata(fetchRequest)) { |
| 755 RecordSriResourceIntegrityMismatchEvent(RefetchDueToIntegrityMismatch); | 768 RecordSriResourceIntegrityMismatchEvent(RefetchDueToIntegrityMismatch); |
| 756 return Reload; | 769 return Reload; |
| 757 } | 770 } |
| 758 | 771 |
| 759 // Service Worker's CORS fallback message must not be cached. | 772 // Service Worker's CORS fallback message must not be cached. |
| 760 if (existingResource->response().wasFallbackRequiredByServiceWorker()) | 773 if (existingResource->response().wasFallbackRequiredByServiceWorker()) |
| 761 return Reload; | 774 return Reload; |
| 762 | 775 |
| 763 // We already have a preload going for this URL. | 776 // We already have a preload going for this URL. |
| 764 if (fetchRequest.forPreload() && existingResource->isPreloaded()) | 777 if (fetchRequest.forPreload() && existingResource->isPreloaded()) |
| 765 return Use; | 778 return Use; |
| 766 | 779 |
| 767 // If the same URL has been loaded as a different type, we need to reload. | 780 // If the same URL has been loaded as a different type, we need to reload. |
| 768 if (existingResource->getType() != type) { | 781 if (existingResource->getType() != type) { |
| 769 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch | 782 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch |
| 770 // We really should discard the new prefetch since the preload has more | 783 // We really should discard the new prefetch since the preload has more |
| 771 // specific type information! crbug.com/379893 | 784 // specific type information! crbug.com/379893 |
| 772 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. | 785 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. |
| 773 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 786 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 774 "reloading due to type mismatch."; | 787 "reloading due to type mismatch."; |
| 775 return Reload; | 788 return Reload; |
| 776 } | 789 } |
| 777 | 790 |
| 778 // Do not load from cache if images are not enabled. | 791 // Do not load from cache if images are not enabled. There are two general |
| 779 // There are two general cases: | 792 // cases: |
| 780 // 1. Images are disabled. Don't ever load images, even if the image is | 793 // |
| 781 // cached or it is a data: url. In this case, we "Reload" the image, | 794 // 1. Images are disabled. Don't ever load images, even if the image is cached |
| 782 // then defer it with resourceNeedsLoad() so that it never actually | 795 // or it is a data: url. In this case, we "Reload" the image, then defer it |
| 783 // goes to the network. | 796 // with resourceNeedsLoad() so that it never actually goes to the network. |
| 784 // 2. Images are enabled, but not loaded automatically. In this case, we | 797 // |
| 785 // will Use cached resources or data: urls, but will similarly fall back | 798 // 2. Images are enabled, but not loaded automatically. In this case, we will |
| 786 // to a deferred network load if we don't have the data available | 799 // Use cached resources or data: urls, but will similarly fall back to a |
| 787 // without a network request. We check allowImage() here, which is | 800 // deferred network load if we don't have the data available without a network |
| 788 // affected by m_imagesEnabled but not m_autoLoadImages, in order to | 801 // request. We check allowImage() here, which is affected by m_imagesEnabled |
| 789 // allow for this differing behavior. | 802 // but not m_autoLoadImages, in order to allow for this differing behavior. |
| 803 // |
| 790 // TODO(japhet): Can we get rid of one of these settings? | 804 // TODO(japhet): Can we get rid of one of these settings? |
| 791 if (existingResource->isImage() && | 805 if (existingResource->isImage() && |
| 792 !context().allowImage(m_imagesEnabled, existingResource->url())) | 806 !context().allowImage(m_imagesEnabled, existingResource->url())) |
| 793 return Reload; | 807 return Reload; |
| 794 | 808 |
| 795 // Never use cache entries for downloadToFile / useStreamOnResponse | 809 // Never use cache entries for downloadToFile / useStreamOnResponse requests. |
| 796 // requests. The data will be delivered through other paths. | 810 // The data will be delivered through other paths. |
| 797 if (request.downloadToFile() || request.useStreamOnResponse()) | 811 if (request.downloadToFile() || request.useStreamOnResponse()) |
| 798 return Reload; | 812 return Reload; |
| 799 | 813 |
| 800 // Never reuse opaque responses from a service worker for requests that | 814 // Never reuse opaque responses from a service worker for requests that are |
| 801 // are not no-cors. https://crbug.com/625575 | 815 // not no-cors. https://crbug.com/625575 |
| 802 if (existingResource->response().wasFetchedViaServiceWorker() && | 816 if (existingResource->response().wasFetchedViaServiceWorker() && |
| 803 existingResource->response().serviceWorkerResponseType() == | 817 existingResource->response().serviceWorkerResponseType() == |
| 804 WebServiceWorkerResponseTypeOpaque && | 818 WebServiceWorkerResponseTypeOpaque && |
| 805 request.fetchRequestMode() != WebURLRequest::FetchRequestModeNoCORS) | 819 request.fetchRequestMode() != WebURLRequest::FetchRequestModeNoCORS) |
| 806 return Reload; | 820 return Reload; |
| 807 | 821 |
| 808 // If resource was populated from a SubstituteData load or data: url, use it. | 822 // If resource was populated from a SubstituteData load or data: url, use it. |
| 809 if (isStaticData) | 823 if (isStaticData) |
| 810 return Use; | 824 return Use; |
| 811 | 825 |
| 812 if (!existingResource->canReuse(request)) | 826 if (!existingResource->canReuse(request)) |
| 813 return Reload; | 827 return Reload; |
| 814 | 828 |
| 815 // Certain requests (e.g., XHRs) might have manually set headers that require
revalidation. | 829 // Certain requests (e.g., XHRs) might have manually set headers that require |
| 816 // In theory, this should be a Revalidate case. In practice, the MemoryCache r
evalidation path assumes a whole bunch | 830 // revalidation. In theory, this should be a Revalidate case. In practice, the |
| 817 // of things about how revalidation works that manual headers violate, so punt
to Reload instead. | 831 // MemoryCache revalidation path assumes a whole bunch of things about how |
| 832 // revalidation works that manual headers violate, so punt to Reload instead. |
| 818 // | 833 // |
| 819 // Similarly, a request with manually added revalidation headers can lead | 834 // Similarly, a request with manually added revalidation headers can lead to a |
| 820 // to a 304 response for a request that wasn't flagged as a revalidation | 835 // 304 response for a request that wasn't flagged as a revalidation attempt. |
| 821 // attempt. Normally, successful revalidation will maintain the original | 836 // Normally, successful revalidation will maintain the original response's |
| 822 // response's status code, but for a manual revalidation the response code | 837 // status code, but for a manual revalidation the response code remains 304. |
| 823 // remains 304. In this case, the Resource likely has insufficient context | 838 // In this case, the Resource likely has insufficient context to provide a |
| 824 // to provide a useful cache hit or revalidation. | 839 // useful cache hit or revalidation. See http://crbug.com/643659 |
| 825 // See http://crbug.com/643659 | |
| 826 if (request.isConditional() || | 840 if (request.isConditional() || |
| 827 existingResource->response().httpStatusCode() == 304) | 841 existingResource->response().httpStatusCode() == 304) |
| 828 return Reload; | 842 return Reload; |
| 829 | 843 |
| 830 // Don't try to reuse an in-progress async request for a new sync request. | 844 // Don't try to reuse an in-progress async request for a new sync request. |
| 831 if (fetchRequest.options().synchronousPolicy == RequestSynchronously && | 845 if (fetchRequest.options().synchronousPolicy == RequestSynchronously && |
| 832 existingResource->isLoading()) | 846 existingResource->isLoading()) |
| 833 return Reload; | 847 return Reload; |
| 834 | 848 |
| 835 // Don't reload resources while pasting. | 849 // Don't reload resources while pasting. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 848 if (cachePolicy == CachePolicyHistoryBuffer) | 862 if (cachePolicy == CachePolicyHistoryBuffer) |
| 849 return Use; | 863 return Use; |
| 850 | 864 |
| 851 // Don't reuse resources with Cache-control: no-store. | 865 // Don't reuse resources with Cache-control: no-store. |
| 852 if (existingResource->hasCacheControlNoStoreHeader()) { | 866 if (existingResource->hasCacheControlNoStoreHeader()) { |
| 853 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 867 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 854 "reloading due to Cache-control: no-store."; | 868 "reloading due to Cache-control: no-store."; |
| 855 return Reload; | 869 return Reload; |
| 856 } | 870 } |
| 857 | 871 |
| 858 // If credentials were sent with the previous request and won't be | 872 // If credentials were sent with the previous request and won't be with this |
| 859 // with this one, or vice versa, re-fetch the resource. | 873 // one, or vice versa, re-fetch the resource. |
| 860 // | 874 // |
| 861 // This helps with the case where the server sends back | 875 // This helps with the case where the server sends back |
| 862 // "Access-Control-Allow-Origin: *" all the time, but some of the | 876 // "Access-Control-Allow-Origin: *" all the time, but some of the client's |
| 863 // client's requests are made without CORS and some with. | 877 // requests are made without CORS and some with. |
| 864 if (existingResource->resourceRequest().allowStoredCredentials() != | 878 if (existingResource->resourceRequest().allowStoredCredentials() != |
| 865 request.allowStoredCredentials()) { | 879 request.allowStoredCredentials()) { |
| 866 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 880 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 867 "reloading due to difference in credentials " | 881 "reloading due to difference in credentials " |
| 868 "settings."; | 882 "settings."; |
| 869 return Reload; | 883 return Reload; |
| 870 } | 884 } |
| 871 | 885 |
| 872 // During the initial load, avoid loading the same resource multiple times for
a single document, | 886 // During the initial load, avoid loading the same resource multiple times for |
| 873 // even if the cache policies would tell us to. | 887 // a single document, even if the cache policies would tell us to. We also |
| 874 // We also group loads of the same resource together. | 888 // group loads of the same resource together. Raw resources are exempted, as |
| 875 // Raw resources are exempted, as XHRs fall into this category and may have us
er-set Cache-Control: | 889 // XHRs fall into this category and may have user-set Cache-Control: headers |
| 876 // headers or other factors that require separate requests. | 890 // or other factors that require separate requests. |
| 877 if (type != Resource::Raw) { | 891 if (type != Resource::Raw) { |
| 878 if (!context().isLoadComplete() && | 892 if (!context().isLoadComplete() && |
| 879 m_validatedURLs.contains(existingResource->url())) | 893 m_validatedURLs.contains(existingResource->url())) |
| 880 return Use; | 894 return Use; |
| 881 if (existingResource->isLoading()) | 895 if (existingResource->isLoading()) |
| 882 return Use; | 896 return Use; |
| 883 } | 897 } |
| 884 | 898 |
| 885 if (request.getCachePolicy() == WebCachePolicy::BypassingCache) | 899 if (request.getCachePolicy() == WebCachePolicy::BypassingCache) |
| 886 return Reload; | 900 return Reload; |
| 887 | 901 |
| 888 // CachePolicyReload always reloads | 902 // CachePolicyReload always reloads |
| 889 if (cachePolicy == CachePolicyReload) { | 903 if (cachePolicy == CachePolicyReload) { |
| 890 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 904 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 891 "reloading due to CachePolicyReload."; | 905 "reloading due to CachePolicyReload."; |
| 892 return Reload; | 906 return Reload; |
| 893 } | 907 } |
| 894 | 908 |
| 895 // We'll try to reload the resource if it failed last time. | 909 // We'll try to reload the resource if it failed last time. |
| 896 if (existingResource->errorOccurred()) { | 910 if (existingResource->errorOccurred()) { |
| 897 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::" | 911 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::" |
| 898 "determineRevalidationPolicye reloading due " | 912 "determineRevalidationPolicye reloading due " |
| 899 "to resource being in the error state"; | 913 "to resource being in the error state"; |
| 900 return Reload; | 914 return Reload; |
| 901 } | 915 } |
| 902 | 916 |
| 903 // List of available images logic allows images to be re-used without cache va
lidation. We restrict this only to images | 917 // List of available images logic allows images to be re-used without cache |
| 904 // from memory cache which are the same as the version in the current document
. | 918 // validation. We restrict this only to images from memory cache which are the |
| 919 // same as the version in the current document. |
| 905 if (type == Resource::Image && | 920 if (type == Resource::Image && |
| 906 existingResource == cachedResource(request.url())) | 921 existingResource == cachedResource(request.url())) |
| 907 return Use; | 922 return Use; |
| 908 | 923 |
| 909 // Defer to the browser process cache for Vary header handling. | 924 // Defer to the browser process cache for Vary header handling. |
| 910 if (existingResource->hasVaryHeader()) | 925 if (existingResource->hasVaryHeader()) |
| 911 return Reload; | 926 return Reload; |
| 912 | 927 |
| 913 // If any of the redirects in the chain to loading the resource were not cache
able, we cannot reuse our cached resource. | 928 // If any of the redirects in the chain to loading the resource were not |
| 929 // cacheable, we cannot reuse our cached resource. |
| 914 if (!existingResource->canReuseRedirectChain()) { | 930 if (!existingResource->canReuseRedirectChain()) { |
| 915 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 931 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 916 "reloading due to an uncacheable redirect"; | 932 "reloading due to an uncacheable redirect"; |
| 917 return Reload; | 933 return Reload; |
| 918 } | 934 } |
| 919 | 935 |
| 920 // Check if the cache headers requires us to revalidate (cache expiration for
example). | 936 // Check if the cache headers requires us to revalidate (cache expiration for |
| 937 // example). |
| 921 if (cachePolicy == CachePolicyRevalidate || | 938 if (cachePolicy == CachePolicyRevalidate || |
| 922 existingResource->mustRevalidateDueToCacheHeaders() || | 939 existingResource->mustRevalidateDueToCacheHeaders() || |
| 923 request.cacheControlContainsNoCache()) { | 940 request.cacheControlContainsNoCache()) { |
| 924 // See if the resource has usable ETag or Last-modified headers. | 941 // See if the resource has usable ETag or Last-modified headers. If the page |
| 925 // 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) | 942 // is controlled by the ServiceWorker, we choose the Reload policy because |
| 943 // the revalidation headers should not be exposed to the |
| 944 // ServiceWorker.(crbug.com/429570) |
| 926 if (existingResource->canUseCacheValidator() && | 945 if (existingResource->canUseCacheValidator() && |
| 927 !context().isControlledByServiceWorker()) { | 946 !context().isControlledByServiceWorker()) { |
| 928 // If the resource is already a cache validator but not started yet, | 947 // If the resource is already a cache validator but not started yet, the |
| 929 // the |Use| policy should be applied to subsequent requests. | 948 // |Use| policy should be applied to subsequent requests. |
| 930 if (existingResource->isCacheValidator()) { | 949 if (existingResource->isCacheValidator()) { |
| 931 DCHECK(existingResource->stillNeedsLoad()); | 950 DCHECK(existingResource->stillNeedsLoad()); |
| 932 return Use; | 951 return Use; |
| 933 } | 952 } |
| 934 return Revalidate; | 953 return Revalidate; |
| 935 } | 954 } |
| 936 | 955 |
| 937 // No, must reload. | 956 // No, must reload. |
| 938 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | 957 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 939 "reloading due to missing cache validators."; | 958 "reloading due to missing cache validators."; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1065 return m_archive ? m_archive->mainResource() : nullptr; | 1084 return m_archive ? m_archive->mainResource() : nullptr; |
| 1066 } | 1085 } |
| 1067 | 1086 |
| 1068 void ResourceFetcher::didFinishLoading(Resource* resource, | 1087 void ResourceFetcher::didFinishLoading(Resource* resource, |
| 1069 double finishTime, | 1088 double finishTime, |
| 1070 int64_t encodedDataLength, | 1089 int64_t encodedDataLength, |
| 1071 DidFinishLoadingReason finishReason) { | 1090 DidFinishLoadingReason finishReason) { |
| 1072 TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier()); | 1091 TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier()); |
| 1073 DCHECK(resource); | 1092 DCHECK(resource); |
| 1074 | 1093 |
| 1075 // When loading a multipart resource, make the loader non-block when | 1094 // When loading a multipart resource, make the loader non-block when finishing |
| 1076 // finishing loading the first part. | 1095 // loading the first part. |
| 1077 if (finishReason == DidFinishFirstPartInMultipart) | 1096 if (finishReason == DidFinishFirstPartInMultipart) |
| 1078 moveResourceLoaderToNonBlocking(resource->loader()); | 1097 moveResourceLoaderToNonBlocking(resource->loader()); |
| 1079 else | 1098 else |
| 1080 removeResourceLoader(resource->loader()); | 1099 removeResourceLoader(resource->loader()); |
| 1081 DCHECK(!m_loaders.contains(resource->loader())); | 1100 DCHECK(!m_loaders.contains(resource->loader())); |
| 1082 DCHECK(finishReason == DidFinishFirstPartInMultipart || | 1101 DCHECK(finishReason == DidFinishFirstPartInMultipart || |
| 1083 !m_nonBlockingLoaders.contains(resource->loader())); | 1102 !m_nonBlockingLoaders.contains(resource->loader())); |
| 1084 | 1103 |
| 1085 if (std::unique_ptr<ResourceTimingInfo> info = | 1104 if (std::unique_ptr<ResourceTimingInfo> info = |
| 1086 m_resourceTimingInfoMap.take(resource)) { | 1105 m_resourceTimingInfoMap.take(resource)) { |
| 1087 if (resource->response().isHTTP() && | 1106 if (resource->response().isHTTP() && |
| 1088 resource->response().httpStatusCode() < 400) { | 1107 resource->response().httpStatusCode() < 400) { |
| 1089 populateResourceTiming(info.get(), resource); | 1108 populateResourceTiming(info.get(), resource); |
| 1090 info->setLoadFinishTime(finishTime); | 1109 info->setLoadFinishTime(finishTime); |
| 1091 // encodedDataLength == -1 means "not available". | 1110 // encodedDataLength == -1 means "not available". |
| 1092 // TODO(ricea): Find cases where it is not available but the | 1111 // TODO(ricea): Find cases where it is not available but the |
| 1093 // PerformanceResourceTiming spec requires it to be available and | 1112 // PerformanceResourceTiming spec requires it to be available and fix |
| 1094 // fix them. | 1113 // them. |
| 1095 info->addFinalTransferSize(encodedDataLength == -1 ? 0 | 1114 info->addFinalTransferSize(encodedDataLength == -1 ? 0 |
| 1096 : encodedDataLength); | 1115 : encodedDataLength); |
| 1097 if (resource->options().requestInitiatorContext == DocumentContext) | 1116 if (resource->options().requestInitiatorContext == DocumentContext) |
| 1098 context().addResourceTiming(*info); | 1117 context().addResourceTiming(*info); |
| 1099 resource->reportResourceTimingToClients(*info); | 1118 resource->reportResourceTimingToClients(*info); |
| 1100 } | 1119 } |
| 1101 } | 1120 } |
| 1102 context().dispatchDidFinishLoading(resource->identifier(), finishTime, | 1121 context().dispatchDidFinishLoading(resource->identifier(), finishTime, |
| 1103 encodedDataLength); | 1122 encodedDataLength); |
| 1104 if (finishReason == DidFinishLoading) | 1123 if (finishReason == DidFinishLoading) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1124 // |rawHandle|'s ownership is transferred to the callee. | 1143 // |rawHandle|'s ownership is transferred to the callee. |
| 1125 std::unique_ptr<WebDataConsumerHandle> handle = wrapUnique(rawHandle); | 1144 std::unique_ptr<WebDataConsumerHandle> handle = wrapUnique(rawHandle); |
| 1126 | 1145 |
| 1127 if (response.wasFetchedViaServiceWorker()) { | 1146 if (response.wasFetchedViaServiceWorker()) { |
| 1128 if (resource->options().corsEnabled == IsCORSEnabled && | 1147 if (resource->options().corsEnabled == IsCORSEnabled && |
| 1129 response.wasFallbackRequiredByServiceWorker()) { | 1148 response.wasFallbackRequiredByServiceWorker()) { |
| 1130 ResourceRequest request = resource->lastResourceRequest(); | 1149 ResourceRequest request = resource->lastResourceRequest(); |
| 1131 DCHECK_EQ(request.skipServiceWorker(), | 1150 DCHECK_EQ(request.skipServiceWorker(), |
| 1132 WebURLRequest::SkipServiceWorker::None); | 1151 WebURLRequest::SkipServiceWorker::None); |
| 1133 // This code handles the case when a regular controlling service worker | 1152 // This code handles the case when a regular controlling service worker |
| 1134 // doesn't handle a cross origin request. When this happens we still | 1153 // doesn't handle a cross origin request. When this happens we still want |
| 1135 // want to give foreign fetch a chance to handle the request, so | 1154 // to give foreign fetch a chance to handle the request, so only skip the |
| 1136 // only skip the controlling service worker for the fallback request. | 1155 // controlling service worker for the fallback request. This is currently |
| 1137 // This is currently safe because of http://crbug.com/604084 the | 1156 // safe because of http://crbug.com/604084 the |
| 1138 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch | 1157 // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch |
| 1139 // handled a request. | 1158 // handled a request. |
| 1140 request.setSkipServiceWorker( | 1159 request.setSkipServiceWorker( |
| 1141 WebURLRequest::SkipServiceWorker::Controlling); | 1160 WebURLRequest::SkipServiceWorker::Controlling); |
| 1142 resource->loader()->restartForServiceWorkerFallback(request); | 1161 resource->loader()->restartForServiceWorkerFallback(request); |
| 1143 return; | 1162 return; |
| 1144 } | 1163 } |
| 1145 | 1164 |
| 1146 // If the response is fetched via ServiceWorker, the original URL of the res
ponse could be different from the URL of the request. | 1165 // If the response is fetched via ServiceWorker, the original URL of the |
| 1147 // We check the URL not to load the resources which are forbidden by the pag
e CSP. | 1166 // response could be different from the URL of the request. We check the URL |
| 1167 // not to load the resources which are forbidden by the page CSP. |
| 1148 // https://w3c.github.io/webappsec-csp/#should-block-response | 1168 // https://w3c.github.io/webappsec-csp/#should-block-response |
| 1149 const KURL& originalURL = response.originalURLViaServiceWorker(); | 1169 const KURL& originalURL = response.originalURLViaServiceWorker(); |
| 1150 if (!originalURL.isEmpty() && | 1170 if (!originalURL.isEmpty() && |
| 1151 !context().allowResponse(resource->getType(), | 1171 !context().allowResponse(resource->getType(), |
| 1152 resource->resourceRequest(), originalURL, | 1172 resource->resourceRequest(), originalURL, |
| 1153 resource->options())) { | 1173 resource->options())) { |
| 1154 resource->loader()->didFail( | 1174 resource->loader()->didFail( |
| 1155 nullptr, ResourceError::cancelledDueToAccessCheckError(originalURL)); | 1175 nullptr, ResourceError::cancelledDueToAccessCheckError(originalURL)); |
| 1156 return; | 1176 return; |
| 1157 } | 1177 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 DCHECK(resource->stillNeedsLoad()); | 1225 DCHECK(resource->stillNeedsLoad()); |
| 1206 if (!context().shouldLoadNewResource(resource->getType())) { | 1226 if (!context().shouldLoadNewResource(resource->getType())) { |
| 1207 memoryCache()->remove(resource); | 1227 memoryCache()->remove(resource); |
| 1208 return false; | 1228 return false; |
| 1209 } | 1229 } |
| 1210 | 1230 |
| 1211 ResourceRequest request(resource->resourceRequest()); | 1231 ResourceRequest request(resource->resourceRequest()); |
| 1212 willSendRequest(resource->identifier(), request, ResourceResponse(), | 1232 willSendRequest(resource->identifier(), request, ResourceResponse(), |
| 1213 resource->options()); | 1233 resource->options()); |
| 1214 | 1234 |
| 1215 // Resource requests from suborigins should not be intercepted by the | 1235 // Resource requests from suborigins should not be intercepted by the service |
| 1216 // service worker of the physical origin. This has the effect that, for | 1236 // worker of the physical origin. This has the effect that, for now, |
| 1217 // now, suborigins do not work with service workers. See | 1237 // suborigins do not work with service workers. See |
| 1218 // https://w3c.github.io/webappsec-suborigins/. | 1238 // https://w3c.github.io/webappsec-suborigins/. |
| 1219 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); | 1239 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); |
| 1220 if (sourceOrigin && sourceOrigin->hasSuborigin()) | 1240 if (sourceOrigin && sourceOrigin->hasSuborigin()) |
| 1221 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); | 1241 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); |
| 1222 | 1242 |
| 1223 ResourceLoader* loader = ResourceLoader::create(this, resource); | 1243 ResourceLoader* loader = ResourceLoader::create(this, resource); |
| 1224 if (resource->shouldBlockLoadEvent()) | 1244 if (resource->shouldBlockLoadEvent()) |
| 1225 m_loaders.add(loader); | 1245 m_loaders.add(loader); |
| 1226 else | 1246 else |
| 1227 m_nonBlockingLoaders.add(loader); | 1247 m_nonBlockingLoaders.add(loader); |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 visitor->trace(m_context); | 1576 visitor->trace(m_context); |
| 1557 visitor->trace(m_archive); | 1577 visitor->trace(m_archive); |
| 1558 visitor->trace(m_loaders); | 1578 visitor->trace(m_loaders); |
| 1559 visitor->trace(m_nonBlockingLoaders); | 1579 visitor->trace(m_nonBlockingLoaders); |
| 1560 visitor->trace(m_documentResources); | 1580 visitor->trace(m_documentResources); |
| 1561 visitor->trace(m_preloads); | 1581 visitor->trace(m_preloads); |
| 1562 visitor->trace(m_resourceTimingInfoMap); | 1582 visitor->trace(m_resourceTimingInfoMap); |
| 1563 } | 1583 } |
| 1564 | 1584 |
| 1565 } // namespace blink | 1585 } // namespace blink |
| OLD | NEW |