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 |