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 | 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
6 rights reserved. | 6 rights reserved. |
7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
8 | 8 |
9 This library is free software; you can redistribute it and/or | 9 This library is free software; you can redistribute it and/or |
10 modify it under the terms of the GNU Library General Public | 10 modify it under the terms of the GNU Library General Public |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, TextTrack) \ | 96 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, TextTrack) \ |
97 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, XSLStyleSheet) \ | 97 DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, XSLStyleSheet) \ |
98 } | 98 } |
99 | 99 |
100 bool IsCrossOrigin(const KURL& a, const KURL& b) { | 100 bool IsCrossOrigin(const KURL& a, const KURL& b) { |
101 RefPtr<SecurityOrigin> originA = SecurityOrigin::create(a); | 101 RefPtr<SecurityOrigin> originA = SecurityOrigin::create(a); |
102 RefPtr<SecurityOrigin> originB = SecurityOrigin::create(b); | 102 RefPtr<SecurityOrigin> originB = SecurityOrigin::create(b); |
103 return !originB->isSameSchemeHostPort(originA.get()); | 103 return !originB->isSameSchemeHostPort(originA.get()); |
104 } | 104 } |
105 | 105 |
106 void addRedirectsToTimingInfo(Resource* resource, ResourceTimingInfo* info) { | |
107 // Store redirect responses that were packed inside the final response. | |
108 const Vector<ResourceResponse>& responses = | |
109 resource->response().redirectResponses(); | |
110 for (size_t i = 0; i < responses.size(); ++i) { | |
111 const KURL& newURL = i + 1 < responses.size() | |
112 ? KURL(responses[i + 1].url()) | |
113 : resource->resourceRequest().url(); | |
114 bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL); | |
115 info->addRedirect(responses[i], crossOrigin); | |
116 } | |
117 } | |
118 | |
106 } // namespace | 119 } // namespace |
107 | 120 |
108 static void RecordSriResourceIntegrityMismatchEvent( | 121 static void RecordSriResourceIntegrityMismatchEvent( |
109 SriResourceIntegrityMismatchEvent event) { | 122 SriResourceIntegrityMismatchEvent event) { |
110 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 123 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
111 EnumerationHistogram, integrityHistogram, | 124 EnumerationHistogram, integrityHistogram, |
112 new EnumerationHistogram("sri.resource_integrity_mismatch_event", | 125 new EnumerationHistogram("sri.resource_integrity_mismatch_event", |
113 SriResourceIntegrityMismatchEventCount)); | 126 SriResourceIntegrityMismatchEventCount)); |
114 integrityHistogram.count(event); | 127 integrityHistogram.count(event); |
115 } | 128 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 NOTREACHED(); | 249 NOTREACHED(); |
237 return WebURLRequest::RequestContextSubresource; | 250 return WebURLRequest::RequestContextSubresource; |
238 } | 251 } |
239 | 252 |
240 ResourceFetcher::ResourceFetcher(FetchContext* newContext) | 253 ResourceFetcher::ResourceFetcher(FetchContext* newContext) |
241 : m_context(newContext), | 254 : m_context(newContext), |
242 m_archive(context().isMainFrame() ? nullptr : context().archive()), | 255 m_archive(context().isMainFrame() ? nullptr : context().archive()), |
243 m_resourceTimingReportTimer( | 256 m_resourceTimingReportTimer( |
244 this, | 257 this, |
245 &ResourceFetcher::resourceTimingReportTimerFired), | 258 &ResourceFetcher::resourceTimingReportTimerFired), |
259 m_mainResourceIdentifier(0), | |
246 m_autoLoadImages(true), | 260 m_autoLoadImages(true), |
247 m_imagesEnabled(true), | 261 m_imagesEnabled(true), |
248 m_allowStaleResources(false), | 262 m_allowStaleResources(false), |
249 m_imageFetched(false) { | 263 m_imageFetched(false) { |
250 ThreadState::current()->registerPreFinalizer(this); | 264 ThreadState::current()->registerPreFinalizer(this); |
251 } | 265 } |
252 | 266 |
253 ResourceFetcher::~ResourceFetcher() {} | 267 ResourceFetcher::~ResourceFetcher() {} |
254 | 268 |
255 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const { | 269 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const { |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
746 | 760 |
747 // - Don't add main resource to cache to prevent reuse. | 761 // - Don't add main resource to cache to prevent reuse. |
748 // - Don't add the resource if its body will not be stored. | 762 // - Don't add the resource if its body will not be stored. |
749 if (factory.type() != Resource::MainResource && | 763 if (factory.type() != Resource::MainResource && |
750 request.options().dataBufferingPolicy != DoNotBufferData) { | 764 request.options().dataBufferingPolicy != DoNotBufferData) { |
751 memoryCache()->add(resource); | 765 memoryCache()->add(resource); |
752 } | 766 } |
753 return resource; | 767 return resource; |
754 } | 768 } |
755 | 769 |
756 void ResourceFetcher::storeResourceTimingInitiatorInformation( | 770 void ResourceFetcher::storePerformanceTimingInitiatorInformation( |
757 Resource* resource) { | 771 Resource* resource) { |
758 const AtomicString& fetchInitiator = resource->options().initiatorInfo.name; | 772 const AtomicString& fetchInitiator = resource->options().initiatorInfo.name; |
759 if (fetchInitiator == FetchInitiatorTypeNames::internal) | 773 if (fetchInitiator == FetchInitiatorTypeNames::internal) |
760 return; | 774 return; |
761 | 775 |
762 bool isMainResource = resource->getType() == Resource::MainResource; | 776 bool isMainResource = resource->getType() == Resource::MainResource; |
763 | 777 |
764 // The request can already be fetched in a previous navigation. Thus | 778 // The request can already be fetched in a previous navigation. Thus |
765 // startTime must be set accordingly. | 779 // startTime must be set accordingly. |
766 double startTime = resource->resourceRequest().navigationStartTime() | 780 double startTime = resource->resourceRequest().navigationStartTime() |
767 ? resource->resourceRequest().navigationStartTime() | 781 ? resource->resourceRequest().navigationStartTime() |
768 : monotonicallyIncreasingTime(); | 782 : monotonicallyIncreasingTime(); |
769 | 783 |
770 std::unique_ptr<ResourceTimingInfo> info = | 784 std::unique_ptr<ResourceTimingInfo> info = |
771 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource); | 785 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource); |
772 | 786 |
773 if (resource->isCacheValidator()) { | 787 if (resource->isCacheValidator()) { |
774 const AtomicString& timingAllowOrigin = | 788 const AtomicString& timingAllowOrigin = |
775 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin); | 789 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin); |
776 if (!timingAllowOrigin.isEmpty()) | 790 if (!timingAllowOrigin.isEmpty()) |
777 info->setOriginalTimingAllowOrigin(timingAllowOrigin); | 791 info->setOriginalTimingAllowOrigin(timingAllowOrigin); |
778 } | 792 } |
779 | 793 |
780 if (!isMainResource || | 794 if (!isMainResource || |
781 context().updateTimingInfoForIFrameNavigation(info.get())) | 795 context().updateTimingInfoForIFrameNavigation(info.get())) { |
782 m_resourceTimingInfoMap.add(resource, std::move(info)); | 796 m_resourceTimingInfoMap.add(resource, std::move(info)); |
797 } else { | |
798 DCHECK(!m_mainResourceTimingInfo); | |
799 m_mainResourceTimingInfo = std::move(info); | |
800 m_mainResourceIdentifier = resource->identifier(); | |
Yoav Weiss
2016/12/05 19:21:04
Can you add a DCHECK here to make sure the resourc
sunjian
2016/12/07 19:09:50
Done.
| |
801 } | |
783 } | 802 } |
784 | 803 |
785 ResourceFetcher::RevalidationPolicy | 804 ResourceFetcher::RevalidationPolicy |
786 ResourceFetcher::determineRevalidationPolicy(Resource::Type type, | 805 ResourceFetcher::determineRevalidationPolicy(Resource::Type type, |
787 const FetchRequest& fetchRequest, | 806 const FetchRequest& fetchRequest, |
788 Resource* existingResource, | 807 Resource* existingResource, |
789 bool isStaticData) const { | 808 bool isStaticData) const { |
790 const ResourceRequest& request = fetchRequest.resourceRequest(); | 809 const ResourceRequest& request = fetchRequest.resourceRequest(); |
791 | 810 |
792 if (!existingResource) | 811 if (!existingResource) |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1114 } | 1133 } |
1115 | 1134 |
1116 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { | 1135 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { |
1117 // Only the top-frame can load MHTML. | 1136 // Only the top-frame can load MHTML. |
1118 if (!context().isMainFrame()) | 1137 if (!context().isMainFrame()) |
1119 return nullptr; | 1138 return nullptr; |
1120 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer()); | 1139 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer()); |
1121 return m_archive ? m_archive->mainResource() : nullptr; | 1140 return m_archive ? m_archive->mainResource() : nullptr; |
1122 } | 1141 } |
1123 | 1142 |
1143 // m_mainResourceTimingInfo can be null if it is an iframe navigation restored | |
1144 // from history. | |
1145 ResourceTimingInfo* ResourceFetcher::getMainResourceTimingInfo() { | |
1146 return m_mainResourceTimingInfo.get(); | |
1147 } | |
1148 | |
1124 void ResourceFetcher::didFinishLoading(Resource* resource, | 1149 void ResourceFetcher::didFinishLoading(Resource* resource, |
1125 double finishTime, | 1150 double finishTime, |
1126 DidFinishLoadingReason finishReason) { | 1151 DidFinishLoadingReason finishReason) { |
1127 network_instrumentation::endResourceLoad( | 1152 network_instrumentation::endResourceLoad( |
1128 resource->identifier(), network_instrumentation::RequestOutcome::Success); | 1153 resource->identifier(), network_instrumentation::RequestOutcome::Success); |
1129 DCHECK(resource); | 1154 DCHECK(resource); |
1130 const int64_t encodedDataLength = resource->response().encodedDataLength(); | 1155 const int64_t encodedDataLength = resource->response().encodedDataLength(); |
1131 | 1156 |
1132 // When loading a multipart resource, make the loader non-block when finishing | 1157 // When loading a multipart resource, make the loader non-block when finishing |
1133 // loading the first part. | 1158 // loading the first part. |
1134 if (finishReason == DidFinishFirstPartInMultipart) | 1159 if (finishReason == DidFinishFirstPartInMultipart) |
1135 moveResourceLoaderToNonBlocking(resource->loader()); | 1160 moveResourceLoaderToNonBlocking(resource->loader()); |
1136 else | 1161 else |
1137 removeResourceLoader(resource->loader()); | 1162 removeResourceLoader(resource->loader()); |
1138 DCHECK(!m_loaders.contains(resource->loader())); | 1163 DCHECK(!m_loaders.contains(resource->loader())); |
1139 DCHECK(finishReason == DidFinishFirstPartInMultipart || | 1164 DCHECK(finishReason == DidFinishFirstPartInMultipart || |
1140 !m_nonBlockingLoaders.contains(resource->loader())); | 1165 !m_nonBlockingLoaders.contains(resource->loader())); |
1141 | 1166 |
1167 if (resource->getType() == Resource::MainResource && | |
1168 resource->identifier() == m_mainResourceIdentifier) { | |
1169 DCHECK(m_mainResourceTimingInfo); | |
1170 // Store redirect responses that were packed inside the final response. | |
1171 addRedirectsToTimingInfo(resource, m_mainResourceTimingInfo.get()); | |
1172 m_mainResourceTimingInfo->addFinalTransferSize( | |
1173 encodedDataLength == -1 ? 0 : encodedDataLength); | |
1174 } | |
1142 if (std::unique_ptr<ResourceTimingInfo> info = | 1175 if (std::unique_ptr<ResourceTimingInfo> info = |
1143 m_resourceTimingInfoMap.take(resource)) { | 1176 m_resourceTimingInfoMap.take(resource)) { |
1144 // Store redirect responses that were packed inside the final response. | 1177 // Store redirect responses that were packed inside the final response. |
1145 const Vector<ResourceResponse>& responses = | 1178 addRedirectsToTimingInfo(resource, info.get()); |
1146 resource->response().redirectResponses(); | |
1147 for (size_t i = 0; i < responses.size(); ++i) { | |
1148 const KURL& newURL = i + 1 < responses.size() | |
1149 ? KURL(responses[i + 1].url()) | |
1150 : resource->resourceRequest().url(); | |
1151 bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL); | |
1152 info->addRedirect(responses[i], crossOrigin); | |
1153 } | |
1154 | 1179 |
1155 if (resource->response().isHTTP() && | 1180 if (resource->response().isHTTP() && |
1156 resource->response().httpStatusCode() < 400) { | 1181 resource->response().httpStatusCode() < 400) { |
1157 populateResourceTiming(info.get(), resource); | 1182 populateResourceTiming(info.get(), resource); |
1158 info->setLoadFinishTime(finishTime); | 1183 info->setLoadFinishTime(finishTime); |
1159 // encodedDataLength == -1 means "not available". | 1184 // encodedDataLength == -1 means "not available". |
1160 // TODO(ricea): Find cases where it is not available but the | 1185 // TODO(ricea): Find cases where it is not available but the |
1161 // PerformanceResourceTiming spec requires it to be available and fix | 1186 // PerformanceResourceTiming spec requires it to be available and fix |
1162 // them. | 1187 // them. |
1163 info->addFinalTransferSize(encodedDataLength == -1 ? 0 | 1188 info->addFinalTransferSize(encodedDataLength == -1 ? 0 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1303 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); | 1328 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); |
1304 if (sourceOrigin && sourceOrigin->hasSuborigin()) | 1329 if (sourceOrigin && sourceOrigin->hasSuborigin()) |
1305 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); | 1330 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); |
1306 | 1331 |
1307 ResourceLoader* loader = ResourceLoader::create(this, resource); | 1332 ResourceLoader* loader = ResourceLoader::create(this, resource); |
1308 if (resource->shouldBlockLoadEvent()) | 1333 if (resource->shouldBlockLoadEvent()) |
1309 m_loaders.add(loader); | 1334 m_loaders.add(loader); |
1310 else | 1335 else |
1311 m_nonBlockingLoaders.add(loader); | 1336 m_nonBlockingLoaders.add(loader); |
1312 | 1337 |
1313 storeResourceTimingInitiatorInformation(resource); | 1338 storePerformanceTimingInitiatorInformation(resource); |
1314 resource->setFetcherSecurityOrigin(sourceOrigin); | 1339 resource->setFetcherSecurityOrigin(sourceOrigin); |
1315 | 1340 |
1316 loader->activateCacheAwareLoadingIfNeeded(request); | 1341 loader->activateCacheAwareLoadingIfNeeded(request); |
1317 loader->start(request, context().loadingTaskRunner(), | 1342 loader->start(request, context().loadingTaskRunner(), |
1318 context().defersLoading()); | 1343 context().defersLoading()); |
1319 return true; | 1344 return true; |
1320 } | 1345 } |
1321 | 1346 |
1322 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) { | 1347 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) { |
1323 DCHECK(loader); | 1348 DCHECK(loader); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1393 if (resource->getType() == Resource::Image && | 1418 if (resource->getType() == Resource::Image && |
1394 shouldDeferImageLoad(newRequest.url())) | 1419 shouldDeferImageLoad(newRequest.url())) |
1395 return false; | 1420 return false; |
1396 } | 1421 } |
1397 | 1422 |
1398 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); | 1423 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); |
1399 if (it != m_resourceTimingInfoMap.end()) { | 1424 if (it != m_resourceTimingInfoMap.end()) { |
1400 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); | 1425 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); |
1401 it->value->addRedirect(redirectResponse, crossOrigin); | 1426 it->value->addRedirect(redirectResponse, crossOrigin); |
1402 } | 1427 } |
1428 | |
1429 if (resource->getType() == Resource::MainResource && | |
1430 resource->identifier() == m_mainResourceIdentifier) { | |
1431 DCHECK(m_mainResourceTimingInfo); | |
1432 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); | |
1433 m_mainResourceTimingInfo->addRedirect(redirectResponse, crossOrigin); | |
1434 } | |
1435 | |
1403 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == | 1436 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == |
1404 AllowStoredCredentials); | 1437 AllowStoredCredentials); |
1405 willSendRequest(resource->identifier(), newRequest, redirectResponse, | 1438 willSendRequest(resource->identifier(), newRequest, redirectResponse, |
1406 resource->options()); | 1439 resource->options()); |
1407 return true; | 1440 return true; |
1408 } | 1441 } |
1409 | 1442 |
1410 void ResourceFetcher::willSendRequest(unsigned long identifier, | 1443 void ResourceFetcher::willSendRequest(unsigned long identifier, |
1411 ResourceRequest& newRequest, | 1444 ResourceRequest& newRequest, |
1412 const ResourceResponse& redirectResponse, | 1445 const ResourceResponse& redirectResponse, |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1638 visitor->trace(m_context); | 1671 visitor->trace(m_context); |
1639 visitor->trace(m_archive); | 1672 visitor->trace(m_archive); |
1640 visitor->trace(m_loaders); | 1673 visitor->trace(m_loaders); |
1641 visitor->trace(m_nonBlockingLoaders); | 1674 visitor->trace(m_nonBlockingLoaders); |
1642 visitor->trace(m_documentResources); | 1675 visitor->trace(m_documentResources); |
1643 visitor->trace(m_preloads); | 1676 visitor->trace(m_preloads); |
1644 visitor->trace(m_resourceTimingInfoMap); | 1677 visitor->trace(m_resourceTimingInfoMap); |
1645 } | 1678 } |
1646 | 1679 |
1647 } // namespace blink | 1680 } // namespace blink |
OLD | NEW |