blob: 97e3f1d9e18803b5377ff2c2f3405db7c4339f96 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/loader/loader_factory_for_frame.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url_loader_factory.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/frame_or_imported_document.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
LoaderFactoryForFrame::LoaderFactoryForFrame(
const FrameOrImportedDocument& frame_or_imported_document)
: frame_or_imported_document_(frame_or_imported_document) {}
void LoaderFactoryForFrame::Trace(Visitor* visitor) {
visitor->Trace(frame_or_imported_document_);
LoaderFactory::Trace(visitor);
}
std::unique_ptr<WebURLLoader> LoaderFactoryForFrame::CreateURLLoader(
const ResourceRequest& request,
const ResourceLoaderOptions& options,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
WrappedResourceRequest webreq(request);
network::mojom::blink::URLLoaderFactoryPtr url_loader_factory;
if (options.url_loader_factory) {
options.url_loader_factory->data->Clone(MakeRequest(&url_loader_factory));
}
// Resolve any blob: URLs that haven't been resolved yet. The XHR and
// fetch() API implementations resolve blob URLs earlier because there can
// be arbitrarily long delays between creating requests with those APIs and
// actually creating the URL loader here. Other subresource loading will
// immediately create the URL loader so resolving those blob URLs here is
// simplest.
// Don't resolve the URL again if this is a shared worker request though, as
// in that case the browser process will have already done so and the code
// here should just go through the normal non-blob specific code path (note
// that this is only strictly true if NetworkService/S13nSW is enabled, but
// if that isn't the case we're going to run into race conditions resolving
// the blob URL anyway so it doesn't matter if the blob URL gets resolved
// here or later in the browser process, so skipping blob URL resolution
// here for all shared worker loads is okay even with NetworkService/S13nSW
// disabled).
// TODO(mek): Move the RequestContext check to the worker side's relevant
// callsite when we make Shared Worker loading off-main-thread.
Document* document = frame_or_imported_document_->GetDocument();
if (document && request.Url().ProtocolIs("blob") &&
BlobUtils::MojoBlobURLsEnabled() && !url_loader_factory &&
request.GetRequestContext() != mojom::RequestContextType::SHARED_WORKER) {
document->GetPublicURLManager().Resolve(request.Url(),
MakeRequest(&url_loader_factory));
}
LocalFrame& frame = frame_or_imported_document_->GetFrame();
FrameScheduler* frame_scheduler = frame.GetFrameScheduler();
DCHECK(frame_scheduler);
// TODO(altimin): frame_scheduler->CreateResourceLoadingTaskRunnerHandle is
// used when creating a URLLoader, and ResourceFetcher::GetTaskRunner is
// used whenever asynchronous tasks around resource loading are posted. Modify
// the code so that all the tasks related to loading a resource use the
// resource loader handle's task runner.
if (url_loader_factory) {
return Platform::Current()
->WrapURLLoaderFactory(url_loader_factory.PassInterface().PassHandle())
->CreateURLLoader(
webreq, frame_scheduler->CreateResourceLoadingTaskRunnerHandle());
}
DocumentLoader& document_loader =
frame_or_imported_document_->GetMasterDocumentLoader();
if (document_loader.GetServiceWorkerNetworkProvider()) {
auto loader =
document_loader.GetServiceWorkerNetworkProvider()->CreateURLLoader(
webreq, frame_scheduler->CreateResourceLoadingTaskRunnerHandle());
if (loader)
return loader;
}
return frame.GetURLLoaderFactory()->CreateURLLoader(
webreq, frame_scheduler->CreateResourceLoadingTaskRunnerHandle());
}
std::unique_ptr<CodeCacheLoader>
LoaderFactoryForFrame::CreateCodeCacheLoader() {
return Platform::Current()->CreateCodeCacheLoader();
}
} // namespace blink