Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
| 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
| 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
| 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All | 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 addRedirectsToResourceTimingInfo(Resource* resource, | |
| 107 ResourceTimingInfo* info) { | |
| 108 // Store redirect responses that were packed inside the final response. | |
| 109 const Vector<ResourceResponse>& responses = | |
| 110 resource->response().redirectResponses(); | |
| 111 for (size_t i = 0; i < responses.size(); ++i) { | |
| 112 const KURL& newURL = i + 1 < responses.size() | |
| 113 ? KURL(responses[i + 1].url()) | |
| 114 : resource->resourceRequest().url(); | |
| 115 bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL); | |
| 116 info->addRedirect(responses[i], crossOrigin); | |
| 117 } | |
| 118 } | |
| 119 | |
| 106 } // namespace | 120 } // namespace |
| 107 | 121 |
| 108 static void RecordSriResourceIntegrityMismatchEvent( | 122 static void RecordSriResourceIntegrityMismatchEvent( |
| 109 SriResourceIntegrityMismatchEvent event) { | 123 SriResourceIntegrityMismatchEvent event) { |
| 110 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 124 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
| 111 EnumerationHistogram, integrityHistogram, | 125 EnumerationHistogram, integrityHistogram, |
| 112 new EnumerationHistogram("sri.resource_integrity_mismatch_event", | 126 new EnumerationHistogram("sri.resource_integrity_mismatch_event", |
| 113 SriResourceIntegrityMismatchEventCount)); | 127 SriResourceIntegrityMismatchEventCount)); |
| 114 integrityHistogram.count(event); | 128 integrityHistogram.count(event); |
| 115 } | 129 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 NOTREACHED(); | 250 NOTREACHED(); |
| 237 return WebURLRequest::RequestContextSubresource; | 251 return WebURLRequest::RequestContextSubresource; |
| 238 } | 252 } |
| 239 | 253 |
| 240 ResourceFetcher::ResourceFetcher(FetchContext* newContext) | 254 ResourceFetcher::ResourceFetcher(FetchContext* newContext) |
| 241 : m_context(newContext), | 255 : m_context(newContext), |
| 242 m_archive(context().isMainFrame() ? nullptr : context().archive()), | 256 m_archive(context().isMainFrame() ? nullptr : context().archive()), |
| 243 m_resourceTimingReportTimer( | 257 m_resourceTimingReportTimer( |
| 244 this, | 258 this, |
| 245 &ResourceFetcher::resourceTimingReportTimerFired), | 259 &ResourceFetcher::resourceTimingReportTimerFired), |
| 260 m_mainResourceIdentifier(0), | |
|
Yoav Weiss
2016/12/02 07:42:49
This assumes a resource's identifier is never 0. S
sunjian
2016/12/03 00:16:50
So getMainResourceTimingInfo() doesn't take any id
| |
| 246 m_autoLoadImages(true), | 261 m_autoLoadImages(true), |
| 247 m_imagesEnabled(true), | 262 m_imagesEnabled(true), |
| 248 m_allowStaleResources(false), | 263 m_allowStaleResources(false), |
| 249 m_imageFetched(false) { | 264 m_imageFetched(false) { |
| 250 ThreadState::current()->registerPreFinalizer(this); | 265 ThreadState::current()->registerPreFinalizer(this); |
| 251 } | 266 } |
| 252 | 267 |
| 253 ResourceFetcher::~ResourceFetcher() {} | 268 ResourceFetcher::~ResourceFetcher() {} |
| 254 | 269 |
| 255 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const { | 270 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const { |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 | 760 |
| 746 // - Don't add main resource to cache to prevent reuse. | 761 // - Don't add main resource to cache to prevent reuse. |
| 747 // - 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. |
| 748 if (factory.type() != Resource::MainResource && | 763 if (factory.type() != Resource::MainResource && |
| 749 request.options().dataBufferingPolicy != DoNotBufferData) { | 764 request.options().dataBufferingPolicy != DoNotBufferData) { |
| 750 memoryCache()->add(resource); | 765 memoryCache()->add(resource); |
| 751 } | 766 } |
| 752 return resource; | 767 return resource; |
| 753 } | 768 } |
| 754 | 769 |
| 755 void ResourceFetcher::storeResourceTimingInitiatorInformation( | 770 void ResourceFetcher::storePerformanceTimingInitiatorInformation( |
| 756 Resource* resource) { | 771 Resource* resource) { |
| 757 const AtomicString& fetchInitiator = resource->options().initiatorInfo.name; | 772 const AtomicString& fetchInitiator = resource->options().initiatorInfo.name; |
| 758 if (fetchInitiator == FetchInitiatorTypeNames::internal) | 773 if (fetchInitiator == FetchInitiatorTypeNames::internal) |
| 759 return; | 774 return; |
| 760 | 775 |
| 761 bool isMainResource = resource->getType() == Resource::MainResource; | 776 bool isMainResource = resource->getType() == Resource::MainResource; |
| 762 | 777 |
| 763 // The request can already be fetched in a previous navigation. Thus | 778 // The request can already be fetched in a previous navigation. Thus |
| 764 // startTime must be set accordingly. | 779 // startTime must be set accordingly. |
| 765 double startTime = resource->resourceRequest().navigationStartTime() | 780 double startTime = resource->resourceRequest().navigationStartTime() |
| 766 ? resource->resourceRequest().navigationStartTime() | 781 ? resource->resourceRequest().navigationStartTime() |
| 767 : monotonicallyIncreasingTime(); | 782 : monotonicallyIncreasingTime(); |
| 768 | 783 |
| 769 std::unique_ptr<ResourceTimingInfo> info = | 784 std::unique_ptr<ResourceTimingInfo> info = |
| 770 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource); | 785 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource); |
| 771 | 786 |
| 772 if (resource->isCacheValidator()) { | 787 if (resource->isCacheValidator()) { |
| 773 const AtomicString& timingAllowOrigin = | 788 const AtomicString& timingAllowOrigin = |
| 774 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin); | 789 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin); |
| 775 if (!timingAllowOrigin.isEmpty()) | 790 if (!timingAllowOrigin.isEmpty()) |
| 776 info->setOriginalTimingAllowOrigin(timingAllowOrigin); | 791 info->setOriginalTimingAllowOrigin(timingAllowOrigin); |
| 777 } | 792 } |
| 778 | 793 |
| 779 if (!isMainResource || | 794 if (!isMainResource || |
| 780 context().updateTimingInfoForIFrameNavigation(info.get())) | 795 context().updateTimingInfoForIFrameNavigation(info.get())) { |
| 781 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(); | |
| 801 } | |
| 782 } | 802 } |
| 783 | 803 |
| 784 ResourceFetcher::RevalidationPolicy | 804 ResourceFetcher::RevalidationPolicy |
| 785 ResourceFetcher::determineRevalidationPolicy(Resource::Type type, | 805 ResourceFetcher::determineRevalidationPolicy(Resource::Type type, |
| 786 const FetchRequest& fetchRequest, | 806 const FetchRequest& fetchRequest, |
| 787 Resource* existingResource, | 807 Resource* existingResource, |
| 788 bool isStaticData) const { | 808 bool isStaticData) const { |
| 789 const ResourceRequest& request = fetchRequest.resourceRequest(); | 809 const ResourceRequest& request = fetchRequest.resourceRequest(); |
| 790 | 810 |
| 791 if (!existingResource) | 811 if (!existingResource) |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1113 } | 1133 } |
| 1114 | 1134 |
| 1115 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { | 1135 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { |
| 1116 // Only the top-frame can load MHTML. | 1136 // Only the top-frame can load MHTML. |
| 1117 if (!context().isMainFrame()) | 1137 if (!context().isMainFrame()) |
| 1118 return nullptr; | 1138 return nullptr; |
| 1119 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer()); | 1139 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer()); |
| 1120 return m_archive ? m_archive->mainResource() : nullptr; | 1140 return m_archive ? m_archive->mainResource() : nullptr; |
| 1121 } | 1141 } |
| 1122 | 1142 |
| 1143 ResourceTimingInfo* ResourceFetcher::getMainResourceTimingInfo() { | |
| 1144 DCHECK(m_mainResourceTimingInfo); | |
| 1145 DCHECK(m_mainResourceIdentifier); | |
| 1146 return m_mainResourceTimingInfo.get(); | |
| 1147 } | |
| 1148 | |
| 1123 void ResourceFetcher::didFinishLoading(Resource* resource, | 1149 void ResourceFetcher::didFinishLoading(Resource* resource, |
| 1124 double finishTime, | 1150 double finishTime, |
| 1125 DidFinishLoadingReason finishReason) { | 1151 DidFinishLoadingReason finishReason) { |
| 1126 network_instrumentation::endResourceLoad( | 1152 network_instrumentation::endResourceLoad( |
| 1127 resource->identifier(), network_instrumentation::RequestOutcome::Success); | 1153 resource->identifier(), network_instrumentation::RequestOutcome::Success); |
| 1128 DCHECK(resource); | 1154 DCHECK(resource); |
| 1129 const int64_t encodedDataLength = resource->response().encodedDataLength(); | 1155 const int64_t encodedDataLength = resource->response().encodedDataLength(); |
| 1130 | 1156 |
| 1131 // 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 |
| 1132 // loading the first part. | 1158 // loading the first part. |
| 1133 if (finishReason == DidFinishFirstPartInMultipart) | 1159 if (finishReason == DidFinishFirstPartInMultipart) |
| 1134 moveResourceLoaderToNonBlocking(resource->loader()); | 1160 moveResourceLoaderToNonBlocking(resource->loader()); |
| 1135 else | 1161 else |
| 1136 removeResourceLoader(resource->loader()); | 1162 removeResourceLoader(resource->loader()); |
| 1137 DCHECK(!m_loaders.contains(resource->loader())); | 1163 DCHECK(!m_loaders.contains(resource->loader())); |
| 1138 DCHECK(finishReason == DidFinishFirstPartInMultipart || | 1164 DCHECK(finishReason == DidFinishFirstPartInMultipart || |
| 1139 !m_nonBlockingLoaders.contains(resource->loader())); | 1165 !m_nonBlockingLoaders.contains(resource->loader())); |
| 1140 | 1166 |
| 1167 if (resource->getType() == Resource::MainResource && | |
| 1168 m_mainResourceTimingInfo) { | |
| 1169 DCHECK_EQ(resource->identifier(), m_mainResourceIdentifier); | |
| 1170 // Store redirect responses that were packed inside the final response. | |
| 1171 addRedirectsToResourceTimingInfo(resource, m_mainResourceTimingInfo.get()); | |
| 1172 m_mainResourceTimingInfo->addFinalTransferSize( | |
| 1173 encodedDataLength == -1 ? 0 : encodedDataLength); | |
| 1174 } | |
| 1141 if (std::unique_ptr<ResourceTimingInfo> info = | 1175 if (std::unique_ptr<ResourceTimingInfo> info = |
| 1142 m_resourceTimingInfoMap.take(resource)) { | 1176 m_resourceTimingInfoMap.take(resource)) { |
| 1143 // Store redirect responses that were packed inside the final response. | 1177 // Store redirect responses that were packed inside the final response. |
| 1144 const Vector<ResourceResponse>& responses = | 1178 addRedirectsToResourceTimingInfo(resource, info.get()); |
| 1145 resource->response().redirectResponses(); | |
| 1146 for (size_t i = 0; i < responses.size(); ++i) { | |
| 1147 const KURL& newURL = i + 1 < responses.size() | |
| 1148 ? KURL(responses[i + 1].url()) | |
| 1149 : resource->resourceRequest().url(); | |
| 1150 bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL); | |
| 1151 info->addRedirect(responses[i], crossOrigin); | |
| 1152 } | |
| 1153 | 1179 |
| 1154 if (resource->response().isHTTP() && | 1180 if (resource->response().isHTTP() && |
| 1155 resource->response().httpStatusCode() < 400) { | 1181 resource->response().httpStatusCode() < 400) { |
| 1156 populateResourceTiming(info.get(), resource); | 1182 populateResourceTiming(info.get(), resource); |
| 1157 info->setLoadFinishTime(finishTime); | 1183 info->setLoadFinishTime(finishTime); |
| 1158 // encodedDataLength == -1 means "not available". | 1184 // encodedDataLength == -1 means "not available". |
| 1159 // TODO(ricea): Find cases where it is not available but the | 1185 // TODO(ricea): Find cases where it is not available but the |
| 1160 // PerformanceResourceTiming spec requires it to be available and fix | 1186 // PerformanceResourceTiming spec requires it to be available and fix |
| 1161 // them. | 1187 // them. |
| 1162 info->addFinalTransferSize(encodedDataLength == -1 ? 0 | 1188 info->addFinalTransferSize(encodedDataLength == -1 ? 0 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1307 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); | 1333 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); |
| 1308 if (sourceOrigin && sourceOrigin->hasSuborigin()) | 1334 if (sourceOrigin && sourceOrigin->hasSuborigin()) |
| 1309 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); | 1335 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); |
| 1310 | 1336 |
| 1311 ResourceLoader* loader = ResourceLoader::create(this, resource); | 1337 ResourceLoader* loader = ResourceLoader::create(this, resource); |
| 1312 if (resource->shouldBlockLoadEvent()) | 1338 if (resource->shouldBlockLoadEvent()) |
| 1313 m_loaders.add(loader); | 1339 m_loaders.add(loader); |
| 1314 else | 1340 else |
| 1315 m_nonBlockingLoaders.add(loader); | 1341 m_nonBlockingLoaders.add(loader); |
| 1316 | 1342 |
| 1317 storeResourceTimingInitiatorInformation(resource); | 1343 storePerformanceTimingInitiatorInformation(resource); |
| 1318 resource->setFetcherSecurityOrigin(sourceOrigin); | 1344 resource->setFetcherSecurityOrigin(sourceOrigin); |
| 1319 | 1345 |
| 1320 loader->activateCacheAwareLoadingIfNeeded(request); | 1346 loader->activateCacheAwareLoadingIfNeeded(request); |
| 1321 loader->start(request, context().loadingTaskRunner(), | 1347 loader->start(request, context().loadingTaskRunner(), |
| 1322 context().defersLoading()); | 1348 context().defersLoading()); |
| 1323 return true; | 1349 return true; |
| 1324 } | 1350 } |
| 1325 | 1351 |
| 1326 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) { | 1352 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) { |
| 1327 if (m_loaders.contains(loader)) | 1353 if (m_loaders.contains(loader)) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1396 if (resource->getType() == Resource::Image && | 1422 if (resource->getType() == Resource::Image && |
| 1397 shouldDeferImageLoad(newRequest.url())) | 1423 shouldDeferImageLoad(newRequest.url())) |
| 1398 return false; | 1424 return false; |
| 1399 } | 1425 } |
| 1400 | 1426 |
| 1401 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); | 1427 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); |
| 1402 if (it != m_resourceTimingInfoMap.end()) { | 1428 if (it != m_resourceTimingInfoMap.end()) { |
| 1403 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); | 1429 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); |
| 1404 it->value->addRedirect(redirectResponse, crossOrigin); | 1430 it->value->addRedirect(redirectResponse, crossOrigin); |
| 1405 } | 1431 } |
| 1432 | |
| 1433 if (resource->getType() == Resource::MainResource && | |
| 1434 m_mainResourceTimingInfo) { | |
| 1435 DCHECK_EQ(resource->identifier(), m_mainResourceIdentifier); | |
| 1436 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); | |
| 1437 m_mainResourceTimingInfo->addRedirect(redirectResponse, crossOrigin); | |
| 1438 } | |
| 1439 | |
| 1406 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == | 1440 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == |
| 1407 AllowStoredCredentials); | 1441 AllowStoredCredentials); |
| 1408 willSendRequest(resource->identifier(), newRequest, redirectResponse, | 1442 willSendRequest(resource->identifier(), newRequest, redirectResponse, |
| 1409 resource->options()); | 1443 resource->options()); |
| 1410 return true; | 1444 return true; |
| 1411 } | 1445 } |
| 1412 | 1446 |
| 1413 void ResourceFetcher::willSendRequest(unsigned long identifier, | 1447 void ResourceFetcher::willSendRequest(unsigned long identifier, |
| 1414 ResourceRequest& newRequest, | 1448 ResourceRequest& newRequest, |
| 1415 const ResourceResponse& redirectResponse, | 1449 const ResourceResponse& redirectResponse, |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1641 visitor->trace(m_context); | 1675 visitor->trace(m_context); |
| 1642 visitor->trace(m_archive); | 1676 visitor->trace(m_archive); |
| 1643 visitor->trace(m_loaders); | 1677 visitor->trace(m_loaders); |
| 1644 visitor->trace(m_nonBlockingLoaders); | 1678 visitor->trace(m_nonBlockingLoaders); |
| 1645 visitor->trace(m_documentResources); | 1679 visitor->trace(m_documentResources); |
| 1646 visitor->trace(m_preloads); | 1680 visitor->trace(m_preloads); |
| 1647 visitor->trace(m_resourceTimingInfoMap); | 1681 visitor->trace(m_resourceTimingInfoMap); |
| 1648 } | 1682 } |
| 1649 | 1683 |
| 1650 } // namespace blink | 1684 } // namespace blink |
| OLD | NEW |