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