Chromium Code Reviews| Index: third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp |
| diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp |
| index cb7b2cccaaab98ed31825e0f51f7e26352b45a12..85fe142a65530693a5aff5f5a39af36480267188 100644 |
| --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp |
| +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp |
| @@ -103,6 +103,19 @@ bool IsCrossOrigin(const KURL& a, const KURL& b) { |
| return !originB->isSameSchemeHostPort(originA.get()); |
| } |
| +void addRedirectsToTimingInfo(Resource* resource, ResourceTimingInfo* info) { |
| + // Store redirect responses that were packed inside the final response. |
| + const Vector<ResourceResponse>& responses = |
| + resource->response().redirectResponses(); |
| + for (size_t i = 0; i < responses.size(); ++i) { |
| + const KURL& newURL = i + 1 < responses.size() |
| + ? KURL(responses[i + 1].url()) |
| + : resource->resourceRequest().url(); |
| + bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL); |
| + info->addRedirect(responses[i], crossOrigin); |
| + } |
| +} |
| + |
| } // namespace |
| static void RecordSriResourceIntegrityMismatchEvent( |
| @@ -243,6 +256,7 @@ ResourceFetcher::ResourceFetcher(FetchContext* newContext) |
| m_resourceTimingReportTimer( |
| this, |
| &ResourceFetcher::resourceTimingReportTimerFired), |
| + m_mainResourceIdentifier(0), |
| m_autoLoadImages(true), |
| m_imagesEnabled(true), |
| m_allowStaleResources(false), |
| @@ -753,7 +767,7 @@ Resource* ResourceFetcher::createResourceForLoading( |
| return resource; |
| } |
| -void ResourceFetcher::storeResourceTimingInitiatorInformation( |
| +void ResourceFetcher::storePerformanceTimingInitiatorInformation( |
| Resource* resource) { |
| const AtomicString& fetchInitiator = resource->options().initiatorInfo.name; |
| if (fetchInitiator == FetchInitiatorTypeNames::internal) |
| @@ -778,8 +792,14 @@ void ResourceFetcher::storeResourceTimingInitiatorInformation( |
| } |
| if (!isMainResource || |
| - context().updateTimingInfoForIFrameNavigation(info.get())) |
| + context().updateTimingInfoForIFrameNavigation(info.get())) { |
| m_resourceTimingInfoMap.add(resource, std::move(info)); |
| + } else { |
| + DCHECK(!m_mainResourceTimingInfo); |
| + m_mainResourceTimingInfo = std::move(info); |
| + m_mainResourceIdentifier = resource->identifier(); |
| + DCHECK(m_mainResourceIdentifier); |
| + } |
| } |
| ResourceFetcher::RevalidationPolicy |
| @@ -1121,6 +1141,12 @@ ArchiveResource* ResourceFetcher::createArchive(Resource* resource) { |
| return m_archive ? m_archive->mainResource() : nullptr; |
| } |
| +// m_mainResourceTimingInfo can be null if it is an iframe navigation restored |
| +// from history. |
| +ResourceTimingInfo* ResourceFetcher::getMainResourceTimingInfo() { |
| + return m_mainResourceTimingInfo.get(); |
| +} |
| + |
| void ResourceFetcher::didFinishLoading(Resource* resource, |
| double finishTime, |
| DidFinishLoadingReason finishReason) { |
| @@ -1139,18 +1165,18 @@ void ResourceFetcher::didFinishLoading(Resource* resource, |
| DCHECK(finishReason == DidFinishFirstPartInMultipart || |
| !m_nonBlockingLoaders.contains(resource->loader())); |
| + if (resource->getType() == Resource::MainResource && |
| + resource->identifier() == m_mainResourceIdentifier) { |
|
Nate Chapin
2016/12/06 20:07:50
I didn't follow your explanation earlier: why isn'
panicker
2016/12/07 00:49:00
We weren't certain of that, therefore the identifi
Yoav Weiss
2016/12/07 01:26:37
An iframe resource loading here would have a MainR
sunjian
2016/12/07 19:09:50
I think you are correct about the fact that each R
|
| + DCHECK(m_mainResourceTimingInfo); |
| + // Store redirect responses that were packed inside the final response. |
| + addRedirectsToTimingInfo(resource, m_mainResourceTimingInfo.get()); |
| + m_mainResourceTimingInfo->addFinalTransferSize( |
| + encodedDataLength == -1 ? 0 : encodedDataLength); |
| + } |
| if (std::unique_ptr<ResourceTimingInfo> info = |
| m_resourceTimingInfoMap.take(resource)) { |
| // Store redirect responses that were packed inside the final response. |
| - const Vector<ResourceResponse>& responses = |
| - resource->response().redirectResponses(); |
| - for (size_t i = 0; i < responses.size(); ++i) { |
| - const KURL& newURL = i + 1 < responses.size() |
| - ? KURL(responses[i + 1].url()) |
| - : resource->resourceRequest().url(); |
| - bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL); |
| - info->addRedirect(responses[i], crossOrigin); |
| - } |
| + addRedirectsToTimingInfo(resource, info.get()); |
| if (resource->response().isHTTP() && |
| resource->response().httpStatusCode() < 400) { |
| @@ -1310,7 +1336,7 @@ bool ResourceFetcher::startLoad(Resource* resource) { |
| else |
| m_nonBlockingLoaders.add(loader); |
| - storeResourceTimingInitiatorInformation(resource); |
| + storePerformanceTimingInitiatorInformation(resource); |
| resource->setFetcherSecurityOrigin(sourceOrigin); |
| loader->activateCacheAwareLoadingIfNeeded(request); |
| @@ -1400,6 +1426,14 @@ bool ResourceFetcher::willFollowRedirect( |
| bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); |
| it->value->addRedirect(redirectResponse, crossOrigin); |
| } |
| + |
| + if (resource->getType() == Resource::MainResource && |
| + resource->identifier() == m_mainResourceIdentifier) { |
| + DCHECK(m_mainResourceTimingInfo); |
| + bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url()); |
| + m_mainResourceTimingInfo->addRedirect(redirectResponse, crossOrigin); |
| + } |
| + |
| newRequest.setAllowStoredCredentials(resource->options().allowCredentials == |
| AllowStoredCredentials); |
| willSendRequest(resource->identifier(), newRequest, redirectResponse, |