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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |