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

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

Issue 2051243002: Drop ResourceLoader (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@startLoad
Patch Set: Rebase Created 4 years, 3 months 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 5ff0d0d3861a31c60532f733a76016d704734229..74005e60f3f56b11b95c5e97942d217c8d46bdb6 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -32,13 +32,13 @@
#include "core/fetch/FetchInitiatorTypeNames.h"
#include "core/fetch/ImageResource.h"
#include "core/fetch/MemoryCache.h"
-#include "core/fetch/ResourceLoader.h"
#include "core/fetch/ResourceLoadingLog.h"
#include "core/fetch/UniqueIdentifier.h"
#include "platform/Histogram.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "platform/TracedValue.h"
+#include "platform/exported/WrappedResourceRequest.h"
#include "platform/mhtml/ArchiveResource.h"
#include "platform/mhtml/MHTMLArchive.h"
#include "platform/network/ResourceTimingInfo.h"
@@ -49,6 +49,7 @@
#include "public/platform/WebCachePolicy.h"
#include "public/platform/WebURL.h"
#include "public/platform/WebURLRequest.h"
+#include "public/platform/WebURLResponse.h"
#include "wtf/text/CString.h"
#include "wtf/text/WTFString.h"
#include <memory>
@@ -373,12 +374,47 @@ Resource* ResourceFetcher::resourceForStaticData(const FetchRequest& request, co
return resource;
}
+void ResourceFetcher::requestSynchronously(WebURLLoader* loader, Resource* resource, const ResourceRequest& request)
+{
+ // downloadToFile is not supported for synchronous requests.
+ DCHECK(!request.downloadToFile());
+ DCHECK(request.priority() == ResourceLoadPriorityHighest);
+
+ if (context().defersLoading()) {
+ resource->error(ResourceError::cancelledError(resource->url()));
+ return;
+ }
+
+ WebURLResponse responseOut;
+ WebURLError errorOut;
+ WebData dataOut;
+ int64_t encodedDataLength = WebURLLoaderClient::kUnknownEncodedDataLength;
+ loader->loadSynchronously(WrappedResourceRequest(request), responseOut, errorOut, dataOut, encodedDataLength);
+
+ if (errorOut.reason) {
+ didFail(loader, errorOut);
+ return;
+ }
+ didReceiveResponse(loader, responseOut, nullptr);
+ if (resource->isLoaded())
+ return;
+ DCHECK_GE(responseOut.toResourceResponse().encodedBodyLength(), 0);
+ if (dataOut.size()) {
+ Resource* resource = resourceForLoader(loader);
+ context().dispatchDidReceiveData(resource->identifier(), dataOut.data(), dataOut.size(), encodedDataLength);
+ resource->setResourceBuffer(dataOut);
+ }
+ didFinishLoading(loader, monotonicallyIncreasingTime(), encodedDataLength);
+}
+
void ResourceFetcher::moveCachedNonBlockingResourceToBlocking(Resource* resource, const FetchRequest& request)
{
// TODO(yoav): Test that non-blocking resources (video/audio/track) continue to not-block even after being preloaded and discovered.
- if (resource && resource->loader() && resource->isLoadEventBlockingResourceType() && resource->isLinkPreload() && !request.forPreload()) {
- m_nonBlockingLoaders.remove(resource->loader());
- m_loaders.add(resource->loader());
+ if (!resource || !resource->isLoadEventBlockingResourceType() || !resource->isLinkPreload() || request.forPreload())
+ return;
+ if (WebURLLoader* loader = m_resourcesInProgress.get(resource)) {
+ m_nonBlockingLoaders.remove(loader);
+ m_loaders.add(loader, resource);
}
}
@@ -497,8 +533,11 @@ Resource* ResourceFetcher::requestResource(FetchRequest& request, const Resource
// isn't at the same priority as the in-flight request, only allow promotions.
// This can happen when a visible image's priority is increased and then another
// reference to the image is parsed (which would be at a lower priority).
- if (request.resourceRequest().priority() > resource->resourceRequest().priority())
+ if (request.resourceRequest().priority() > resource->resourceRequest().priority()) {
resource->didChangePriority(request.resourceRequest().priority(), 0);
+ if (WebURLLoader* loader = m_resourcesInProgress.get(resource))
+ loader->didChangePriority(static_cast<WebURLRequest::Priority>(request.resourceRequest().priority()), 0);
+ }
}
// If only the fragment identifiers differ, it is the same resource.
@@ -915,20 +954,29 @@ ArchiveResource* ResourceFetcher::createArchive(Resource* resource)
return m_archive ? m_archive->mainResource() : nullptr;
}
-void ResourceFetcher::didFinishLoading(Resource* resource, double finishTime, int64_t encodedDataLength, DidFinishLoadingReason finishReason)
+void ResourceFetcher::didFinishLoadingFirstPartInMultipart(Resource* resource)
{
- TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier());
- DCHECK(resource);
-
+ DCHECK(m_resourcesInProgress.contains(resource));
+ WebURLLoader* loader = m_resourcesInProgress.get(resource);
// 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()));
+ m_loaders.remove(loader);
+ m_nonBlockingLoaders.add(loader, resource);
+ didFinishLoading(resource, 0, WebURLLoaderClient::kUnknownEncodedDataLength);
+}
+void ResourceFetcher::didFinishLoading(WebURLLoader* loader, double finishTime, int64_t encodedDataLength)
+{
+ Resource* resource = resourceForLoader(loader);
+ DCHECK(resource);
+ removeLoader(loader, resource);
+ DCHECK(!m_resourcesInProgress.contains(resource));
+ didFinishLoading(resource, finishTime, encodedDataLength);
+}
+
+void ResourceFetcher::didFinishLoading(Resource* resource, double finishTime, int64_t encodedDataLength)
+{
+ TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier());
if (std::unique_ptr<ResourceTimingInfo> info = m_resourceTimingInfoMap.take(resource)) {
if (resource->response().isHTTP() && resource->response().httpStatusCode() < 400) {
populateResourceTiming(info.get(), resource);
@@ -944,15 +992,24 @@ void ResourceFetcher::didFinishLoading(Resource* resource, double finishTime, in
}
}
context().dispatchDidFinishLoading(resource->identifier(), finishTime, encodedDataLength);
- if (finishReason == DidFinishLoading)
+ // If this is just the completion of the first part of a multipart response,
+ // don't mark the resource as finished yet.
+ if (!m_resourcesInProgress.contains(resource))
resource->finish(finishTime);
context().didLoadResource(resource);
}
-void ResourceFetcher::didFailLoading(Resource* resource, const ResourceError& error)
+void ResourceFetcher::cancelResourceLoad(Resource* resource)
{
+ DCHECK(m_resourcesInProgress.contains(resource));
+ didFail(m_resourcesInProgress.get(resource), ResourceError::cancelledError(resource->lastResourceRequest().url()));
+}
+
+void ResourceFetcher::didFail(WebURLLoader* loader, const WebURLError& error)
+{
+ Resource* resource = resourceForLoader(loader);
TRACE_EVENT_ASYNC_END0("blink.net", "Resource", resource->identifier());
- removeResourceLoader(resource->loader());
+ removeLoader(loader, resource);
m_resourceTimingInfoMap.take(const_cast<Resource*>(resource));
bool isInternalRequest = resource->options().initiatorInfo.name == FetchInitiatorTypeNames::internal;
context().dispatchDidFail(resource->identifier(), error, isInternalRequest);
@@ -960,10 +1017,29 @@ void ResourceFetcher::didFailLoading(Resource* resource, const ResourceError& er
context().didLoadResource(resource);
}
-void ResourceFetcher::didReceiveResponse(Resource* resource, const ResourceResponse& response, WebDataConsumerHandle* rawHandle)
+void ResourceFetcher::didSendData(WebURLLoader* loader, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+{
+ resourceForLoader(loader)->didSendData(bytesSent, totalBytesToBeSent);
+}
+
+void ResourceFetcher::didReceiveCachedMetadata(WebURLLoader* loader, const char* data, int length)
+{
+ resourceForLoader(loader)->setSerializedCachedMetadata(data, length);
+}
+
+void ResourceFetcher::didReceiveResponse(WebURLLoader* loader, const WebURLResponse& response)
{
+ didReceiveResponse(loader, response, nullptr);
+}
+
+void ResourceFetcher::didReceiveResponse(WebURLLoader* loader, const WebURLResponse& webURLResponse, WebDataConsumerHandle* rawHandle)
+{
+ DCHECK(!webURLResponse.isNull());
+
// |rawHandle|'s ownership is transferred to the callee.
std::unique_ptr<WebDataConsumerHandle> handle = wrapUnique(rawHandle);
+ Resource* resource = resourceForLoader(loader);
+ const ResourceResponse& response = webURLResponse.toResourceResponse();
if (response.wasFetchedViaServiceWorker()) {
if (resource->options().corsEnabled == IsCORSEnabled && response.wasFallbackRequiredByServiceWorker()) {
@@ -977,48 +1053,46 @@ void ResourceFetcher::didReceiveResponse(Resource* resource, const ResourceRespo
// wasFallbackRequiredByServiceWorker flag is never set when foreign fetch
// handled a request.
request.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::Controlling);
- resource->loader()->restartForServiceWorkerFallback(request);
+ removeLoader(loader, resource);
+ startRequestForResource(resource, request);
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
+ resource->initializeServiceWorkerCachedMetadataHandler(context().getSecurityOrigin());
const KURL& originalURL = response.originalURLViaServiceWorker();
if (!originalURL.isEmpty() && !context().allowResponse(resource->getType(), resource->resourceRequest(), originalURL, resource->options())) {
- resource->loader()->didFail(nullptr, ResourceError::cancelledDueToAccessCheckError(originalURL));
+ didFail(loader, ResourceError::cancelledDueToAccessCheckError(originalURL));
return;
}
} else if (resource->options().corsEnabled == IsCORSEnabled && !canAccessResponse(resource, response)) {
- resource->loader()->didFail(nullptr, ResourceError::cancelledDueToAccessCheckError(response.url()));
+ didFail(loader, 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(nullptr, ResourceError::cancelledError(response.url()));
+ if (response.httpStatusCode() >= 400 && !resource->shouldIgnoreHTTPStatusCodeErrors())
+ didFail(loader, ResourceError::cancelledError(response.url()));
}
-void ResourceFetcher::didReceiveData(const Resource* resource, const char* data, int dataLength, int encodedDataLength)
+void ResourceFetcher::didReceiveData(WebURLLoader* loader, const char* data, int dataLength, int encodedDataLength, int encodedBodyLength)
{
+ RELEASE_ASSERT(dataLength >= 0);
+ Resource* resource = resourceForLoader(loader);
context().dispatchDidReceiveData(resource->identifier(), data, dataLength, encodedDataLength);
+ resource->addToEncodedBodyLength(encodedBodyLength);
+ resource->addToDecodedBodyLength(dataLength);
+ resource->appendData(data, dataLength);
}
-void ResourceFetcher::didDownloadData(const Resource* resource, int dataLength, int encodedDataLength)
+void ResourceFetcher::didDownloadData(WebURLLoader* loader, int dataLength, int encodedDataLength)
{
+ Resource* resource = resourceForLoader(loader);
context().dispatchDidDownloadData(resource->identifier(), dataLength, encodedDataLength);
-}
-
-void ResourceFetcher::acceptDataFromThreadedReceiver(unsigned long identifier, const char* data, int dataLength, int encodedDataLength)
-{
- context().dispatchDidReceiveData(identifier, data, dataLength, encodedDataLength);
-}
-
-void ResourceFetcher::moveResourceLoaderToNonBlocking(ResourceLoader* loader)
-{
- m_nonBlockingLoaders.add(loader);
- m_loaders.remove(loader);
+ resource->didDownloadData(dataLength);
}
bool ResourceFetcher::startLoad(Resource* resource)
@@ -1032,39 +1106,55 @@ bool ResourceFetcher::startLoad(Resource* resource)
ResourceRequest request(resource->resourceRequest());
willSendRequest(resource->identifier(), request, ResourceResponse(), resource->options());
- ResourceLoader* loader = ResourceLoader::create(this, resource);
+ storeResourceTimingInitiatorInformation(resource);
+ resource->setFetcher(this);
+ startRequestForResource(resource, request);
+ return true;
+}
+
+void ResourceFetcher::startRequestForResource(Resource* resource, const ResourceRequest& request)
+{
+ DCHECK(!m_resourcesInProgress.contains(resource));
+ m_resourcesInProgress.add(resource, wrapUnique(Platform::current()->createURLLoader()));
+ WebURLLoader* loader = m_resourcesInProgress.get(resource);
if (resource->shouldBlockLoadEvent())
- m_loaders.add(loader);
+ m_loaders.add(loader, resource);
else
- m_nonBlockingLoaders.add(loader);
+ m_nonBlockingLoaders.add(loader, resource);
- storeResourceTimingInitiatorInformation(resource);
- resource->setFetcherSecurityOrigin(context().getSecurityOrigin());
- loader->start(request, context().loadingTaskRunner(), context().defersLoading());
- return true;
+ loader->setDefersLoading(context().defersLoading());
+ loader->setLoadingTaskRunner(context().loadingTaskRunner());
+ if (resource->options().synchronousPolicy == RequestSynchronously)
+ requestSynchronously(loader, resource, request);
+ else
+ loader->loadAsynchronously(WrappedResourceRequest(request), this);
}
-void ResourceFetcher::removeResourceLoader(ResourceLoader* loader)
+void ResourceFetcher::removeLoader(WebURLLoader* loader, Resource* resource)
{
+ DCHECK(m_resourcesInProgress.contains(resource));
+ DCHECK(m_resourcesInProgress.get(resource) == loader);
+ DCHECK(m_loaders.get(loader) == resource || m_nonBlockingLoaders.get(loader) == resource);
if (m_loaders.contains(loader))
m_loaders.remove(loader);
else if (m_nonBlockingLoaders.contains(loader))
m_nonBlockingLoaders.remove(loader);
else
- ASSERT_NOT_REACHED();
+ NOTREACHED();
+ m_resourcesInProgress.remove(resource);
}
void ResourceFetcher::stopFetching()
{
- HeapVector<Member<ResourceLoader>> loadersToCancel;
+ Vector<WebURLLoader*> loadersToCancel;
for (const auto& loader : m_nonBlockingLoaders)
- loadersToCancel.append(loader);
+ loadersToCancel.append(loader.key);
for (const auto& loader : m_loaders)
- loadersToCancel.append(loader);
+ loadersToCancel.append(loader.key);
for (const auto& loader : loadersToCancel) {
if (m_loaders.contains(loader) || m_nonBlockingLoaders.contains(loader))
- loader->cancel();
+ didFail(loader, ResourceError::cancelledError(resourceForLoader(loader)->url()));
}
}
@@ -1076,9 +1166,9 @@ bool ResourceFetcher::isFetching() const
void ResourceFetcher::setDefersLoading(bool defers)
{
for (const auto& loader : m_nonBlockingLoaders)
- loader->setDefersLoading(defers);
+ loader.key->setDefersLoading(defers);
for (const auto& loader : m_loaders)
- loader->setDefersLoading(defers);
+ loader.key->setDefersLoading(defers);
}
bool ResourceFetcher::defersLoading() const
@@ -1086,12 +1176,29 @@ bool ResourceFetcher::defersLoading() const
return context().defersLoading();
}
+void ResourceFetcher::setDefersLoadingForResource(Resource* resource, bool defers)
+{
+ DCHECK(resource);
+ DCHECK(m_resourcesInProgress.contains(resource));
+ m_resourcesInProgress.get(resource)->setDefersLoading(defers);
+}
+
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, int64_t encodedDataLength)
+Resource* ResourceFetcher::resourceForLoader(WebURLLoader* loader)
+{
+ if (m_loaders.contains(loader))
+ return m_loaders.get(loader);
+ if (m_nonBlockingLoaders.contains(loader))
+ return m_nonBlockingLoaders.get(loader);
+ NOTREACHED();
+ return nullptr;
+}
+
+bool ResourceFetcher::canFollowRedirect(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))
@@ -1112,6 +1219,24 @@ bool ResourceFetcher::willFollowRedirect(Resource* resource, ResourceRequest& ne
if (resource->getType() == Resource::Image && shouldDeferImageLoad(newRequest.url()))
return false;
}
+ return true;
+}
+
+void ResourceFetcher::willFollowRedirect(WebURLLoader* loader, WebURLRequest& passedNewRequest, const WebURLResponse& passedRedirectResponse, int64_t encodedDataLength)
+{
+ DCHECK(!passedNewRequest.isNull());
+ DCHECK(!passedRedirectResponse.isNull());
+ ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest());
+ const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceResponse());
+ newRequest.setRedirectStatus(ResourceRequest::RedirectStatus::FollowedRedirect);
+
+ Resource* resource = resourceForLoader(loader);
+ if (!canFollowRedirect(resource, newRequest, redirectResponse)) {
+ resource->willNotFollowRedirect();
+ if (m_resourcesInProgress.contains(resource))
+ didFail(loader, ResourceError::cancelledDueToAccessCheckError(newRequest.url()));
+ return;
+ }
ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
if (it != m_resourceTimingInfoMap.end()) {
@@ -1122,7 +1247,7 @@ bool ResourceFetcher::willFollowRedirect(Resource* resource, ResourceRequest& ne
}
newRequest.setAllowStoredCredentials(resource->options().allowCredentials == AllowStoredCredentials);
willSendRequest(resource->identifier(), newRequest, redirectResponse, resource->options());
- return true;
+ resource->willFollowRedirect(newRequest, redirectResponse);
}
void ResourceFetcher::willSendRequest(unsigned long identifier, ResourceRequest& newRequest, const ResourceResponse& redirectResponse, const ResourceLoaderOptions& options)
@@ -1133,9 +1258,9 @@ void ResourceFetcher::willSendRequest(unsigned long identifier, ResourceRequest&
void ResourceFetcher::updateAllImageResourcePriorities()
{
TRACE_EVENT0("blink", "ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities");
- for (const auto& documentResource : m_documentResources) {
- Resource* resource = documentResource.value.get();
- if (!resource || !resource->isImage() || !resource->isLoading())
+ for (const auto& resourceInProgress : m_resourcesInProgress) {
+ Resource* resource = resourceInProgress.key.get();
+ if (!resource || !resource->isImage())
continue;
ResourcePriority resourcePriority = resource->priorityFromObservers();
@@ -1144,6 +1269,7 @@ void ResourceFetcher::updateAllImageResourcePriorities()
continue;
resource->didChangePriority(resourceLoadPriority, resourcePriority.intraPriorityValue);
+ resourceInProgress.value->didChangePriority(static_cast<WebURLRequest::Priority>(resourceLoadPriority), resourcePriority.intraPriorityValue);
TRACE_EVENT_ASYNC_STEP_INTO1("blink.net", "Resource", resource->identifier(), "ChangePriority", "priority", resourceLoadPriority);
context().dispatchDidChangeResourcePriority(resource->identifier(), resourceLoadPriority, resourcePriority.intraPriorityValue);
}
@@ -1324,6 +1450,7 @@ DEFINE_TRACE(ResourceFetcher)
visitor->trace(m_archive);
visitor->trace(m_loaders);
visitor->trace(m_nonBlockingLoaders);
+ visitor->trace(m_resourcesInProgress);
visitor->trace(m_documentResources);
visitor->trace(m_preloads);
visitor->trace(m_resourceTimingInfoMap);
« no previous file with comments | « third_party/WebKit/Source/core/fetch/ResourceFetcher.h ('k') | third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698