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

Unified Diff: third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp

Issue 2533683002: Move the code in ResourceFetcher handling calls from WebURLLoaderImpl to ResourceLoader (Closed)
Patch Set: Fixed a bug in resource timing population 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 side-by-side diff with in-line comments
Download patch
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 1c9fd3a59b1b6274383c87e2b2060006e5405300..a29c986bccb19e01af362d1b34276fa7258eb357 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -28,7 +28,6 @@
#include "core/fetch/ResourceFetcher.h"
#include "bindings/core/v8/V8DOMActivityLogger.h"
-#include "core/fetch/CrossOriginAccessControl.h"
#include "core/fetch/FetchContext.h"
#include "core/fetch/FetchInitiatorTypeNames.h"
#include "core/fetch/ImageResource.h"
@@ -97,12 +96,6 @@ enum SriResourceIntegrityMismatchEvent {
DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, XSLStyleSheet) \
}
-bool IsCrossOrigin(const KURL& a, const KURL& b) {
- RefPtr<SecurityOrigin> originA = SecurityOrigin::create(a);
- RefPtr<SecurityOrigin> originB = SecurityOrigin::create(b);
- return !originB->isSameSchemeHostPort(originA.get());
-}
-
} // namespace
static void RecordSriResourceIntegrityMismatchEvent(
@@ -198,6 +191,21 @@ static void populateResourceTiming(ResourceTimingInfo* info,
info->setFinalResponse(resource->response());
}
+static void populateRedirectResourceTimingOnFinish(ResourceTimingInfo* info,
yhirano 2016/12/12 06:32:04 [optional] I prefer placing this function to the u
tyoshino (SeeGerritForStatus) 2016/12/12 11:10:55 Done.
+ Resource* resource) {
+ // Store redirect responses that were packed inside the final response.
+ const Vector<ResourceResponse>& redirectResponses =
+ resource->response().redirectResponses();
+ for (size_t i = 0; i < redirectResponses.size(); ++i) {
+ const KURL& newURL = i + 1 < redirectResponses.size()
+ ? KURL(redirectResponses[i + 1].url())
+ : resource->resourceRequest().url();
+ bool crossOrigin =
+ !SecurityOrigin::areSameOrigin(redirectResponses[i].url(), newURL);
+ info->addRedirect(redirectResponses[i], crossOrigin);
+ }
+}
+
static WebURLRequest::RequestContext requestContextFromType(
bool isMainFrame,
Resource::Type type) {
@@ -258,48 +266,6 @@ Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const {
return resource.get();
}
-bool ResourceFetcher::canAccessResponse(
- Resource* resource,
- const ResourceResponse& response) const {
- // Redirects can change the response URL different from one of request.
- bool forPreload = resource->isUnusedPreload();
- if (!context().canRequest(resource->getType(), resource->resourceRequest(),
- response.url(), resource->options(), forPreload,
- FetchRequest::UseDefaultOriginRestrictionForType))
- return false;
-
- SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get();
- if (!sourceOrigin)
- sourceOrigin = context().getSecurityOrigin();
-
- if (sourceOrigin->canRequestNoSuborigin(response.url()))
- return true;
-
- // Use the original response instead of the 304 response for a successful
- // revaldiation.
- const ResourceResponse& responseForAccessControl =
- (resource->isCacheValidator() && response.httpStatusCode() == 304)
- ? resource->response()
- : response;
- String errorDescription;
- if (!passesAccessControlCheck(
- responseForAccessControl, resource->options().allowCredentials,
- sourceOrigin, errorDescription,
- resource->lastResourceRequest().requestContext())) {
- resource->setCORSFailed();
- if (!forPreload) {
- String resourceType = Resource::resourceTypeToString(
- resource->getType(), resource->options().initiatorInfo);
- context().addConsoleMessage(
- "Access to " + resourceType + " at '" + response.url().getString() +
- "' from origin '" + sourceOrigin->toString() +
- "' has been blocked by CORS policy: " + errorDescription);
- }
- return false;
- }
- return true;
-}
-
bool ResourceFetcher::isControlledByServiceWorker() const {
return context().isControlledByServiceWorker();
}
@@ -781,6 +747,16 @@ void ResourceFetcher::storeResourceTimingInitiatorInformation(
m_resourceTimingInfoMap.add(resource, std::move(info));
}
+void ResourceFetcher::recordResourceTimingOnRedirect(
+ Resource* resource,
+ const ResourceResponse& redirectResponse,
+ bool crossOrigin) {
+ ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
+ if (it != m_resourceTimingInfoMap.end()) {
+ it->value->addRedirect(redirectResponse, crossOrigin);
+ }
+}
+
ResourceFetcher::RevalidationPolicy
ResourceFetcher::determineRevalidationPolicy(Resource::Type type,
const FetchRequest& fetchRequest,
@@ -1120,36 +1096,36 @@ ArchiveResource* ResourceFetcher::createArchive(Resource* resource) {
return m_archive ? m_archive->mainResource() : nullptr;
}
-void ResourceFetcher::didFinishLoading(Resource* resource,
- double finishTime,
- DidFinishLoadingReason finishReason) {
- network_instrumentation::endResourceLoad(
- resource->identifier(), network_instrumentation::RequestOutcome::Success);
+void ResourceFetcher::handleLoadCompletion(Resource* resource) {
+ context().didLoadResource(resource);
+
+ if (resource->isImage() &&
+ toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
+ toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
+ }
+}
+
+void ResourceFetcher::handleLoaderFinish(Resource* resource,
+ double finishTime,
+ LoaderFinishType type) {
DCHECK(resource);
- const int64_t encodedDataLength = resource->response().encodedDataLength();
- // When loading a multipart resource, make the loader non-block when finishing
- // loading the first part.
- if (finishReason == DidFinishFirstPartInMultipart)
- moveResourceLoaderToNonBlocking(resource->loader());
- else
- removeResourceLoader(resource->loader());
- DCHECK(!m_loaders.contains(resource->loader()));
- DCHECK(finishReason == DidFinishFirstPartInMultipart ||
- !m_nonBlockingLoaders.contains(resource->loader()));
+ ResourceLoader* loader = resource->loader();
+ if (type == DidFinishFirstPartInMultipart) {
+ // When loading a multipart resource, make the loader non-block when
+ // finishing loading the first part.
+ moveResourceLoaderToNonBlocking(loader);
+ } else {
+ removeResourceLoader(loader);
+ DCHECK(!m_nonBlockingLoaders.contains(loader));
+ }
+ DCHECK(!m_loaders.contains(loader));
+
+ const int64_t encodedDataLength = resource->response().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);
- }
+ populateRedirectResourceTimingOnFinish(info.get(), resource);
if (resource->response().isHTTP() &&
resource->response().httpStatusCode() < 400) {
@@ -1161,122 +1137,37 @@ void ResourceFetcher::didFinishLoading(Resource* resource,
// them.
info->addFinalTransferSize(encodedDataLength == -1 ? 0
: encodedDataLength);
+
if (resource->options().requestInitiatorContext == DocumentContext)
context().addResourceTiming(*info);
resource->reportResourceTimingToClients(*info);
}
}
+
context().dispatchDidFinishLoading(resource->identifier(), finishTime,
encodedDataLength);
- if (finishReason == DidFinishLoading)
+
+ if (type == DidFinishLoading)
resource->finish(finishTime);
- context().didLoadResource(resource);
- if (resource->isImage() &&
- toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
- toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
- }
+ handleLoadCompletion(resource);
}
-void ResourceFetcher::didFailLoading(Resource* resource,
- const ResourceError& error) {
- network_instrumentation::endResourceLoad(
- resource->identifier(), network_instrumentation::RequestOutcome::Fail);
+void ResourceFetcher::handleLoaderError(Resource* resource,
+ const ResourceError& error) {
+ DCHECK(resource);
+
removeResourceLoader(resource->loader());
- m_resourceTimingInfoMap.take(const_cast<Resource*>(resource));
+
+ m_resourceTimingInfoMap.take(resource);
+
bool isInternalRequest = resource->options().initiatorInfo.name ==
FetchInitiatorTypeNames::internal;
context().dispatchDidFail(resource->identifier(), error, isInternalRequest);
- resource->error(error);
- context().didLoadResource(resource);
-
- if (resource->isImage() &&
- toImageResource(resource)->shouldReloadBrokenPlaceholder()) {
- toImageResource(resource)->reloadIfLoFiOrPlaceholder(this);
- }
-}
-
-void ResourceFetcher::didReceiveResponse(
- Resource* resource,
- const ResourceResponse& response,
- std::unique_ptr<WebDataConsumerHandle> handle) {
- if (response.wasFetchedViaServiceWorker()) {
- if (resource->options().corsEnabled == IsCORSEnabled &&
- response.wasFallbackRequiredByServiceWorker()) {
- ResourceRequest request = resource->lastResourceRequest();
- DCHECK_EQ(request.skipServiceWorker(),
- WebURLRequest::SkipServiceWorker::None);
- // This code handles the case when a regular controlling service worker
- // doesn't handle a cross origin request. When this happens we still want
- // to give foreign fetch a chance to handle the request, so only skip the
- // controlling service worker for the fallback request. This is currently
- // safe because of http://crbug.com/604084 the
- // wasFallbackRequiredByServiceWorker flag is never set when foreign fetch
- // handled a request.
- if (!context().shouldLoadNewResource(resource->getType())) {
- // Cancel the request if we should not trigger a reload now.
- resource->loader()->didFail(
- ResourceError::cancelledError(response.url()));
- return;
- }
- request.setSkipServiceWorker(
- WebURLRequest::SkipServiceWorker::Controlling);
- resource->loader()->restart(request, context().loadingTaskRunner(),
- context().defersLoading());
- return;
- }
-
- // If the response is fetched via ServiceWorker, the original URL of the
- // response could be different from the URL of the request. We check the URL
- // not to load the resources which are forbidden by the page CSP.
- // https://w3c.github.io/webappsec-csp/#should-block-response
- const KURL& originalURL = response.originalURLViaServiceWorker();
- if (!originalURL.isEmpty() &&
- !context().allowResponse(resource->getType(),
- resource->resourceRequest(), originalURL,
- resource->options())) {
- resource->loader()->didFail(
- ResourceError::cancelledDueToAccessCheckError(originalURL));
- return;
- }
- } else if (resource->options().corsEnabled == IsCORSEnabled &&
- !canAccessResponse(resource, response)) {
- resource->loader()->didFail(
- ResourceError::cancelledDueToAccessCheckError(response.url()));
- return;
- }
-
- context().dispatchDidReceiveResponse(
- resource->identifier(), response, resource->resourceRequest().frameType(),
- resource->resourceRequest().requestContext(), resource);
- resource->responseReceived(response, std::move(handle));
- if (resource->loader() && response.httpStatusCode() >= 400 &&
- !resource->shouldIgnoreHTTPStatusCodeErrors()) {
- resource->loader()->didFail(ResourceError::cancelledError(response.url()));
- }
-}
-
-void ResourceFetcher::didReceiveData(const Resource* resource,
- const char* data,
- int dataLength,
- int encodedDataLength) {
- context().dispatchDidReceiveData(resource->identifier(), data, dataLength,
- encodedDataLength);
-}
-void ResourceFetcher::didDownloadData(const Resource* resource,
- int dataLength,
- int encodedDataLength) {
- context().dispatchDidDownloadData(resource->identifier(), dataLength,
- encodedDataLength);
-}
+ resource->error(error);
-void ResourceFetcher::acceptDataFromThreadedReceiver(unsigned long identifier,
- const char* data,
- int dataLength,
- int encodedDataLength) {
- context().dispatchDidReceiveData(identifier, data, dataLength,
- encodedDataLength);
+ handleLoadCompletion(resource);
}
void ResourceFetcher::moveResourceLoaderToNonBlocking(ResourceLoader* loader) {
@@ -1293,11 +1184,13 @@ bool ResourceFetcher::startLoad(Resource* resource) {
}
ResourceRequest request(resource->resourceRequest());
- willSendRequest(resource->identifier(), request, ResourceResponse(),
- resource->options());
+ context().dispatchWillSendRequest(resource->identifier(), request,
+ ResourceResponse(),
+ resource->options().initiatorInfo);
// TODO(shaochuan): Saving modified ResourceRequest back to |resource|, remove
- // once willSendRequest() takes const ResourceRequest. crbug.com/632580
+ // once dispatchWillSendRequest() takes const ResourceRequest.
+ // crbug.com/632580
resource->setResourceRequest(request);
// Resource requests from suborigins should not be intercepted by the service
@@ -1318,8 +1211,7 @@ bool ResourceFetcher::startLoad(Resource* resource) {
resource->setFetcherSecurityOrigin(sourceOrigin);
loader->activateCacheAwareLoadingIfNeeded(request);
- loader->start(request, context().loadingTaskRunner(),
- context().defersLoading());
+ loader->start(request);
return true;
}
@@ -1356,68 +1248,6 @@ void ResourceFetcher::setDefersLoading(bool defers) {
loader->setDefersLoading(defers);
}
-bool ResourceFetcher::defersLoading() const {
- return context().defersLoading();
-}
-
-static bool isManualRedirectFetchRequest(const ResourceRequest& request) {
- return request.fetchRedirectMode() ==
- WebURLRequest::FetchRedirectModeManual &&
- request.requestContext() == WebURLRequest::RequestContextFetch;
-}
-
-bool ResourceFetcher::willFollowRedirect(
- Resource* resource,
- ResourceRequest& newRequest,
- const ResourceResponse& redirectResponse) {
- if (!isManualRedirectFetchRequest(resource->resourceRequest())) {
- if (!context().canRequest(resource->getType(), newRequest, newRequest.url(),
- resource->options(), resource->isUnusedPreload(),
- FetchRequest::UseDefaultOriginRestrictionForType))
- return false;
- if (resource->options().corsEnabled == IsCORSEnabled) {
- RefPtr<SecurityOrigin> sourceOrigin = resource->options().securityOrigin;
- if (!sourceOrigin.get())
- sourceOrigin = context().getSecurityOrigin();
-
- String errorMessage;
- StoredCredentials withCredentials =
- resource->lastResourceRequest().allowStoredCredentials()
- ? AllowStoredCredentials
- : DoNotAllowStoredCredentials;
- if (!CrossOriginAccessControl::handleRedirect(
- sourceOrigin, newRequest, redirectResponse, withCredentials,
- resource->mutableOptions(), errorMessage)) {
- resource->setCORSFailed();
- context().addConsoleMessage(errorMessage);
- return false;
- }
- }
- if (resource->getType() == Resource::Image &&
- shouldDeferImageLoad(newRequest.url()))
- return false;
- }
-
- ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
- if (it != m_resourceTimingInfoMap.end()) {
- bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
- it->value->addRedirect(redirectResponse, crossOrigin);
- }
- newRequest.setAllowStoredCredentials(resource->options().allowCredentials ==
- AllowStoredCredentials);
- willSendRequest(resource->identifier(), newRequest, redirectResponse,
- resource->options());
- return true;
-}
-
-void ResourceFetcher::willSendRequest(unsigned long identifier,
- ResourceRequest& newRequest,
- const ResourceResponse& redirectResponse,
- const ResourceLoaderOptions& options) {
- context().dispatchWillSendRequest(identifier, newRequest, redirectResponse,
- options.initiatorInfo);
-}
-
void ResourceFetcher::updateAllImageResourcePriorities() {
TRACE_EVENT0(
"blink",

Powered by Google App Engine
This is Rietveld 408576698