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 = | |
Yoav Weiss
2016/12/09 00:11:13
Nit: const auto&
sunjian
2016/12/09 00:50:12
Done.
| |
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 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 resource = createResourceForLoading(request, request.charset(), factory); | 603 resource = createResourceForLoading(request, request.charset(), factory); |
591 break; | 604 break; |
592 case Revalidate: | 605 case Revalidate: |
593 initializeRevalidation(request.mutableResourceRequest(), resource); | 606 initializeRevalidation(request.mutableResourceRequest(), resource); |
594 break; | 607 break; |
595 case Use: | 608 case Use: |
596 if (resource->isLinkPreload() && !request.isLinkPreload()) | 609 if (resource->isLinkPreload() && !request.isLinkPreload()) |
597 resource->setLinkPreload(false); | 610 resource->setLinkPreload(false); |
598 break; | 611 break; |
599 } | 612 } |
600 | |
601 if (!resource) | 613 if (!resource) |
602 return nullptr; | 614 return nullptr; |
603 if (resource->getType() != factory.type()) { | 615 if (resource->getType() != factory.type()) { |
604 DCHECK(request.forPreload()); | 616 DCHECK(request.forPreload()); |
605 return nullptr; | 617 return nullptr; |
606 } | 618 } |
607 | 619 |
608 if (!resource->isAlive()) | 620 if (!resource->isAlive()) |
609 m_deadStatsRecorder.update(policy); | 621 m_deadStatsRecorder.update(policy); |
610 | 622 |
(...skipping 23 matching lines...) Expand all Loading... | |
634 | 646 |
635 // Returns with an existing resource if the resource does not need to start | 647 // Returns with an existing resource if the resource does not need to start |
636 // loading immediately. If revalidation policy was determined as |Revalidate|, | 648 // loading immediately. If revalidation policy was determined as |Revalidate|, |
637 // the resource was already initialized for the revalidation here, but won't | 649 // the resource was already initialized for the revalidation here, but won't |
638 // start loading. | 650 // start loading. |
639 if (!resourceNeedsLoad(resource, request, policy)) | 651 if (!resourceNeedsLoad(resource, request, policy)) |
640 return resource; | 652 return resource; |
641 | 653 |
642 if (!startLoad(resource)) | 654 if (!startLoad(resource)) |
643 return nullptr; | 655 return nullptr; |
644 | |
645 scopedResourceLoadTracker.resourceLoadContinuesBeyondScope(); | 656 scopedResourceLoadTracker.resourceLoadContinuesBeyondScope(); |
646 | 657 |
647 DCHECK(!resource->errorOccurred() || | 658 DCHECK(!resource->errorOccurred() || |
648 request.options().synchronousPolicy == RequestSynchronously); | 659 request.options().synchronousPolicy == RequestSynchronously); |
649 return resource; | 660 return resource; |
650 } | 661 } |
651 | 662 |
652 void ResourceFetcher::resourceTimingReportTimerFired(TimerBase* timer) { | 663 void ResourceFetcher::resourceTimingReportTimerFired(TimerBase* timer) { |
653 DCHECK_EQ(timer, &m_resourceTimingReportTimer); | 664 DCHECK_EQ(timer, &m_resourceTimingReportTimer); |
654 Vector<std::unique_ptr<ResourceTimingInfo>> timingReports; | 665 Vector<std::unique_ptr<ResourceTimingInfo>> timingReports; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
750 | 761 |
751 // - Don't add main resource to cache to prevent reuse. | 762 // - Don't add main resource to cache to prevent reuse. |
752 // - Don't add the resource if its body will not be stored. | 763 // - Don't add the resource if its body will not be stored. |
753 if (factory.type() != Resource::MainResource && | 764 if (factory.type() != Resource::MainResource && |
754 request.options().dataBufferingPolicy != DoNotBufferData) { | 765 request.options().dataBufferingPolicy != DoNotBufferData) { |
755 memoryCache()->add(resource); | 766 memoryCache()->add(resource); |
756 } | 767 } |
757 return resource; | 768 return resource; |
758 } | 769 } |
759 | 770 |
760 void ResourceFetcher::storeResourceTimingInitiatorInformation( | 771 void ResourceFetcher::storePerformanceTimingInitiatorInformation( |
761 Resource* resource) { | 772 Resource* resource) { |
762 const AtomicString& fetchInitiator = resource->options().initiatorInfo.name; | 773 const AtomicString& fetchInitiator = resource->options().initiatorInfo.name; |
763 if (fetchInitiator == FetchInitiatorTypeNames::internal) | 774 if (fetchInitiator == FetchInitiatorTypeNames::internal) |
764 return; | 775 return; |
765 | 776 |
766 bool isMainResource = resource->getType() == Resource::MainResource; | 777 bool isMainResource = resource->getType() == Resource::MainResource; |
767 | 778 |
768 // The request can already be fetched in a previous navigation. Thus | 779 // The request can already be fetched in a previous navigation. Thus |
769 // startTime must be set accordingly. | 780 // startTime must be set accordingly. |
770 double startTime = resource->resourceRequest().navigationStartTime() | 781 double startTime = resource->resourceRequest().navigationStartTime() |
771 ? resource->resourceRequest().navigationStartTime() | 782 ? resource->resourceRequest().navigationStartTime() |
772 : monotonicallyIncreasingTime(); | 783 : monotonicallyIncreasingTime(); |
773 | 784 |
785 // This buffer is created and populated for providing transferSize | |
786 // and Redirect timing opt in information. | |
787 if (isMainResource) { | |
788 DCHECK(!m_navigationTimingInfo); | |
789 m_navigationTimingInfo = | |
790 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource); | |
791 } | |
792 | |
774 std::unique_ptr<ResourceTimingInfo> info = | 793 std::unique_ptr<ResourceTimingInfo> info = |
775 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource); | 794 ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource); |
776 | 795 |
777 if (resource->isCacheValidator()) { | 796 if (resource->isCacheValidator()) { |
778 const AtomicString& timingAllowOrigin = | 797 const AtomicString& timingAllowOrigin = |
779 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin); | 798 resource->response().httpHeaderField(HTTPNames::Timing_Allow_Origin); |
780 if (!timingAllowOrigin.isEmpty()) | 799 if (!timingAllowOrigin.isEmpty()) |
781 info->setOriginalTimingAllowOrigin(timingAllowOrigin); | 800 info->setOriginalTimingAllowOrigin(timingAllowOrigin); |
782 } | 801 } |
783 | 802 |
784 if (!isMainResource || | 803 if (!isMainResource || |
785 context().updateTimingInfoForIFrameNavigation(info.get())) | 804 context().updateTimingInfoForIFrameNavigation(info.get())) { |
786 m_resourceTimingInfoMap.add(resource, std::move(info)); | 805 m_resourceTimingInfoMap.add(resource, std::move(info)); |
806 } | |
787 } | 807 } |
788 | 808 |
789 ResourceFetcher::RevalidationPolicy | 809 ResourceFetcher::RevalidationPolicy |
790 ResourceFetcher::determineRevalidationPolicy(Resource::Type type, | 810 ResourceFetcher::determineRevalidationPolicy(Resource::Type type, |
791 const FetchRequest& fetchRequest, | 811 const FetchRequest& fetchRequest, |
792 Resource* existingResource, | 812 Resource* existingResource, |
793 bool isStaticData) const { | 813 bool isStaticData) const { |
794 const ResourceRequest& request = fetchRequest.resourceRequest(); | 814 const ResourceRequest& request = fetchRequest.resourceRequest(); |
795 | 815 |
796 if (!existingResource) | 816 if (!existingResource) |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1118 } | 1138 } |
1119 | 1139 |
1120 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { | 1140 ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { |
1121 // Only the top-frame can load MHTML. | 1141 // Only the top-frame can load MHTML. |
1122 if (!context().isMainFrame()) | 1142 if (!context().isMainFrame()) |
1123 return nullptr; | 1143 return nullptr; |
1124 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer()); | 1144 m_archive = MHTMLArchive::create(resource->url(), resource->resourceBuffer()); |
1125 return m_archive ? m_archive->mainResource() : nullptr; | 1145 return m_archive ? m_archive->mainResource() : nullptr; |
1126 } | 1146 } |
1127 | 1147 |
1148 ResourceTimingInfo* ResourceFetcher::getNavigationTimingInfo() { | |
1149 return m_navigationTimingInfo.get(); | |
1150 } | |
1151 | |
1128 void ResourceFetcher::didFinishLoading(Resource* resource, | 1152 void ResourceFetcher::didFinishLoading(Resource* resource, |
1129 double finishTime, | 1153 double finishTime, |
1130 DidFinishLoadingReason finishReason) { | 1154 DidFinishLoadingReason finishReason) { |
1131 network_instrumentation::endResourceLoad( | 1155 network_instrumentation::endResourceLoad( |
1132 resource->identifier(), network_instrumentation::RequestOutcome::Success); | 1156 resource->identifier(), network_instrumentation::RequestOutcome::Success); |
1133 DCHECK(resource); | 1157 DCHECK(resource); |
1134 const int64_t encodedDataLength = resource->response().encodedDataLength(); | 1158 const int64_t encodedDataLength = resource->response().encodedDataLength(); |
1135 | 1159 |
1136 // When loading a multipart resource, make the loader non-block when finishing | 1160 // When loading a multipart resource, make the loader non-block when finishing |
1137 // loading the first part. | 1161 // loading the first part. |
1138 if (finishReason == DidFinishFirstPartInMultipart) | 1162 if (finishReason == DidFinishFirstPartInMultipart) |
1139 moveResourceLoaderToNonBlocking(resource->loader()); | 1163 moveResourceLoaderToNonBlocking(resource->loader()); |
1140 else | 1164 else |
1141 removeResourceLoader(resource->loader()); | 1165 removeResourceLoader(resource->loader()); |
1142 DCHECK(!m_loaders.contains(resource->loader())); | 1166 DCHECK(!m_loaders.contains(resource->loader())); |
1143 DCHECK(finishReason == DidFinishFirstPartInMultipart || | 1167 DCHECK(finishReason == DidFinishFirstPartInMultipart || |
1144 !m_nonBlockingLoaders.contains(resource->loader())); | 1168 !m_nonBlockingLoaders.contains(resource->loader())); |
1145 | 1169 |
1170 if (resource->getType() == Resource::MainResource) { | |
1171 DCHECK(m_navigationTimingInfo); | |
1172 // Store redirect responses that were packed inside the final response. | |
1173 addRedirectsToTimingInfo(resource, m_navigationTimingInfo.get()); | |
1174 m_navigationTimingInfo->addFinalTransferSize( | |
1175 encodedDataLength == -1 ? 0 : encodedDataLength); | |
1176 } | |
1146 if (std::unique_ptr<ResourceTimingInfo> info = | 1177 if (std::unique_ptr<ResourceTimingInfo> info = |
1147 m_resourceTimingInfoMap.take(resource)) { | 1178 m_resourceTimingInfoMap.take(resource)) { |
1148 // Store redirect responses that were packed inside the final response. | 1179 // Store redirect responses that were packed inside the final response. |
1149 const Vector<ResourceResponse>& responses = | 1180 addRedirectsToTimingInfo(resource, info.get()); |
1150 resource->response().redirectResponses(); | |
1151 for (size_t i = 0; i < responses.size(); ++i) { | |
1152 const KURL& newURL = i + 1 < responses.size() | |
1153 ? KURL(responses[i + 1].url()) | |
1154 : resource->resourceRequest().url(); | |
1155 bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL); | |
1156 info->addRedirect(responses[i], crossOrigin); | |
1157 } | |
1158 | 1181 |
1159 if (resource->response().isHTTP() && | 1182 if (resource->response().isHTTP() && |
1160 resource->response().httpStatusCode() < 400) { | 1183 resource->response().httpStatusCode() < 400) { |
1161 populateResourceTiming(info.get(), resource); | 1184 populateResourceTiming(info.get(), resource); |
1162 info->setLoadFinishTime(finishTime); | 1185 info->setLoadFinishTime(finishTime); |
1163 // encodedDataLength == -1 means "not available". | 1186 // encodedDataLength == -1 means "not available". |
1164 // TODO(ricea): Find cases where it is not available but the | 1187 // TODO(ricea): Find cases where it is not available but the |
1165 // PerformanceResourceTiming spec requires it to be available and fix | 1188 // PerformanceResourceTiming spec requires it to be available and fix |
1166 // them. | 1189 // them. |
1167 info->addFinalTransferSize(encodedDataLength == -1 ? 0 | 1190 info->addFinalTransferSize(encodedDataLength == -1 ? 0 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1316 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); | 1339 SecurityOrigin* sourceOrigin = context().getSecurityOrigin(); |
1317 if (sourceOrigin && sourceOrigin->hasSuborigin()) | 1340 if (sourceOrigin && sourceOrigin->hasSuborigin()) |
1318 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); | 1341 request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); |
1319 | 1342 |
1320 ResourceLoader* loader = ResourceLoader::create(this, resource); | 1343 ResourceLoader* loader = ResourceLoader::create(this, resource); |
1321 if (resource->shouldBlockLoadEvent()) | 1344 if (resource->shouldBlockLoadEvent()) |
1322 m_loaders.add(loader); | 1345 m_loaders.add(loader); |
1323 else | 1346 else |
1324 m_nonBlockingLoaders.add(loader); | 1347 m_nonBlockingLoaders.add(loader); |
1325 | 1348 |
1326 storeResourceTimingInitiatorInformation(resource); | 1349 storePerformanceTimingInitiatorInformation(resource); |
1327 resource->setFetcherSecurityOrigin(sourceOrigin); | 1350 resource->setFetcherSecurityOrigin(sourceOrigin); |
1328 | 1351 |
1329 loader->activateCacheAwareLoadingIfNeeded(request); | 1352 loader->activateCacheAwareLoadingIfNeeded(request); |
1330 loader->start(request, context().loadingTaskRunner(), | 1353 loader->start(request, context().loadingTaskRunner(), |
1331 context().defersLoading()); | 1354 context().defersLoading()); |
1332 return true; | 1355 return true; |
1333 } | 1356 } |
1334 | 1357 |
1335 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) { | 1358 void ResourceFetcher::removeResourceLoader(ResourceLoader* loader) { |
1336 DCHECK(loader); | 1359 DCHECK(loader); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1409 shouldDeferImageLoad(newRequest.url())) { | 1432 shouldDeferImageLoad(newRequest.url())) { |
1410 return ResourceRequestBlockedReason::Other; | 1433 return ResourceRequestBlockedReason::Other; |
1411 } | 1434 } |
1412 } | 1435 } |
1413 | 1436 |
1414 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); | 1437 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); |
1415 if (it != m_resourceTimingInfoMap.end()) { | 1438 if (it != m_resourceTimingInfoMap.end()) { |
1416 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); | 1439 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); |
1417 it->value->addRedirect(redirectResponse, crossOrigin); | 1440 it->value->addRedirect(redirectResponse, crossOrigin); |
1418 } | 1441 } |
1442 | |
1443 if (resource->getType() == Resource::MainResource) { | |
1444 DCHECK(m_navigationTimingInfo); | |
1445 bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); | |
1446 m_navigationTimingInfo->addRedirect(redirectResponse, crossOrigin); | |
1447 } | |
1448 | |
1419 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == | 1449 newRequest.setAllowStoredCredentials(resource->options().allowCredentials == |
1420 AllowStoredCredentials); | 1450 AllowStoredCredentials); |
1421 willSendRequest(resource->identifier(), newRequest, redirectResponse, | 1451 willSendRequest(resource->identifier(), newRequest, redirectResponse, |
1422 resource->options()); | 1452 resource->options()); |
1423 return ResourceRequestBlockedReason::None; | 1453 return ResourceRequestBlockedReason::None; |
1424 } | 1454 } |
1425 | 1455 |
1426 void ResourceFetcher::willSendRequest(unsigned long identifier, | 1456 void ResourceFetcher::willSendRequest(unsigned long identifier, |
1427 ResourceRequest& newRequest, | 1457 ResourceRequest& newRequest, |
1428 const ResourceResponse& redirectResponse, | 1458 const ResourceResponse& redirectResponse, |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1671 visitor->trace(m_context); | 1701 visitor->trace(m_context); |
1672 visitor->trace(m_archive); | 1702 visitor->trace(m_archive); |
1673 visitor->trace(m_loaders); | 1703 visitor->trace(m_loaders); |
1674 visitor->trace(m_nonBlockingLoaders); | 1704 visitor->trace(m_nonBlockingLoaders); |
1675 visitor->trace(m_documentResources); | 1705 visitor->trace(m_documentResources); |
1676 visitor->trace(m_preloads); | 1706 visitor->trace(m_preloads); |
1677 visitor->trace(m_resourceTimingInfoMap); | 1707 visitor->trace(m_resourceTimingInfoMap); |
1678 } | 1708 } |
1679 | 1709 |
1680 } // namespace blink | 1710 } // namespace blink |
OLD | NEW |