Reland: Introduce ResourceDownloader for url downloading with network service
The previous CL: https://chromium-review.googlesource.com/c/chromium/src/+/621772 was reverted,
due to broken test on network service bot.
However, those test shouldn't pass in the first place.
The test passes because they are not using network service.
Instead, they are using the UrlRequest codepath.
This CL is clone of the original CL, but it removed the if statement to create ResourceDownloader
in DownloadManagerImpl. I added a TODO instead.
Will enable the ResourceDownload creation when the new code path fully works,
so network service bot will be happy.
Both the ResourceDownloader and the UrlDownloader now inherits UrlDownloadHandler,
so DownloadManagerImpl/DownloadWorker can reuse most of the current code for both implementations.
The ResourceDownloader returns a data pipe when download starts,
DownloadManagerImpl/DownloadWorker can use the data pipe to initialize DownloadFile.
Bug=715630
Change-Id: Ia4cdfee066e0c8236b941437b58393bdeaaaa5fc
Reviewed-on: https://chromium-review.googlesource.com/631636
Commit-Queue: Min Qin <[email protected]>
Reviewed-by: Bo <[email protected]>
Cr-Commit-Position: refs/heads/master@{#497336}
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 459a1fa5..ab6acae9 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -695,6 +695,8 @@
"download/parallel_download_utils.h",
"download/rate_estimator.cc",
"download/rate_estimator.h",
+ "download/resource_downloader.cc",
+ "download/resource_downloader.h",
"download/save_file.cc",
"download/save_file.h",
"download/save_file_manager.cc",
@@ -709,6 +711,8 @@
"download/save_package_download_job.h",
"download/save_types.cc",
"download/save_types.h",
+ "download/url_download_handler.cc",
+ "download/url_download_handler.h",
"download/url_downloader.cc",
"download/url_downloader.h",
"field_trial_recorder.cc",
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index b87f694..0abd4a0f 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -30,9 +30,13 @@
#include "content/browser/download/download_item_impl.h"
#include "content/browser/download/download_stats.h"
#include "content/browser/download/download_task_runner.h"
+#include "content/browser/download/download_utils.h"
+#include "content/browser/download/resource_downloader.h"
+#include "content/browser/download/url_downloader.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/storage_partition_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
@@ -44,6 +48,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/previews_state.h"
#include "content/public/common/referrer.h"
#include "net/base/elements_upload_data_stream.h"
@@ -63,6 +68,24 @@
namespace content {
namespace {
+scoped_refptr<URLLoaderFactoryGetter> GetURLLoaderFactoryGetter(
+ BrowserContext* context,
+ int render_process_id,
+ int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ SiteInstance* site_instance = nullptr;
+ if (render_process_id >= 0) {
+ RenderFrameHost* render_frame_host_ =
+ RenderFrameHost::FromID(render_process_id, render_frame_id);
+ if (render_frame_host_)
+ site_instance = render_frame_host_->GetSiteInstance();
+ }
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetStoragePartition(context, site_instance));
+ return partition->url_loader_factory_getter();
+}
+
std::unique_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread> BeginDownload(
std::unique_ptr<DownloadUrlParameters> params,
content::ResourceContext* resource_context,
@@ -117,6 +140,23 @@
.release());
}
+std::unique_ptr<ResourceDownloader, BrowserThread::DeleteOnIOThread>
+BeginResourceDownload(
+ std::unique_ptr<DownloadUrlParameters> params,
+ std::unique_ptr<ResourceRequest> request,
+ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
+ uint32_t download_id,
+ base::WeakPtr<DownloadManagerImpl> download_manager) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ return std::unique_ptr<ResourceDownloader, BrowserThread::DeleteOnIOThread>(
+ ResourceDownloader::BeginDownload(download_manager, std::move(params),
+ std::move(request),
+ url_loader_factory_getter, download_id,
+ false)
+ .release());
+}
+
class DownloadItemFactoryImpl : public DownloadItemFactory {
public:
DownloadItemFactoryImpl() {}
@@ -304,7 +344,7 @@
}
downloads_.clear();
downloads_by_guid_.clear();
- url_downloaders_.clear();
+ url_download_handlers_.clear();
// We'll have nothing more to report to the observers after this point.
observers_.Clear();
@@ -502,7 +542,7 @@
base::Bind(&BeginDownload, base::Passed(¶ms),
browser_context_->GetResourceContext(), id,
weak_factory_.GetWeakPtr()),
- base::Bind(&DownloadManagerImpl::AddUrlDownloader,
+ base::Bind(&DownloadManagerImpl::AddUrlDownloadHandler,
weak_factory_.GetWeakPtr()));
}
@@ -528,11 +568,11 @@
downloads_.erase(download->GetId());
}
-void DownloadManagerImpl::AddUrlDownloader(
- std::unique_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>
+void DownloadManagerImpl::AddUrlDownloadHandler(
+ std::unique_ptr<UrlDownloadHandler, BrowserThread::DeleteOnIOThread>
downloader) {
if (downloader)
- url_downloaders_.push_back(std::move(downloader));
+ url_download_handlers_.push_back(std::move(downloader));
}
// static
@@ -625,13 +665,34 @@
DCHECK(params->prefer_cache());
DCHECK_EQ("POST", params->method());
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&BeginDownload, base::Passed(¶ms),
- browser_context_->GetResourceContext(),
- content::DownloadItem::kInvalidId, weak_factory_.GetWeakPtr()),
- base::Bind(&DownloadManagerImpl::AddUrlDownloader,
- weak_factory_.GetWeakPtr()));
+
+ // TODO(qinmin): remove false from the if statement once download works when
+ // network service is enabled, or once we disable the tests that are currently
+ // passing with the URLRequest code path.
+ if (base::FeatureList::IsEnabled(features::kNetworkService) && false) {
+ std::unique_ptr<ResourceRequest> request = CreateResourceRequest(
+ params.get());
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BeginResourceDownload, std::move(params),
+ std::move(request),
+ GetURLLoaderFactoryGetter(
+ browser_context_, params->render_process_host_id(),
+ params->render_frame_host_routing_id()),
+ content::DownloadItem::kInvalidId,
+ weak_factory_.GetWeakPtr()),
+ base::BindOnce(&DownloadManagerImpl::AddUrlDownloadHandler,
+ weak_factory_.GetWeakPtr()));
+ } else {
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BeginDownload, std::move(params),
+ browser_context_->GetResourceContext(),
+ content::DownloadItem::kInvalidId,
+ weak_factory_.GetWeakPtr()),
+ base::BindOnce(&DownloadManagerImpl::AddUrlDownloadHandler,
+ weak_factory_.GetWeakPtr()));
+ }
}
void DownloadManagerImpl::AddObserver(Observer* observer) {
@@ -734,19 +795,21 @@
: nullptr;
}
-void DownloadManagerImpl::OnUrlDownloaderStarted(
+void DownloadManagerImpl::OnUrlDownloadStarted(
std::unique_ptr<DownloadCreateInfo> download_create_info,
- std::unique_ptr<ByteStreamReader> stream_reader,
+ std::unique_ptr<UrlDownloadHandler::InputStream> input_stream,
const DownloadUrlParameters::OnStartedCallback& callback) {
- StartDownload(std::move(download_create_info), std::move(stream_reader),
- callback);
+ if (!base::FeatureList::IsEnabled(features::kNetworkService)) {
+ StartDownload(std::move(download_create_info),
+ std::move(input_stream->stream_reader_), callback);
+ }
}
-void DownloadManagerImpl::OnUrlDownloaderStopped(UrlDownloader* downloader) {
- for (auto ptr = url_downloaders_.begin(); ptr != url_downloaders_.end();
- ++ptr) {
+void DownloadManagerImpl::OnUrlDownloadStopped(UrlDownloadHandler* downloader) {
+ for (auto ptr = url_download_handlers_.begin();
+ ptr != url_download_handlers_.end(); ++ptr) {
if (ptr->get() == downloader) {
- url_downloaders_.erase(ptr);
+ url_download_handlers_.erase(ptr);
return;
}
}
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h
index 67c48e3..6e3b37e8 100644
--- a/content/browser/download/download_manager_impl.h
+++ b/content/browser/download/download_manager_impl.h
@@ -21,7 +21,7 @@
#include "base/sequenced_task_runner_helpers.h"
#include "base/synchronization/lock.h"
#include "content/browser/download/download_item_impl_delegate.h"
-#include "content/browser/download/url_downloader.h"
+#include "content/browser/download/url_download_handler.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
@@ -40,7 +40,7 @@
class ResourceContext;
class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
- public UrlDownloader::Delegate,
+ public UrlDownloadHandler::Delegate,
private DownloadItemImplDelegate {
public:
using DownloadItemImplCreated = base::Callback<void(DownloadItemImpl*)>;
@@ -114,12 +114,12 @@
DownloadItem* GetDownload(uint32_t id) override;
DownloadItem* GetDownloadByGuid(const std::string& guid) override;
- // UrlDownloader::Delegate implementation.
- void OnUrlDownloaderStarted(
+ // UrlDownloadHandler::Delegate implementation.
+ void OnUrlDownloadStarted(
std::unique_ptr<DownloadCreateInfo> download_create_info,
- std::unique_ptr<ByteStreamReader> stream_reader,
+ std::unique_ptr<UrlDownloadHandler::InputStream> input_stream,
const DownloadUrlParameters::OnStartedCallback& callback) override;
- void OnUrlDownloaderStopped(UrlDownloader* downloader) override;
+ void OnUrlDownloadStopped(UrlDownloadHandler* downloader) override;
// For testing; specifically, accessed from TestFileErrorInjector.
void SetDownloadItemFactoryForTesting(
@@ -199,8 +199,8 @@
void ShowDownloadInShell(DownloadItemImpl* download) override;
void DownloadRemoved(DownloadItemImpl* download) override;
- void AddUrlDownloader(
- std::unique_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>
+ void AddUrlDownloadHandler(
+ std::unique_ptr<UrlDownloadHandler, BrowserThread::DeleteOnIOThread>
downloader);
// Factory for creation of downloads items.
@@ -240,8 +240,9 @@
net::NetLog* net_log_;
- std::vector<std::unique_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>>
- url_downloaders_;
+ std::vector<
+ std::unique_ptr<UrlDownloadHandler, BrowserThread::DeleteOnIOThread>>
+ url_download_handlers_;
base::WeakPtrFactory<DownloadManagerImpl> weak_factory_;
diff --git a/content/browser/download/download_response_handler.cc b/content/browser/download/download_response_handler.cc
index 715df6d..ab85646b 100644
--- a/content/browser/download/download_response_handler.cc
+++ b/content/browser/download/download_response_handler.cc
@@ -6,18 +6,18 @@
#include "content/browser/download/download_stats.h"
#include "content/browser/download/download_utils.h"
+#include "content/public/browser/download_url_parameters.h"
namespace content {
-DownloadResponseHandler::DownloadResponseHandler(
- ResourceRequest* resource_request,
- Delegate* delegate,
- bool is_parallel_request)
+DownloadResponseHandler::DownloadResponseHandler(DownloadUrlParameters* params,
+ Delegate* delegate,
+ bool is_parallel_request)
: delegate_(delegate) {
if (!is_parallel_request)
RecordDownloadCount(UNTHROTTLED_COUNT);
- // TODO(qinmin): create the DownloadSaveInfo from |resource_request|
+ // TODO(qinmin): create the DownloadSaveInfo from |params|
}
DownloadResponseHandler::~DownloadResponseHandler() = default;
@@ -34,7 +34,7 @@
? HandleSuccessfulServerResponse(*(head.headers.get()), nullptr)
: DOWNLOAD_INTERRUPT_REASON_NONE;
if (result != DOWNLOAD_INTERRUPT_REASON_NONE) {
- delegate_->OnResponseStarted(download_create_info_,
+ delegate_->OnResponseStarted(base::MakeUnique<DownloadCreateInfo>(),
mojo::ScopedDataPipeConsumerHandle());
}
}
@@ -59,7 +59,8 @@
void DownloadResponseHandler::OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) {
- delegate_->OnResponseStarted(download_create_info_, std::move(body));
+ delegate_->OnResponseStarted(base::MakeUnique<DownloadCreateInfo>(),
+ std::move(body));
}
void DownloadResponseHandler::OnComplete(
diff --git a/content/browser/download/download_response_handler.h b/content/browser/download/download_response_handler.h
index f60158e..d3a658cc 100644
--- a/content/browser/download/download_response_handler.h
+++ b/content/browser/download/download_response_handler.h
@@ -6,11 +6,12 @@
#define CONTENT_BROWSER_DOWNLOAD_RESPONSE_HANDLER_
#include "content/browser/download/download_create_info.h"
-#include "content/public/common/resource_request.h"
#include "content/public/common/url_loader.mojom.h"
namespace content {
+class DownloadUrlParameters;
+
// This class is responsible for handling the server response for a download.
// It passes the DataPipeConsumerHandle and completion status to the download
// sink. The class is common to both navigation triggered downloads and
@@ -20,11 +21,11 @@
class Delegate {
public:
virtual void OnResponseStarted(
- const DownloadCreateInfo& download_create_info,
+ std::unique_ptr<DownloadCreateInfo> download_create_info,
mojo::ScopedDataPipeConsumerHandle body) = 0;
};
- DownloadResponseHandler(ResourceRequest* resource_request,
+ DownloadResponseHandler(DownloadUrlParameters* params,
Delegate* delegate,
bool is_parallel_request);
~DownloadResponseHandler() override;
@@ -49,8 +50,6 @@
private:
Delegate* const delegate_;
- DownloadCreateInfo download_create_info_;
-
DISALLOW_COPY_AND_ASSIGN(DownloadResponseHandler);
};
diff --git a/content/browser/download/download_utils.cc b/content/browser/download/download_utils.cc
index 3e288d8..319a3fa 100644
--- a/content/browser/download/download_utils.cc
+++ b/content/browser/download/download_utils.cc
@@ -6,12 +6,15 @@
#include "base/format_macros.h"
#include "base/memory/ptr_util.h"
+#include "base/process/process_handle.h"
#include "base/strings/stringprintf.h"
#include "content/browser/download/download_interrupt_reasons_impl.h"
#include "content/browser/download/download_stats.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_save_info.h"
#include "content/public/browser/download_url_parameters.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/common/resource_request.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/load_flags.h"
@@ -167,6 +170,23 @@
request->referrer = params->referrer().url;
request->referrer_policy = params->referrer().policy;
request->download_to_file = true;
+ request->allow_download = true;
+
+ if (params->render_process_host_id()) {
+ request->origin_pid = params->render_process_host_id();
+ RenderFrameHost* render_frame_host =
+ RenderFrameHost::FromID(params->render_process_host_id(),
+ params->render_frame_host_routing_id());
+ RenderFrameHost* parent_frame = render_frame_host->GetParent();
+ if (parent_frame) {
+ request->parent_render_frame_id = parent_frame->GetRoutingID();
+ request->parent_is_main_frame = (parent_frame->GetParent() == nullptr);
+ } else {
+ request->is_main_frame = true;
+ }
+
+ request->render_frame_id = params->render_frame_host_routing_id();
+ }
bool has_upload_data = false;
if (!params->post_body().empty()) {
diff --git a/content/browser/download/download_worker.cc b/content/browser/download/download_worker.cc
index 2f564e5..b79f3f6 100644
--- a/content/browser/download/download_worker.cc
+++ b/content/browser/download/download_worker.cc
@@ -30,13 +30,14 @@
int status_;
};
-std::unique_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>
-CreateUrlDownloader(std::unique_ptr<DownloadUrlParameters> params,
- base::WeakPtr<UrlDownloader::Delegate> delegate) {
+std::unique_ptr<UrlDownloadHandler, BrowserThread::DeleteOnIOThread>
+CreateUrlDownloadHandler(std::unique_ptr<DownloadUrlParameters> params,
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Build the URLRequest, BlobDataHandle is hold in original request for image
// download.
+ // TODO(qinmin): Handle the case when network service is enabled.
std::unique_ptr<net::URLRequest> url_request =
DownloadRequestCore::CreateRequestOnIOThread(DownloadItem::kInvalidId,
params.get());
@@ -69,10 +70,10 @@
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::IO, FROM_HERE,
- base::Bind(&CreateUrlDownloader, base::Passed(¶ms),
- weak_factory_.GetWeakPtr()),
- base::Bind(&DownloadWorker::AddUrlDownloader,
- weak_factory_.GetWeakPtr()));
+ base::BindOnce(&CreateUrlDownloadHandler, std::move(params),
+ weak_factory_.GetWeakPtr()),
+ base::BindOnce(&DownloadWorker::AddUrlDownloadHandler,
+ weak_factory_.GetWeakPtr()));
}
void DownloadWorker::Pause() {
@@ -94,9 +95,9 @@
request_handle_->CancelRequest(user_cancel);
}
-void DownloadWorker::OnUrlDownloaderStarted(
+void DownloadWorker::OnUrlDownloadStarted(
std::unique_ptr<DownloadCreateInfo> create_info,
- std::unique_ptr<ByteStreamReader> stream_reader,
+ std::unique_ptr<UrlDownloadHandler::InputStream> input_stream,
const DownloadUrlParameters::OnStartedCallback& callback) {
// |callback| is not used in subsequent requests.
DCHECK(callback.is_null());
@@ -113,7 +114,8 @@
DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE) {
VLOG(kVerboseLevel) << "Parallel download sub-request failed. reason = "
<< create_info->result;
- stream_reader.reset(new CompletedByteStreamReader(create_info->result));
+ input_stream->stream_reader_.reset(
+ new CompletedByteStreamReader(create_info->result));
}
request_handle_ = std::move(create_info->request_handle);
@@ -124,18 +126,19 @@
Pause();
}
- delegate_->OnByteStreamReady(this, std::move(stream_reader));
+ delegate_->OnByteStreamReady(this, std::move(input_stream->stream_reader_));
}
-void DownloadWorker::OnUrlDownloaderStopped(UrlDownloader* downloader) {
- // Release the |url_downloader_|, the object will be deleted on IO thread.
- url_downloader_.reset();
+void DownloadWorker::OnUrlDownloadStopped(UrlDownloadHandler* downloader) {
+ // Release the |url_download_handler_|, the object will be deleted on IO
+ // thread.
+ url_download_handler_.reset();
}
-void DownloadWorker::AddUrlDownloader(
- std::unique_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>
+void DownloadWorker::AddUrlDownloadHandler(
+ std::unique_ptr<UrlDownloadHandler, BrowserThread::DeleteOnIOThread>
downloader) {
- url_downloader_ = std::move(downloader);
+ url_download_handler_ = std::move(downloader);
}
} // namespace content
diff --git a/content/browser/download/download_worker.h b/content/browser/download/download_worker.h
index 4fd3a951..81b49089 100644
--- a/content/browser/download/download_worker.h
+++ b/content/browser/download/download_worker.h
@@ -22,7 +22,7 @@
// file after handling response of the original non-range request.
// TODO(xingliu): we should consider to reuse this class for single connection
// download.
-class CONTENT_EXPORT DownloadWorker : public UrlDownloader::Delegate {
+class CONTENT_EXPORT DownloadWorker : public UrlDownloadHandler::Delegate {
public:
class Delegate {
public:
@@ -52,14 +52,14 @@
private:
// UrlDownloader::Delegate implementation.
- void OnUrlDownloaderStarted(
+ void OnUrlDownloadStarted(
std::unique_ptr<DownloadCreateInfo> create_info,
- std::unique_ptr<ByteStreamReader> stream_reader,
+ std::unique_ptr<UrlDownloadHandler::InputStream> input_stream,
const DownloadUrlParameters::OnStartedCallback& callback) override;
- void OnUrlDownloaderStopped(UrlDownloader* downloader) override;
+ void OnUrlDownloadStopped(UrlDownloadHandler* downloader) override;
- void AddUrlDownloader(
- std::unique_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>
+ void AddUrlDownloadHandler(
+ std::unique_ptr<UrlDownloadHandler, BrowserThread::DeleteOnIOThread>
downloader);
DownloadWorker::Delegate* const delegate_;
@@ -79,8 +79,8 @@
std::unique_ptr<DownloadRequestHandleInterface> request_handle_;
// Used to handle the url request. Live and die on IO thread.
- std::unique_ptr<UrlDownloader, BrowserThread::DeleteOnIOThread>
- url_downloader_;
+ std::unique_ptr<UrlDownloadHandler, BrowserThread::DeleteOnIOThread>
+ url_download_handler_;
base::WeakPtrFactory<DownloadWorker> weak_factory_;
diff --git a/content/browser/download/parallel_download_job_unittest.cc b/content/browser/download/parallel_download_job_unittest.cc
index 223a3a1..bc1d07e4 100644
--- a/content/browser/download/parallel_download_job_unittest.cc
+++ b/content/browser/download/parallel_download_job_unittest.cc
@@ -167,13 +167,15 @@
void MakeWorkerReady(
DownloadWorker* worker,
std::unique_ptr<MockDownloadRequestHandle> request_handle) {
- UrlDownloader::Delegate* delegate =
- static_cast<UrlDownloader::Delegate*>(worker);
+ UrlDownloadHandler::Delegate* delegate =
+ static_cast<UrlDownloadHandler::Delegate*>(worker);
std::unique_ptr<DownloadCreateInfo> create_info =
base::MakeUnique<DownloadCreateInfo>();
create_info->request_handle = std::move(request_handle);
- delegate->OnUrlDownloaderStarted(
- std::move(create_info), std::unique_ptr<ByteStreamReader>(),
+ delegate->OnUrlDownloadStarted(
+ std::move(create_info),
+ base::MakeUnique<UrlDownloadHandler::InputStream>(
+ base::MakeUnique<MockByteStreamReader>()),
DownloadUrlParameters::OnStartedCallback());
}
diff --git a/content/browser/download/resource_downloader.cc b/content/browser/download/resource_downloader.cc
new file mode 100644
index 0000000..bef3f56
--- /dev/null
+++ b/content/browser/download/resource_downloader.cc
@@ -0,0 +1,73 @@
+// Copyright 2017 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 "content/browser/download/resource_downloader.h"
+
+#include "content/browser/download/download_utils.h"
+#include "content/browser/url_loader_factory_getter.h"
+#include "content/common/throttling_url_loader.h"
+
+namespace content {
+
+// static
+std::unique_ptr<ResourceDownloader> ResourceDownloader::BeginDownload(
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
+ std::unique_ptr<DownloadUrlParameters> download_url_parameters,
+ std::unique_ptr<ResourceRequest> request,
+ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
+ uint32_t download_id,
+ bool is_parallel_request) {
+ if (download_url_parameters->url().SchemeIs(url::kBlobScheme))
+ return nullptr;
+
+ auto downloader = base::MakeUnique<ResourceDownloader>(
+ delegate, std::move(download_url_parameters), url_loader_factory_getter,
+ download_id, is_parallel_request);
+ downloader->Start(std::move(request));
+
+ return downloader;
+}
+
+ResourceDownloader::ResourceDownloader(
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
+ std::unique_ptr<DownloadUrlParameters> download_url_parameters,
+ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
+ uint32_t download_id,
+ bool is_parallel_request)
+ : delegate_(delegate),
+ download_url_parameters_(std::move(download_url_parameters)),
+ url_loader_factory_getter_(url_loader_factory_getter),
+ response_handler_(download_url_parameters_.get(),
+ this,
+ is_parallel_request),
+ download_id_(download_id),
+ weak_ptr_factory_(this) {}
+
+ResourceDownloader::~ResourceDownloader() = default;
+
+void ResourceDownloader::Start(std::unique_ptr<ResourceRequest> request) {
+ url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
+ url_loader_factory_getter_->GetNetworkFactory()->get(),
+ std::vector<std::unique_ptr<URLLoaderThrottle>>(),
+ 0, // routing_id
+ 0, // request_id
+ mojom::kURLLoadOptionSendSSLInfo | mojom::kURLLoadOptionSniffMimeType,
+ *(request.get()), &response_handler_,
+ download_url_parameters_->GetNetworkTrafficAnnotation());
+}
+
+void ResourceDownloader::OnResponseStarted(
+ std::unique_ptr<DownloadCreateInfo> download_create_info,
+ mojo::ScopedDataPipeConsumerHandle body) {
+ download_create_info->download_id = download_id_;
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ &UrlDownloadHandler::Delegate::OnUrlDownloadStarted, delegate_,
+ std::move(download_create_info),
+ base::MakeUnique<UrlDownloadHandler::InputStream>(std::move(body)),
+ download_url_parameters_->callback()));
+}
+
+} // namespace content
diff --git a/content/browser/download/resource_downloader.h b/content/browser/download/resource_downloader.h
new file mode 100644
index 0000000..a5925ef
--- /dev/null
+++ b/content/browser/download/resource_downloader.h
@@ -0,0 +1,73 @@
+// Copyright 2017 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.
+
+#ifndef CONTENT_BROWSER_DOWNLOAD_RESOURCE_DOWNLOADER_
+#define CONTENT_BROWSER_DOWNLOAD_RESOURCE_DOWNLOADER_
+
+#include "content/browser/download/download_response_handler.h"
+#include "content/browser/download/url_download_handler.h"
+#include "content/public/common/resource_request.h"
+#include "content/public/common/url_loader.mojom.h"
+
+namespace content {
+
+class ThrottlingURLLoader;
+class URLLoaderFactoryGetter;
+
+// Class for handing the download of a url.
+class ResourceDownloader : public UrlDownloadHandler,
+ public DownloadResponseHandler::Delegate {
+ public:
+ // Called to start a download, must be called on IO thread.
+ static std::unique_ptr<ResourceDownloader> BeginDownload(
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
+ std::unique_ptr<DownloadUrlParameters> download_url_parameters,
+ std::unique_ptr<ResourceRequest> request,
+ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
+ uint32_t download_id,
+ bool is_parallel_request);
+
+ ResourceDownloader(
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
+ std::unique_ptr<DownloadUrlParameters> download_url_parameters,
+ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
+ uint32_t download_id,
+ bool is_parallel_request);
+ ~ResourceDownloader() override;
+
+ // DownloadResponseHandler::Delegate
+ void OnResponseStarted(
+ std::unique_ptr<DownloadCreateInfo> download_create_info,
+ mojo::ScopedDataPipeConsumerHandle body) override;
+
+ private:
+ // Helper method to start the network request.
+ void Start(std::unique_ptr<ResourceRequest> request);
+
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate_;
+
+ // URLLoader for sending out the request.
+ std::unique_ptr<ThrottlingURLLoader> url_loader_;
+
+ // Parameters for constructing the ResourceRequest.
+ std::unique_ptr<DownloadUrlParameters> download_url_parameters_;
+
+ // Object for retrieving the URLLoaderFactory.
+ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter_;
+
+ // Object for handing the server response.
+ DownloadResponseHandler response_handler_;
+
+ // ID of the download, or DownloadItem::kInvalidId if this is a new
+ // download.
+ uint32_t download_id_;
+
+ base::WeakPtrFactory<ResourceDownloader> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResourceDownloader);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_RESOURCE_DOWNLOADER_
diff --git a/content/browser/download/url_download_handler.cc b/content/browser/download/url_download_handler.cc
new file mode 100644
index 0000000..0a2f5fc
--- /dev/null
+++ b/content/browser/download/url_download_handler.cc
@@ -0,0 +1,19 @@
+// Copyright 2017 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 "content/browser/download/url_download_handler.h"
+
+namespace content {
+
+UrlDownloadHandler::InputStream::InputStream(
+ std::unique_ptr<ByteStreamReader> stream_reader)
+ : stream_reader_(std::move(stream_reader)) {}
+
+UrlDownloadHandler::InputStream::InputStream(
+ mojo::ScopedDataPipeConsumerHandle body)
+ : body_(std::move(body)) {}
+
+UrlDownloadHandler::InputStream::~InputStream() = default;
+
+} // namespace content
diff --git a/content/browser/download/url_download_handler.h b/content/browser/download/url_download_handler.h
new file mode 100644
index 0000000..7a7ac1b
--- /dev/null
+++ b/content/browser/download/url_download_handler.h
@@ -0,0 +1,49 @@
+// Copyright 2017 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.
+
+#ifndef CONTENT_BROWSER_DOWNLOAD_URL_DOWNLOAD_HANDLER
+#define CONTENT_BROWSER_DOWNLOAD_URL_DOWNLOAD_HANDLER
+
+#include "content/browser/byte_stream.h"
+#include "content/public/browser/download_url_parameters.h"
+#include "content/public/common/url_loader.mojom.h"
+
+namespace content {
+
+struct DownloadCreateInfo;
+
+// Class for handling the download of a url. Implemented by child classes.
+class CONTENT_EXPORT UrlDownloadHandler {
+ public:
+ // InputStream to read after the download starts. Only one of them could be
+ // available at the same time.
+ struct CONTENT_EXPORT InputStream {
+ explicit InputStream(std::unique_ptr<ByteStreamReader> stream_reader);
+ explicit InputStream(mojo::ScopedDataPipeConsumerHandle body);
+ ~InputStream();
+
+ std::unique_ptr<ByteStreamReader> stream_reader_;
+ mojo::ScopedDataPipeConsumerHandle body_;
+ };
+
+ // Class to be notified when download starts/stops.
+ class CONTENT_EXPORT Delegate {
+ public:
+ virtual void OnUrlDownloadStarted(
+ std::unique_ptr<DownloadCreateInfo> download_create_info,
+ std::unique_ptr<InputStream> input_stream,
+ const DownloadUrlParameters::OnStartedCallback& callback) = 0;
+ // Called after the connection is cancelled or finished.
+ virtual void OnUrlDownloadStopped(UrlDownloadHandler* downloader) = 0;
+ };
+
+ UrlDownloadHandler() = default;
+ virtual ~UrlDownloadHandler() = default;
+
+ DISALLOW_COPY_AND_ASSIGN(UrlDownloadHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_URL_DOWNLOAD_HANDLER
diff --git a/content/browser/download/url_downloader.cc b/content/browser/download/url_downloader.cc
index 0781463..f240cb63 100644
--- a/content/browser/download/url_downloader.cc
+++ b/content/browser/download/url_downloader.cc
@@ -64,7 +64,7 @@
// static
std::unique_ptr<UrlDownloader> UrlDownloader::BeginDownload(
- base::WeakPtr<UrlDownloader::Delegate> delegate,
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
std::unique_ptr<net::URLRequest> request,
const Referrer& referrer,
bool is_parallel_request) {
@@ -84,9 +84,10 @@
return downloader;
}
-UrlDownloader::UrlDownloader(std::unique_ptr<net::URLRequest> request,
- base::WeakPtr<Delegate> delegate,
- bool is_parallel_request)
+UrlDownloader::UrlDownloader(
+ std::unique_ptr<net::URLRequest> request,
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
+ bool is_parallel_request)
: request_(std::move(request)),
delegate_(delegate),
core_(request_.get(), this, is_parallel_request),
@@ -215,9 +216,11 @@
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(&UrlDownloader::Delegate::OnUrlDownloaderStarted,
- delegate_, base::Passed(&create_info),
- base::Passed(&stream_reader), callback));
+ base::BindOnce(&UrlDownloadHandler::Delegate::OnUrlDownloadStarted,
+ delegate_, std::move(create_info),
+ base::MakeUnique<UrlDownloadHandler::InputStream>(
+ std::move(stream_reader)),
+ callback));
}
void UrlDownloader::OnReadyToRead() {
@@ -239,7 +242,7 @@
void UrlDownloader::Destroy() {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(&UrlDownloader::Delegate::OnUrlDownloaderStopped,
+ base::BindOnce(&UrlDownloadHandler::Delegate::OnUrlDownloadStopped,
delegate_, this));
}
diff --git a/content/browser/download/url_downloader.h b/content/browser/download/url_downloader.h
index e5c5b90..5f16838 100644
--- a/content/browser/download/url_downloader.h
+++ b/content/browser/download/url_downloader.h
@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "content/browser/download/download_request_core.h"
+#include "content/browser/download/url_download_handler.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/download_save_info.h"
#include "content/public/browser/download_url_parameters.h"
@@ -23,29 +24,16 @@
struct DownloadCreateInfo;
class UrlDownloader : public net::URLRequest::Delegate,
- public DownloadRequestCore::Delegate {
+ public DownloadRequestCore::Delegate,
+ public UrlDownloadHandler {
public:
- // Implemented by the owner of UrlDownloader, functions need to be called on
- // UI thread.
- class Delegate {
- public:
- // Called after response is handled and the byte stream is established.
- virtual void OnUrlDownloaderStarted(
- std::unique_ptr<DownloadCreateInfo> download_create_info,
- std::unique_ptr<ByteStreamReader> stream_reader,
- const DownloadUrlParameters::OnStartedCallback& callback) = 0;
-
- // Called after the connection is cannceled or finished.
- virtual void OnUrlDownloaderStopped(UrlDownloader* downloader) = 0;
- };
-
UrlDownloader(std::unique_ptr<net::URLRequest> request,
- base::WeakPtr<Delegate> delegate,
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
bool is_parallel_request);
~UrlDownloader() override;
static std::unique_ptr<UrlDownloader> BeginDownload(
- base::WeakPtr<UrlDownloader::Delegate> delegate,
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate,
std::unique_ptr<net::URLRequest> request,
const Referrer& referrer,
bool is_parallel_request);
@@ -84,7 +72,7 @@
std::unique_ptr<net::URLRequest> request_;
// Live on UI thread, post task to call |delegate_| functions.
- base::WeakPtr<Delegate> delegate_;
+ base::WeakPtr<UrlDownloadHandler::Delegate> delegate_;
DownloadRequestCore core_;
base::WeakPtrFactory<UrlDownloader> weak_ptr_factory_;