Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp

Issue 2511313002: transferSize implementation (Closed)
Patch Set: report iframes' navigation timing info Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 resource = createResourceForLoading(request, request.charset(), factory); 599 resource = createResourceForLoading(request, request.charset(), factory);
587 break; 600 break;
588 case Revalidate: 601 case Revalidate:
589 initializeRevalidation(request.mutableResourceRequest(), resource); 602 initializeRevalidation(request.mutableResourceRequest(), resource);
590 break; 603 break;
591 case Use: 604 case Use:
592 if (resource->isLinkPreload() && !request.isLinkPreload()) 605 if (resource->isLinkPreload() && !request.isLinkPreload())
593 resource->setLinkPreload(false); 606 resource->setLinkPreload(false);
594 break; 607 break;
595 } 608 }
596
597 if (!resource) 609 if (!resource)
598 return nullptr; 610 return nullptr;
599 if (resource->getType() != factory.type()) { 611 if (resource->getType() != factory.type()) {
600 DCHECK(request.forPreload()); 612 DCHECK(request.forPreload());
601 return nullptr; 613 return nullptr;
602 } 614 }
603 615
604 if (!resource->isAlive()) 616 if (!resource->isAlive())
605 m_deadStatsRecorder.update(policy); 617 m_deadStatsRecorder.update(policy);
606 618
(...skipping 23 matching lines...) Expand all
630 642
631 // Returns with an existing resource if the resource does not need to start 643 // Returns with an existing resource if the resource does not need to start
632 // loading immediately. If revalidation policy was determined as |Revalidate|, 644 // loading immediately. If revalidation policy was determined as |Revalidate|,
633 // the resource was already initialized for the revalidation here, but won't 645 // the resource was already initialized for the revalidation here, but won't
634 // start loading. 646 // start loading.
635 if (!resourceNeedsLoad(resource, request, policy)) 647 if (!resourceNeedsLoad(resource, request, policy))
636 return resource; 648 return resource;
637 649
638 if (!startLoad(resource)) 650 if (!startLoad(resource))
639 return nullptr; 651 return nullptr;
640
641 scopedResourceLoadTracker.resourceLoadContinuesBeyondScope(); 652 scopedResourceLoadTracker.resourceLoadContinuesBeyondScope();
642 653
643 DCHECK(!resource->errorOccurred() || 654 DCHECK(!resource->errorOccurred() ||
644 request.options().synchronousPolicy == RequestSynchronously); 655 request.options().synchronousPolicy == RequestSynchronously);
645 return resource; 656 return resource;
646 } 657 }
647 658
648 void ResourceFetcher::resourceTimingReportTimerFired(TimerBase* timer) { 659 void ResourceFetcher::resourceTimingReportTimerFired(TimerBase* timer) {
649 DCHECK_EQ(timer, &m_resourceTimingReportTimer); 660 DCHECK_EQ(timer, &m_resourceTimingReportTimer);
650 Vector<std::unique_ptr<ResourceTimingInfo>> timingReports; 661 Vector<std::unique_ptr<ResourceTimingInfo>> timingReports;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 757
747 // - Don't add main resource to cache to prevent reuse. 758 // - Don't add main resource to cache to prevent reuse.
748 // - Don't add the resource if its body will not be stored. 759 // - Don't add the resource if its body will not be stored.
749 if (factory.type() != Resource::MainResource && 760 if (factory.type() != Resource::MainResource &&
750 request.options().dataBufferingPolicy != DoNotBufferData) { 761 request.options().dataBufferingPolicy != DoNotBufferData) {
751 memoryCache()->add(resource); 762 memoryCache()->add(resource);
752 } 763 }
753 return resource; 764 return resource;
754 } 765 }
755 766
756 void ResourceFetcher::storeResourceTimingInitiatorInformation( 767 void ResourceFetcher::storePerformanceTimingInitiatorInformation(
757 Resource* resource) { 768 Resource* resource) {
758 const AtomicString& fetchInitiator = resource->options().initiatorInfo.name; 769 const AtomicString& fetchInitiator = resource->options().initiatorInfo.name;
759 if (fetchInitiator == FetchInitiatorTypeNames::internal) 770 if (fetchInitiator == FetchInitiatorTypeNames::internal)
760 return; 771 return;
761 772
762 bool isMainResource = resource->getType() == Resource::MainResource; 773 bool isMainResource = resource->getType() == Resource::MainResource;
763 774
764 // The request can already be fetched in a previous navigation. Thus 775 // The request can already be fetched in a previous navigation. Thus
765 // startTime must be set accordingly. 776 // startTime must be set accordingly.
766 double startTime = resource->resourceRequest().navigationStartTime() 777 double startTime = resource->resourceRequest().navigationStartTime()
767 ? resource->resourceRequest().navigationStartTime() 778 ? resource->resourceRequest().navigationStartTime()
768 : monotonicallyIncreasingTime(); 779 : monotonicallyIncreasingTime();
769 780
770 std::unique_ptr<ResourceTimingInfo> info = 781 std::unique_ptr<ResourceTimingInfo> info =
771 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource); 782 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource);
772 783
773 if (resource->isCacheValidator()) { 784 if (resource->isCacheValidator()) {
774 const AtomicString& timingAllowOrigin = 785 const AtomicString& timingAllowOrigin =
775 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin); 786 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin);
776 if (!timingAllowOrigin.isEmpty()) 787 if (!timingAllowOrigin.isEmpty())
777 info->setOriginalTimingAllowOrigin(timingAllowOrigin); 788 info->setOriginalTimingAllowOrigin(timingAllowOrigin);
778 } 789 }
779 790
780 if (!isMainResource || 791 if (!isMainResource ||
781 context().updateTimingInfoForIFrameNavigation(info.get())) 792 context().updateTimingInfoForIFrameNavigation(info.get())) {
782 m_resourceTimingInfoMap.add(resource, std::move(info)); 793 m_resourceTimingInfoMap.add(resource, std::move(info));
794 }
795
796 if (isMainResource) {
Yoav Weiss 2016/12/09 00:11:13 Could you add a test for the iframe navTiming case
797 DCHECK(!m_navigationTimingInfo);
798 m_navigationTimingInfo = std::move(info);
799 }
783 } 800 }
784 801
785 ResourceFetcher::RevalidationPolicy 802 ResourceFetcher::RevalidationPolicy
786 ResourceFetcher::determineRevalidationPolicy(Resource::Type type, 803 ResourceFetcher::determineRevalidationPolicy(Resource::Type type,
787 const FetchRequest& fetchRequest, 804 const FetchRequest& fetchRequest,
788 Resource* existingResource, 805 Resource* existingResource,
789 bool isStaticData) const { 806 bool isStaticData) const {
790 const ResourceRequest& request = fetchRequest.resourceRequest(); 807 const ResourceRequest& request = fetchRequest.resourceRequest();
791 808
792 if (!existingResource) 809 if (!existingResource)
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 } 1131 }
1115 1132
1116 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { 1133 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) {
1117 // Only the top-frame can load MHTML. 1134 // Only the top-frame can load MHTML.
1118 if (!context().isMainFrame()) 1135 if (!context().isMainFrame())
1119 return nullptr; 1136 return nullptr;
1120 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer()); 1137 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer());
1121 return m_archive ? m_archive->mainResource() : nullptr; 1138 return m_archive ? m_archive->mainResource() : nullptr;
1122 } 1139 }
1123 1140
1141 // m_navigationTimingInfo can be null if it is an iframe navigation restored
panicker 2016/12/08 20:47:06 remove this comment?
sunjian 2016/12/09 00:50:12 Done.
1142 // from history.
1143 ResourceTimingInfo* ResourceFetcher::getNavigationTimingInfo() {
1144 return m_navigationTimingInfo.get();
1145 }
1146
1124 void ResourceFetcher::didFinishLoading(Resource* resource, 1147 void ResourceFetcher::didFinishLoading(Resource* resource,
1125 double finishTime, 1148 double finishTime,
1126 DidFinishLoadingReason finishReason) { 1149 DidFinishLoadingReason finishReason) {
1127 network_instrumentation::endResourceLoad( 1150 network_instrumentation::endResourceLoad(
1128 resource->identifier(), network_instrumentation::RequestOutcome::Success); 1151 resource->identifier(), network_instrumentation::RequestOutcome::Success);
1129 DCHECK(resource); 1152 DCHECK(resource);
1130 const int64_t encodedDataLength = resource->response().encodedDataLength(); 1153 const int64_t encodedDataLength = resource->response().encodedDataLength();
1131 1154
1132 // When loading a multipart resource, make the loader non-block when finishing 1155 // When loading a multipart resource, make the loader non-block when finishing
1133 // loading the first part. 1156 // loading the first part.
1134 if (finishReason == DidFinishFirstPartInMultipart) 1157 if (finishReason == DidFinishFirstPartInMultipart)
1135 moveResourceLoaderToNonBlocking(resource->loader()); 1158 moveResourceLoaderToNonBlocking(resource->loader());
1136 else 1159 else
1137 removeResourceLoader(resource->loader()); 1160 removeResourceLoader(resource->loader());
1138 DCHECK(!m_loaders.contains(resource->loader())); 1161 DCHECK(!m_loaders.contains(resource->loader()));
1139 DCHECK(finishReason == DidFinishFirstPartInMultipart || 1162 DCHECK(finishReason == DidFinishFirstPartInMultipart ||
1140 !m_nonBlockingLoaders.contains(resource->loader())); 1163 !m_nonBlockingLoaders.contains(resource->loader()));
1141 1164
1165 // When it is non-iframe main resource.
panicker 2016/12/08 20:47:06 remove this comment
sunjian 2016/12/09 00:50:12 Done.
1166 if (resource->getType() == Resource::MainResource && m_navigationTimingInfo) {
1167 // Store redirect responses that were packed inside the final response.
1168 addRedirectsToTimingInfo(resource, m_navigationTimingInfo.get());
1169 m_navigationTimingInfo->addFinalTransferSize(
1170 encodedDataLength == -1 ? 0 : encodedDataLength);
1171 }
1142 if (std::unique_ptr<ResourceTimingInfo> info = 1172 if (std::unique_ptr<ResourceTimingInfo> info =
1143 m_resourceTimingInfoMap.take(resource)) { 1173 m_resourceTimingInfoMap.take(resource)) {
1144 // Store redirect responses that were packed inside the final response. 1174 // Store redirect responses that were packed inside the final response.
1145 const Vector<ResourceResponse>& responses = 1175 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 1176
1155 if (resource->response().isHTTP() && 1177 if (resource->response().isHTTP() &&
1156 resource->response().httpStatusCode() < 400) { 1178 resource->response().httpStatusCode() < 400) {
1157 populateResourceTiming(info.get(), resource); 1179 populateResourceTiming(info.get(), resource);
1158 info->setLoadFinishTime(finishTime); 1180 info->setLoadFinishTime(finishTime);
1159 // encodedDataLength == -1 means "not available". 1181 // encodedDataLength == -1 means "not available".
1160 // TODO(ricea): Find cases where it is not available but the 1182 // TODO(ricea): Find cases where it is not available but the
1161 // PerformanceResourceTiming spec requires it to be available and fix 1183 // PerformanceResourceTiming spec requires it to be available and fix
1162 // them. 1184 // them.
1163 info->addFinalTransferSize(encodedDataLength == -1 ? 0 1185 info->addFinalTransferSize(encodedDataLength == -1 ? 0
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); 1325 SecurityOrigin* sourceOrigin = context().getSecurityOrigin();
1304 if (sourceOrigin && sourceOrigin->hasSuborigin()) 1326 if (sourceOrigin && sourceOrigin->hasSuborigin())
1305 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); 1327 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All);
1306 1328
1307 ResourceLoader* loader = ResourceLoader::create(this, resource); 1329 ResourceLoader* loader = ResourceLoader::create(this, resource);
1308 if (resource->shouldBlockLoadEvent()) 1330 if (resource->shouldBlockLoadEvent())
1309 m_loaders.add(loader); 1331 m_loaders.add(loader);
1310 else 1332 else
1311 m_nonBlockingLoaders.add(loader); 1333 m_nonBlockingLoaders.add(loader);
1312 1334
1313 storeResourceTimingInitiatorInformation(resource); 1335 storePerformanceTimingInitiatorInformation(resource);
1314 resource->setFetcherSecurityOrigin(sourceOrigin); 1336 resource->setFetcherSecurityOrigin(sourceOrigin);
1315 1337
1316 loader->activateCacheAwareLoadingIfNeeded(request); 1338 loader->activateCacheAwareLoadingIfNeeded(request);
1317 loader->start(request, context().loadingTaskRunner(), 1339 loader->start(request, context().loadingTaskRunner(),
1318 context().defersLoading()); 1340 context().defersLoading());
1319 return true; 1341 return true;
1320 } 1342 }
1321 1343
1322 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) { 1344 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) {
1323 DCHECK(loader); 1345 DCHECK(loader);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 if (resource->getType() == Resource::Image && 1415 if (resource->getType() == Resource::Image &&
1394 shouldDeferImageLoad(newRequest.url())) 1416 shouldDeferImageLoad(newRequest.url()))
1395 return false; 1417 return false;
1396 } 1418 }
1397 1419
1398 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); 1420 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
1399 if (it != m_resourceTimingInfoMap.end()) { 1421 if (it != m_resourceTimingInfoMap.end()) {
1400 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); 1422 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
1401 it->value->addRedirect(redirectResponse, crossOrigin); 1423 it->value->addRedirect(redirectResponse, crossOrigin);
1402 } 1424 }
1425
1426 if (resource->getType() == Resource::MainResource && m_navigationTimingInfo) {
1427 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
1428 m_navigationTimingInfo->addRedirect(redirectResponse, crossOrigin);
1429 }
1430
1403 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == 1431 newRequest.setAllowStoredCredentials(resource->options().allowCredentials ==
1404 AllowStoredCredentials); 1432 AllowStoredCredentials);
1405 willSendRequest(resource->identifier(), newRequest, redirectResponse, 1433 willSendRequest(resource->identifier(), newRequest, redirectResponse,
1406 resource->options()); 1434 resource->options());
1407 return true; 1435 return true;
1408 } 1436 }
1409 1437
1410 void ResourceFetcher::willSendRequest(unsigned long identifier, 1438 void ResourceFetcher::willSendRequest(unsigned long identifier,
1411 ResourceRequest& newRequest, 1439 ResourceRequest& newRequest,
1412 const ResourceResponse& redirectResponse, 1440 const ResourceResponse& redirectResponse,
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1638 visitor->trace(m_context); 1666 visitor->trace(m_context);
1639 visitor->trace(m_archive); 1667 visitor->trace(m_archive);
1640 visitor->trace(m_loaders); 1668 visitor->trace(m_loaders);
1641 visitor->trace(m_nonBlockingLoaders); 1669 visitor->trace(m_nonBlockingLoaders);
1642 visitor->trace(m_documentResources); 1670 visitor->trace(m_documentResources);
1643 visitor->trace(m_preloads); 1671 visitor->trace(m_preloads);
1644 visitor->trace(m_resourceTimingInfoMap); 1672 visitor->trace(m_resourceTimingInfoMap);
1645 } 1673 }
1646 1674
1647 } // namespace blink 1675 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698