summaryrefslogtreecommitdiff
path: root/chromium/content/browser/download
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 15:28:34 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 13:54:51 +0000
commit2a19c63448c84c1805fb1a585c3651318bb86ca7 (patch)
treeeb17888e8531aa6ee5e85721bd553b832a7e5156 /chromium/content/browser/download
parentb014812705fc80bff0a5c120dfcef88f349816dc (diff)
downloadqtwebengine-chromium-2a19c63448c84c1805fb1a585c3651318bb86ca7.tar.gz
BASELINE: Update Chromium to 69.0.3497.70
Change-Id: I2b7b56e4e7a8b26656930def0d4575dc32b900a0 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/content/browser/download')
-rw-r--r--chromium/content/browser/download/blob_download_url_loader_factory_getter.cc38
-rw-r--r--chromium/content/browser/download/blob_download_url_loader_factory_getter.h40
-rw-r--r--chromium/content/browser/download/download_browsertest.cc303
-rw-r--r--chromium/content/browser/download/download_manager_impl.cc201
-rw-r--r--chromium/content/browser/download/download_manager_impl.h37
-rw-r--r--chromium/content/browser/download/download_manager_impl_unittest.cc69
-rw-r--r--chromium/content/browser/download/download_request_core.cc26
-rw-r--r--chromium/content/browser/download/download_request_core.h4
-rw-r--r--chromium/content/browser/download/download_request_core_unittest.cc3
-rw-r--r--chromium/content/browser/download/download_resource_handler.cc60
-rw-r--r--chromium/content/browser/download/download_resource_handler.h12
-rw-r--r--chromium/content/browser/download/download_utils.cc4
-rw-r--r--chromium/content/browser/download/file_download_url_loader_factory_getter.cc44
-rw-r--r--chromium/content/browser/download/file_download_url_loader_factory_getter.h36
-rw-r--r--chromium/content/browser/download/mhtml_generation_browsertest.cc2
-rw-r--r--chromium/content/browser/download/save_package.cc7
-rw-r--r--chromium/content/browser/download/url_downloader.cc40
-rw-r--r--chromium/content/browser/download/url_downloader.h9
-rw-r--r--chromium/content/browser/download/url_downloader_factory.cc3
-rw-r--r--chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc33
-rw-r--r--chromium/content/browser/download/web_ui_download_url_loader_factory_getter.h40
21 files changed, 721 insertions, 290 deletions
diff --git a/chromium/content/browser/download/blob_download_url_loader_factory_getter.cc b/chromium/content/browser/download/blob_download_url_loader_factory_getter.cc
deleted file mode 100644
index d5d418186a1..00000000000
--- a/chromium/content/browser/download/blob_download_url_loader_factory_getter.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 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/blob_download_url_loader_factory_getter.h"
-
-#include "components/download/public/common/download_task_runner.h"
-#include "content/browser/url_loader_factory_getter.h"
-#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
-#include "services/network/public/mojom/url_loader_factory.mojom.h"
-#include "storage/browser/blob/blob_data_handle.h"
-#include "storage/browser/blob/blob_url_loader_factory.h"
-
-namespace content {
-
-BlobDownloadURLLoaderFactoryGetter::BlobDownloadURLLoaderFactoryGetter(
- const GURL& url,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle)
- : url_(url), blob_data_handle_(std::move(blob_data_handle)) {
- DCHECK(url.SchemeIs(url::kBlobScheme));
-}
-
-BlobDownloadURLLoaderFactoryGetter::~BlobDownloadURLLoaderFactoryGetter() =
- default;
-
-scoped_refptr<network::SharedURLLoaderFactory>
-BlobDownloadURLLoaderFactoryGetter::GetURLLoaderFactory() {
- DCHECK(download::GetIOTaskRunner());
- DCHECK(download::GetIOTaskRunner()->BelongsToCurrentThread());
- network::mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info;
- storage::BlobURLLoaderFactory::Create(
- std::move(blob_data_handle_), url_,
- mojo::MakeRequest(&url_loader_factory_ptr_info));
- return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
- std::move(url_loader_factory_ptr_info));
-}
-
-} // namespace content
diff --git a/chromium/content/browser/download/blob_download_url_loader_factory_getter.h b/chromium/content/browser/download/blob_download_url_loader_factory_getter.h
deleted file mode 100644
index 10938f46c42..00000000000
--- a/chromium/content/browser/download/blob_download_url_loader_factory_getter.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 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_BLOB_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
-#define CONTENT_BROWSER_DOWNLOAD_BLOB_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
-
-#include "components/download/public/common/download_url_loader_factory_getter.h"
-#include "url/gurl.h"
-
-namespace storage {
-class BlobDataHandle;
-}
-
-namespace content {
-
-// Class for retrieving the URLLoaderFactory for a blob URL.
-class BlobDownloadURLLoaderFactoryGetter
- : public download::DownloadURLLoaderFactoryGetter {
- public:
- BlobDownloadURLLoaderFactoryGetter(
- const GURL& url,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle);
-
- // download::DownloadURLLoaderFactoryGetter implementation.
- scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
-
- protected:
- ~BlobDownloadURLLoaderFactoryGetter() override;
-
- private:
- GURL url_;
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle_;
-
- DISALLOW_COPY_AND_ASSIGN(BlobDownloadURLLoaderFactoryGetter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_DOWNLOAD_BLOB_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
diff --git a/chromium/content/browser/download/download_browsertest.cc b/chromium/content/browser/download/download_browsertest.cc
index 1cae12047b7..58882960352 100644
--- a/chromium/content/browser/download/download_browsertest.cc
+++ b/chromium/content/browser/download/download_browsertest.cc
@@ -43,6 +43,7 @@
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/common/content_paths.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -67,6 +68,8 @@
#include "ppapi/buildflags/buildflags.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/platform/web_mouse_event.h"
#include "url/gurl.h"
#if BUILDFLAG(ENABLE_PLUGINS)
@@ -231,7 +234,7 @@ class DownloadFileWithDelayFactory : public download::DownloadFileFactory {
private:
std::vector<base::Closure> rename_callbacks_;
- bool waiting_;
+ base::OnceClosure stop_waiting_;
base::WeakPtrFactory<DownloadFileWithDelayFactory> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelayFactory);
@@ -288,8 +291,7 @@ void DownloadFileWithDelay::RenameCallbackWrapper(
}
DownloadFileWithDelayFactory::DownloadFileWithDelayFactory()
- : waiting_(false),
- weak_ptr_factory_(this) {}
+ : weak_ptr_factory_(this) {}
DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {}
@@ -307,8 +309,8 @@ download::DownloadFile* DownloadFileWithDelayFactory::CreateFile(
void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
rename_callbacks_.push_back(std::move(callback));
- if (waiting_)
- base::RunLoop::QuitCurrentWhenIdleDeprecated();
+ if (stop_waiting_)
+ std::move(stop_waiting_).Run();
}
void DownloadFileWithDelayFactory::GetAllRenameCallbacks(
@@ -321,9 +323,9 @@ void DownloadFileWithDelayFactory::WaitForSomeCallback() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (rename_callbacks_.empty()) {
- waiting_ = true;
- RunMessageLoop();
- waiting_ = false;
+ base::RunLoop run_loop;
+ stop_waiting_ = run_loop.QuitClosure();
+ run_loop.Run();
}
}
@@ -366,11 +368,12 @@ class CountingDownloadFile : public download::DownloadFileImpl {
// until data is returned.
static int GetNumberActiveFilesFromFileThread() {
int result = -1;
+ base::RunLoop run_loop;
download::GetDownloadTaskRunner()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&CountingDownloadFile::GetNumberActiveFiles, &result),
- base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
- base::RunLoop().Run();
+ run_loop.QuitClosure());
+ run_loop.Run();
DCHECK_NE(-1, result);
return result;
}
@@ -2893,10 +2896,9 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
}
-// A filename suggestion specified via a @download attribute should be effective
-// if the final download URL is in the same origin as the initial download URL.
-// Test that this holds even if there are cross origin redirects in the middle
-// of the redirect chain.
+// A filename suggestion specified via a @download attribute should not be
+// effective if there are cross origin redirects in the middle of the redirect
+// chain.
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
DownloadAttributeSameOriginRedirect) {
net::EmbeddedTestServer origin_one;
@@ -2939,12 +2941,135 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
ASSERT_EQ(1u, downloads.size());
- EXPECT_EQ(FILE_PATH_LITERAL("suggested-filename"),
+ EXPECT_EQ(FILE_PATH_LITERAL("download"),
downloads[0]->GetTargetFilePath().BaseName().value());
ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete());
ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
}
+// A file type that Blink can handle should not be downloaded if there are cross
+// origin redirects in the middle of the redirect chain.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ DownloadAttributeSameOriginRedirectNavigation) {
+ net::EmbeddedTestServer origin_one;
+ net::EmbeddedTestServer origin_two;
+ ASSERT_TRUE(origin_one.InitializeAndListen());
+ ASSERT_TRUE(origin_two.InitializeAndListen());
+
+ // The download-attribute.html page contains an anchor element whose href is
+ // set to the value of the query parameter (specified as |target| in the URL
+ // below). The suggested filename for the anchor is 'suggested-filename'. When
+ // the page is loaded, a script simulates a click on the anchor, triggering a
+ // download of the target URL.
+ //
+ // We construct two test servers; origin_one and origin_two. Once started, the
+ // server URLs will differ by the port number. Therefore they will be in
+ // different origins.
+ GURL download_url = origin_one.GetURL("/ping");
+ GURL referrer_url = origin_one.GetURL(
+ std::string("/download-attribute.html?target=") + download_url.spec());
+ origin_one.ServeFilesFromDirectory(GetTestFilePath("download", ""));
+
+ // <origin_one>/download-attribute.html initiates a download of
+ // <origin_one>/ping, which redirects to <origin_two>/download. The latter
+ // serves an HTML document.
+ origin_one.RegisterRequestHandler(
+ CreateRedirectHandler("/ping", origin_two.GetURL("/download")));
+ origin_two.RegisterRequestHandler(
+ CreateBasicResponseHandler("/download", net::HTTP_OK, base::StringPairs(),
+ "text/html", "<title>hello</title>"));
+
+ origin_one.StartAcceptingConnections();
+ origin_two.StartAcceptingConnections();
+
+ base::string16 expected_title(base::UTF8ToUTF16("hello"));
+ TitleWatcher observer(shell()->web_contents(), expected_title);
+ NavigateToURL(shell(), referrer_url);
+ ASSERT_EQ(expected_title, observer.WaitAndGetTitle());
+
+ std::vector<download::DownloadItem*> downloads;
+ DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
+ ASSERT_EQ(0u, downloads.size());
+
+ ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete());
+ ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
+}
+
+// A download initiated by the user via alt-click on a link should download,
+// even when redirected cross origin.
+//
+// Alt-click doesn't make sense on Android, and download a HTML file results
+// in an intent, so just skip.
+#if !defined(OS_ANDROID)
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ DownloadAttributeSameOriginRedirectAltClick) {
+ net::EmbeddedTestServer origin_one;
+ net::EmbeddedTestServer origin_two;
+ ASSERT_TRUE(origin_one.InitializeAndListen());
+ ASSERT_TRUE(origin_two.InitializeAndListen());
+
+ // The download-attribute.html page contains an anchor element whose href is
+ // set to the value of the query parameter (specified as |target| in the URL
+ // below). The suggested filename for the anchor is 'suggested-filename'. We
+ // will later send a "real" click to the anchor, triggering a download of the
+ // target URL.
+ //
+ // We construct two test servers; origin_one and origin_two. Once started, the
+ // server URLs will differ by the port number. Therefore they will be in
+ // different origins.
+ GURL download_url = origin_one.GetURL("/ping");
+ GURL referrer_url = origin_one.GetURL(
+ std::string("/download-attribute.html?noclick=") + download_url.spec());
+ origin_one.ServeFilesFromDirectory(GetTestFilePath("download", ""));
+
+ // <origin_one>/download-attribute.html initiates a download of
+ // <origin_one>/ping, which redirects to <origin_two>/download. The latter
+ // serves an HTML document.
+ origin_one.RegisterRequestHandler(
+ CreateRedirectHandler("/ping", origin_two.GetURL("/download")));
+ origin_two.RegisterRequestHandler(
+ CreateBasicResponseHandler("/download", net::HTTP_OK, base::StringPairs(),
+ "text/html", "<title>hello</title>"));
+
+ origin_one.StartAcceptingConnections();
+ origin_two.StartAcceptingConnections();
+
+ std::unique_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
+ NavigateToURL(shell(), referrer_url);
+
+ // Alt-click the link.
+ blink::WebMouseEvent mouse_event(
+ blink::WebInputEvent::kMouseDown, blink::WebInputEvent::kAltKey,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ mouse_event.button = blink::WebMouseEvent::Button::kLeft;
+ mouse_event.SetPositionInWidget(15, 15);
+ mouse_event.click_count = 1;
+ shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
+ mouse_event);
+ mouse_event.SetType(blink::WebInputEvent::kMouseUp);
+ shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
+ mouse_event);
+
+ observer->WaitForFinished();
+ EXPECT_EQ(
+ 1u, observer->NumDownloadsSeenInState(download::DownloadItem::COMPLETE));
+
+ std::vector<download::DownloadItem*> downloads;
+ DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
+ ASSERT_EQ(1u, downloads.size());
+#if defined(OS_WIN)
+ EXPECT_EQ(FILE_PATH_LITERAL("download.htm"),
+ downloads[0]->GetTargetFilePath().BaseName().value());
+#else
+ EXPECT_EQ(FILE_PATH_LITERAL("download.html"),
+ downloads[0]->GetTargetFilePath().BaseName().value());
+#endif
+
+ ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete());
+ ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
+}
+#endif // !defined(OS_ANDROID)
+
// Test that the suggested filename for data: URLs works.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeDataUrl) {
net::EmbeddedTestServer server;
@@ -2988,23 +3113,33 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeServerError) {
// should result in a network error page.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeNetworkError) {
SetupErrorInjectionDownloads();
+ WebContents* content = shell()->web_contents();
GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
- TestDownloadHttpResponse::Parameters parameters;
+ GURL document_url = embedded_test_server()->GetURL(
+ std::string("/download/download-attribute.html?target=") +
+ server_url.spec());
+
// Simulate a network failure by injecting an error before the response
// header.
+ TestDownloadHttpResponse::Parameters parameters;
parameters.injected_errors.push(-1);
parameters.inject_error_cb = inject_error_callback();
TestDownloadHttpResponse::StartServing(parameters, server_url);
- GURL document_url = embedded_test_server()->GetURL(
- std::string("/download/download-attribute.html?target=") +
- server_url.spec());
- auto observer = std::make_unique<content::TestNavigationObserver>(
- shell()->web_contents(), 2);
- NavigateToURL(shell(), document_url);
- observer->Wait();
- EXPECT_FALSE(observer->last_navigation_succeeded());
+ content::TestNavigationManager navigation_document(content, document_url);
+ content::TestNavigationManager navigation_download(content, server_url);
+ shell()->LoadURL(document_url);
+ navigation_document.WaitForNavigationFinished();
+ navigation_download.WaitForNavigationFinished();
+
+ EXPECT_TRUE(navigation_document.was_successful());
+ EXPECT_FALSE(navigation_download.was_successful());
+
+ NavigationEntry* navigation_entry =
+ shell()->web_contents()->GetController().GetLastCommittedEntry();
+ EXPECT_EQ(PAGE_TYPE_ERROR, navigation_entry->GetPageType());
+ EXPECT_EQ(server_url, navigation_entry->GetURL());
}
// A request that fails due to it being rejected by policy should result in a
@@ -3031,6 +3166,28 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeBlobURL) {
download->GetTargetFilePath().BaseName().value().c_str());
}
+class DownloadContentTestWithMojoBlobURLs : public DownloadContentTest {
+ public:
+ DownloadContentTestWithMojoBlobURLs() {
+ scoped_feature_list_.InitAndEnableFeature(blink::features::kMojoBlobURLs);
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(DownloadContentTestWithMojoBlobURLs,
+ DownloadAttributeBlobURL) {
+ GURL document_url =
+ embedded_test_server()->GetURL("/download/download-attribute-blob.html");
+ download::DownloadItem* download =
+ StartDownloadAndReturnItem(shell(), document_url);
+ WaitForCompletion(download);
+
+ EXPECT_STREQ(FILE_PATH_LITERAL("suggested-filename.txt"),
+ download->GetTargetFilePath().BaseName().value().c_str());
+}
+
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeSameSiteCookie) {
base::ThreadRestrictions::ScopedAllowIO allow_io_during_test;
net::EmbeddedTestServer test_server;
@@ -3470,41 +3627,92 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, FetchErrorResponseBodyResumption) {
std::string("header_value"));
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest,
- DISABLED_ForceDownloadMultipartRelatedPage) {
- // Force downloading the MHTML.
- DownloadTestContentBrowserClient new_client;
- new_client.set_allowed_rendering_mhtml_over_http(false);
- ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadFromWebUI) {
+ GURL webui_url("chrome://resources/images/apps/blue_button.png");
+ NavigateToURL(shell(), webui_url);
+ SetupEnsureNoPendingDownloads();
+ std::unique_ptr<download::DownloadUrlParameters> download_parameters(
+ DownloadRequestUtils::CreateDownloadForWebContentsMainFrame(
+ shell()->web_contents(), webui_url, TRAFFIC_ANNOTATION_FOR_TESTS));
+ std::unique_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
+ DownloadManagerForShell(shell())->DownloadUrl(std::move(download_parameters));
+ observer->WaitForFinished();
+
+ EXPECT_TRUE(EnsureNoPendingDownloads());
+
+ std::vector<download::DownloadItem*> downloads;
+ DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
+ ASSERT_EQ(1u, downloads.size());
+ ASSERT_EQ(download::DownloadItem::COMPLETE, downloads[0]->GetState());
+}
+
+// Test fixture for forcing MHTML download.
+class MhtmlDownloadTest : public DownloadContentTest {
+ protected:
+ void SetUpOnMainThread() override {
+ DownloadContentTest::SetUpOnMainThread();
+
+ // Force downloading the MHTML.
+ new_client_.set_allowed_rendering_mhtml_over_http(false);
+ old_client_ = SetBrowserClientForTesting(&new_client_);
+ }
+ void TearDownOnMainThread() override {
+ SetBrowserClientForTesting(old_client_);
+ DownloadContentTest::TearDownOnMainThread();
+ }
+
+ private:
+ DownloadTestContentBrowserClient new_client_;
+ ContentBrowserClient* old_client_;
+};
+
+IN_PROC_BROWSER_TEST_F(MhtmlDownloadTest, ForceDownloadMultipartRelatedPage) {
NavigateToURLAndWaitForDownload(
shell(),
// .mhtml file is mapped to "multipart/related" by the test server.
embedded_test_server()->GetURL("/download/hello.mhtml"),
download::DownloadItem::COMPLETE);
- SetBrowserClientForTesting(old_client);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ForceDownloadMessageRfc822Page) {
- // Force downloading the MHTML.
- DownloadTestContentBrowserClient new_client;
- new_client.set_allowed_rendering_mhtml_over_http(false);
- ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
-
+#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(ADDRESS_SANITIZER)
+// Flaky https://crbug.com/852073
+#define MAYBE_ForceDownloadMessageRfc822Page \
+ DISABLED_ForceDownloadMessageRfc822Page
+#else
+#define MAYBE_ForceDownloadMessageRfc822Page ForceDownloadMessageRfc822Page
+#endif
+IN_PROC_BROWSER_TEST_F(MhtmlDownloadTest,
+ MAYBE_ForceDownloadMessageRfc822Page) {
NavigateToURLAndWaitForDownload(
shell(),
// .mht file is mapped to "message/rfc822" by the test server.
embedded_test_server()->GetURL("/download/test.mht"),
download::DownloadItem::COMPLETE);
- SetBrowserClientForTesting(old_client);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMultipartRelatedPage) {
- // Allows loading the MHTML, instead of downloading it.
- DownloadTestContentBrowserClient new_client;
- new_client.set_allowed_rendering_mhtml_over_http(true);
- ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
+// Test fixture for loading MHTML.
+class MhtmlLoadingTest : public DownloadContentTest {
+ protected:
+ void SetUpOnMainThread() override {
+ DownloadContentTest::SetUpOnMainThread();
+
+ // Allows loading the MHTML, instead of downloading it.
+ new_client_.set_allowed_rendering_mhtml_over_http(true);
+ old_client_ = SetBrowserClientForTesting(&new_client_);
+ }
+
+ void TearDownOnMainThread() override {
+ SetBrowserClientForTesting(old_client_);
+ DownloadContentTest::TearDownOnMainThread();
+ }
+ private:
+ DownloadTestContentBrowserClient new_client_;
+ ContentBrowserClient* old_client_;
+};
+
+IN_PROC_BROWSER_TEST_F(MhtmlLoadingTest, AllowRenderMultipartRelatedPage) {
// .mhtml file is mapped to "multipart/related" by the test server.
GURL url = embedded_test_server()->GetURL("/download/hello.mhtml");
auto observer = std::make_unique<content::TestNavigationObserver>(url);
@@ -3514,15 +3722,9 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMultipartRelatedPage) {
NavigateToURL(shell(), url);
observer->WaitForNavigationFinished();
- SetBrowserClientForTesting(old_client);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMessageRfc822Page) {
- // Allows loading the MHTML, instead of downloading it.
- DownloadTestContentBrowserClient new_client;
- new_client.set_allowed_rendering_mhtml_over_http(true);
- ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
-
+IN_PROC_BROWSER_TEST_F(MhtmlLoadingTest, AllowRenderMessageRfc822Page) {
// .mht file is mapped to "message/rfc822" by the test server.
GURL url = embedded_test_server()->GetURL("/download/test.mht");
auto observer = std::make_unique<content::TestNavigationObserver>(url);
@@ -3532,7 +3734,6 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMessageRfc822Page) {
NavigateToURL(shell(), url);
observer->WaitForNavigationFinished();
- SetBrowserClientForTesting(old_client);
}
} // namespace content
diff --git a/chromium/content/browser/download/download_manager_impl.cc b/chromium/content/browser/download/download_manager_impl.cc
index 081c7a2c2f1..f8c137fe6d7 100644
--- a/chromium/content/browser/download/download_manager_impl.cc
+++ b/chromium/content/browser/download/download_manager_impl.cc
@@ -21,8 +21,9 @@
#include "base/supports_user_data.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"
-#include "components/download/downloader/in_progress/download_entry.h"
-#include "components/download/downloader/in_progress/in_progress_cache_impl.h"
+#include "components/download/database/in_progress/download_entry.h"
+#include "components/download/database/in_progress/in_progress_cache_impl.h"
+#include "components/download/database/switches.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_file.h"
#include "components/download/public/common/download_interrupt_reasons.h"
@@ -38,14 +39,15 @@
#include "content/browser/byte_stream.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
-#include "content/browser/download/blob_download_url_loader_factory_getter.h"
#include "content/browser/download/byte_stream_input_stream.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/download/download_url_loader_factory_getter_impl.h"
#include "content/browser/download/download_utils.h"
+#include "content/browser/download/file_download_url_loader_factory_getter.h"
#include "content/browser/download/network_download_url_loader_factory_getter.h"
#include "content/browser/download/url_downloader.h"
#include "content/browser/download/url_downloader_factory.h"
+#include "content/browser/download/web_ui_download_url_loader_factory_getter.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"
@@ -112,6 +114,18 @@ bool CanRequestURLFromRenderer(int render_process_id, GURL url) {
return true;
}
+void OnDownloadStarted(
+ download::DownloadItemImpl* download,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started) {
+ if (on_started.is_null())
+ return;
+
+ if (!download || download->GetState() == download::DownloadItem::CANCELLED)
+ on_started.Run(nullptr, download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
+ else
+ on_started.Run(download, download::DOWNLOAD_INTERRUPT_REASON_NONE);
+}
+
// Creates an interrupted download and calls StartDownload. Can be called on
// any thread.
void CreateInterruptedDownload(
@@ -136,7 +150,7 @@ void CreateInterruptedDownload(
void BeginDownload(std::unique_ptr<download::DownloadUrlParameters> params,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
content::ResourceContext* resource_context,
- uint32_t download_id,
+ bool is_new_download,
base::WeakPtr<DownloadManagerImpl> download_manager) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -146,7 +160,8 @@ void BeginDownload(std::unique_ptr<download::DownloadUrlParameters> params,
params->set_blob_storage_context_getter(
base::BindOnce(&BlobStorageContextGetter, resource_context));
std::unique_ptr<net::URLRequest> url_request =
- DownloadRequestCore::CreateRequestOnIOThread(download_id, params.get());
+ DownloadRequestCore::CreateRequestOnIOThread(is_new_download,
+ params.get());
if (blob_data_handle) {
storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
url_request.get(), std::move(blob_data_handle));
@@ -288,17 +303,15 @@ DownloadManagerImpl::DownloadManagerImpl(BrowserContext* browser_context)
if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
download::UrlDownloadHandlerFactory::Install(new UrlDownloaderFactory());
in_progress_manager_ = std::make_unique<download::InProgressDownloadManager>(
- this, base::BindRepeating(&IsOriginSecure));
- in_progress_manager_->Initialize(
- IsOffTheRecord() ? base::FilePath() : browser_context_->GetPath(),
- base::BindOnce(&DownloadManagerImpl::PostInitialization,
- weak_factory_.GetWeakPtr(),
- DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE));
+ this, IsOffTheRecord() ? base::FilePath() : browser_context_->GetPath(),
+ base::BindRepeating(&IsOriginSecure));
+ in_progress_manager_->NotifyWhenInitialized(base::BindOnce(
+ &DownloadManagerImpl::OnInProgressDownloadManagerInitialized,
+ weak_factory_.GetWeakPtr()));
}
DownloadManagerImpl::~DownloadManagerImpl() {
DCHECK(!shutdown_needed_);
- download::SetIOTaskRunner(nullptr);
}
download::DownloadItemImpl* DownloadManagerImpl::CreateActiveItem(
@@ -311,6 +324,10 @@ download::DownloadItemImpl* DownloadManagerImpl::CreateActiveItem(
downloads_[id] = base::WrapUnique(download);
downloads_by_guid_[download->GetGuid()] = download;
+ DownloadItemUtils::AttachInfo(
+ download, GetBrowserContext(),
+ WebContentsImpl::FromRenderFrameHostID(info.render_process_id,
+ info.render_frame_id));
return download;
}
@@ -419,6 +436,25 @@ bool DownloadManagerImpl::InterceptDownload(
const download::DownloadCreateInfo& info) {
WebContents* web_contents = WebContentsImpl::FromRenderFrameHostID(
info.render_process_id, info.render_frame_id);
+ if (info.is_new_download &&
+ info.result ==
+ download::DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT) {
+ if (web_contents) {
+ std::vector<GURL> url_chain(info.url_chain);
+ GURL url = url_chain.back();
+ url_chain.pop_back();
+ NavigationController::LoadURLParams params(url);
+ params.has_user_gesture = info.has_user_gesture;
+ params.referrer = Referrer(
+ info.referrer_url, Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+ info.referrer_policy));
+ params.redirect_chain = url_chain;
+ web_contents->GetController().LoadURLWithParams(params);
+ }
+ if (info.request_handle)
+ info.request_handle->CancelRequest(false);
+ return true;
+ }
if (!delegate_ ||
!delegate_->InterceptDownloadIfApplicable(
info.url(), info.mime_type, info.request_origin, web_contents)) {
@@ -455,37 +491,59 @@ base::FilePath DownloadManagerImpl::GetDefaultDownloadDirectory() {
return default_download_directory;
}
-void DownloadManagerImpl::OnNewDownloadStarted(
- download::DownloadItem* download) {
- for (auto& observer : observers_)
- observer.OnDownloadCreated(this, download);
+void DownloadManagerImpl::OnInProgressDownloadManagerInitialized() {
+ std::vector<std::unique_ptr<download::DownloadItemImpl>>
+ in_progress_downloads = in_progress_manager_->TakeInProgressDownloads();
+ for (auto& download : in_progress_downloads) {
+ DCHECK(!base::ContainsKey(downloads_by_guid_, download->GetGuid()));
+ DCHECK(!base::ContainsKey(downloads_, download->GetId()));
+ DownloadItemUtils::AttachInfo(download.get(), GetBrowserContext(), nullptr);
+ download::DownloadItemImpl* item = download.get();
+ item->SetDelegate(this);
+ downloads_by_guid_[download->GetGuid()] = item;
+ downloads_[download->GetId()] = std::move(download);
+ for (auto& observer : observers_)
+ observer.OnDownloadCreated(this, item);
+ DVLOG(20) << __func__ << "() download = " << item->DebugString(true);
+ }
+ PostInitialization(DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE);
}
-download::DownloadItemImpl* DownloadManagerImpl::GetDownloadItem(
- uint32_t id,
- bool new_download,
- const download::DownloadCreateInfo& info) {
+void DownloadManagerImpl::StartDownloadItem(
+ std::unique_ptr<download::DownloadCreateInfo> info,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started,
+ download::InProgressDownloadManager::StartDownloadItemCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_NE(download::DownloadItem::kInvalidId, id);
- download::DownloadItemImpl* download = nullptr;
- if (new_download) {
- download = CreateActiveItem(id, info);
+ if (!info->is_new_download) {
+ download::DownloadItemImpl* download = downloads_by_guid_[info->guid];
+ if (!download || download->GetState() == download::DownloadItem::CANCELLED)
+ download = nullptr;
+ std::move(callback).Run(std::move(info), download);
+ OnDownloadStarted(download, on_started);
} else {
- auto item_iterator = downloads_.find(id);
- // Trying to resume an interrupted download.
- if (item_iterator == downloads_.end() ||
- (item_iterator->second->GetState() ==
- download::DownloadItem::CANCELLED)) {
- return nullptr;
- }
- download = item_iterator->second.get();
+ GetNextId(
+ base::BindRepeating(&DownloadManagerImpl::CreateNewDownloadItemToStart,
+ weak_factory_.GetWeakPtr(), base::Passed(&info),
+ on_started, base::Passed(&callback)));
}
- DownloadItemUtils::AttachInfo(
- download, GetBrowserContext(),
- WebContentsImpl::FromRenderFrameHostID(info.render_process_id,
- info.render_frame_id));
- return download;
+}
+
+void DownloadManagerImpl::CreateNewDownloadItemToStart(
+ std::unique_ptr<download::DownloadCreateInfo> info,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started,
+ download::InProgressDownloadManager::StartDownloadItemCallback callback,
+ uint32_t id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ download::DownloadItemImpl* download = CreateActiveItem(id, *info);
+ std::move(callback).Run(std::move(info), download);
+ // For new downloads, we notify here, rather than earlier, so that
+ // the download_file is bound to download and all the usual
+ // setters (e.g. Cancel) work.
+ for (auto& observer : observers_)
+ observer.OnDownloadCreated(this, download);
+ OnDownloadStarted(download, on_started);
}
net::URLRequestContextGetter* DownloadManagerImpl::GetURLRequestContextGetter(
@@ -517,6 +575,18 @@ void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
}
}
+void DownloadManagerImpl::OnHistoryQueryComplete(
+ base::OnceClosure load_history_downloads_cb) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ download::switches::kEnableDownloadDB) &&
+ !in_progress_cache_initialized_) {
+ load_history_downloads_cb_ = std::move(load_history_downloads_cb);
+ } else {
+ std::move(load_history_downloads_cb).Run();
+ }
+}
+
void DownloadManagerImpl::CheckForFileRemoval(
download::DownloadItemImpl* download_item) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -595,10 +665,9 @@ void DownloadManagerImpl::CreateSavePackageDownloadItemWithId(
// download.
void DownloadManagerImpl::ResumeInterruptedDownload(
std::unique_ptr<download::DownloadUrlParameters> params,
- uint32_t id,
const GURL& site_url) {
BeginDownloadInternal(std::move(params), nullptr /* blob_data_handle */,
- nullptr /* blob_url_loader_factory */, id, site_url);
+ nullptr /* blob_url_loader_factory */, false, site_url);
}
void DownloadManagerImpl::SetDownloadItemFactoryForTesting(
@@ -697,9 +766,9 @@ download::DownloadInterruptReason DownloadManagerImpl::BeginDownloadRequest(
// TODO(ananta)
// Find a better way to create the DownloadResourceHandler instance.
std::unique_ptr<ResourceHandler> handler(
- DownloadResourceHandler::CreateForNewRequest(url_request.get(),
- params->request_origin(),
- params->download_source()));
+ DownloadResourceHandler::CreateForNewRequest(
+ url_request.get(), params->request_origin(),
+ params->download_source(), params->follow_cross_origin_redirects()));
ResourceDispatcherHostImpl::Get()->BeginURLRequest(
std::move(url_request), std::move(handler), true, // download
@@ -784,8 +853,7 @@ void DownloadManagerImpl::DownloadUrl(
auto* rfh = RenderFrameHost::FromID(params->render_process_host_id(),
params->render_frame_host_routing_id());
BeginDownloadInternal(std::move(params), std::move(blob_data_handle),
- std::move(blob_url_loader_factory),
- download::DownloadItem::kInvalidId,
+ std::move(blob_url_loader_factory), true,
rfh ? rfh->GetSiteInstance()->GetSiteURL() : GURL());
}
@@ -824,10 +892,15 @@ download::DownloadItem* DownloadManagerImpl::CreateDownloadItem(
bool transient,
const std::vector<download::DownloadItem::ReceivedSlice>& received_slices) {
if (base::ContainsKey(downloads_, id)) {
- NOTREACHED();
- return nullptr;
+ // If a completed or cancelled download item is already in the history db,
+ // remove it from the in-progress db.
+ if (state == download::DownloadItem::COMPLETE ||
+ state == download::DownloadItem::CANCELLED) {
+ in_progress_manager_->RemoveInProgressDownload(guid);
+ } else {
+ return downloads_[id].get();
+ }
}
- DCHECK(!base::ContainsKey(downloads_by_guid_, guid));
download::DownloadItemImpl* item = item_factory_->CreatePersistedItem(
this, guid, id, current_path, target_path, url_chain, referrer_url,
site_url, tab_url, tab_refererr_url, mime_type, original_mime_type,
@@ -855,6 +928,8 @@ void DownloadManagerImpl::PostInitialization(
break;
case DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE:
in_progress_cache_initialized_ = true;
+ if (load_history_downloads_cb_)
+ std::move(load_history_downloads_cb_).Run();
break;
case DOWNLOAD_INITIALIZATION_DEPENDENCY_NONE:
default:
@@ -1016,9 +1091,8 @@ void DownloadManagerImpl::InterceptNavigationOnChecksComplete(
void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
std::unique_ptr<download::DownloadUrlParameters> params,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- uint32_t id,
+ bool is_new_download,
const GURL& site_url,
bool is_download_allowed) {
if (!is_download_allowed) {
@@ -1038,6 +1112,7 @@ void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
}
}
+ DCHECK_EQ(params->url().SchemeIsBlob(), bool{blob_url_loader_factory});
scoped_refptr<download::DownloadURLLoaderFactoryGetter>
url_loader_factory_getter;
if (blob_url_loader_factory) {
@@ -1045,10 +1120,14 @@ void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
url_loader_factory_getter =
base::MakeRefCounted<DownloadURLLoaderFactoryGetterImpl>(
blob_url_loader_factory->Clone());
- } else if (params->url().SchemeIsBlob()) {
+ } else if (params->url().SchemeIsFile()) {
url_loader_factory_getter =
- base::MakeRefCounted<BlobDownloadURLLoaderFactoryGetter>(
- params->url(), std::move(blob_data_handle));
+ base::MakeRefCounted<FileDownloadURLLoaderFactoryGetter>(
+ params->url(), browser_context_->GetPath());
+ } else if (params->url().SchemeIs(content::kChromeUIScheme)) {
+ url_loader_factory_getter =
+ base::MakeRefCounted<WebUIDownloadURLLoaderFactoryGetter>(
+ rfh, params->url());
} else {
StoragePartitionImpl* storage_partition =
static_cast<StoragePartitionImpl*>(
@@ -1058,16 +1137,16 @@ void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
CreateDownloadURLLoaderFactoryGetter(storage_partition, rfh, true);
}
- in_progress_manager_->BeginDownload(std::move(params),
- std::move(url_loader_factory_getter), id,
- site_url, tab_url, tab_referrer_url);
+ in_progress_manager_->BeginDownload(
+ std::move(params), std::move(url_loader_factory_getter), is_new_download,
+ site_url, tab_url, tab_referrer_url);
}
void DownloadManagerImpl::BeginDownloadInternal(
std::unique_ptr<download::DownloadUrlParameters> params,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- uint32_t id,
+ bool is_new_download,
const GURL& site_url) {
// Check if the renderer is permitted to request the requested URL.
if (params->render_process_host_id() >= 0 &&
@@ -1096,8 +1175,7 @@ void DownloadManagerImpl::BeginDownloadInternal(
on_can_download_checks_done = base::BindOnce(
&DownloadManagerImpl::BeginResourceDownloadOnChecksComplete,
weak_factory_.GetWeakPtr(), std::move(params),
- std::move(blob_data_handle), std::move(blob_url_loader_factory),
- id, site_url);
+ std::move(blob_url_loader_factory), is_new_download, site_url);
if (delegate_) {
delegate_->CheckDownloadAllowed(std::move(web_contents_getter), url,
method,
@@ -1107,9 +1185,8 @@ void DownloadManagerImpl::BeginDownloadInternal(
}
BeginResourceDownloadOnChecksComplete(
- std::move(params), std::move(blob_data_handle),
- std::move(blob_url_loader_factory), id, site_url,
- rfh ? !content_initiated : true);
+ std::move(params), std::move(blob_url_loader_factory), is_new_download,
+ site_url, rfh ? !content_initiated : true);
} else {
StoragePartition* storage_partition =
BrowserContext::GetStoragePartitionForSite(browser_context_, site_url);
@@ -1119,7 +1196,7 @@ void DownloadManagerImpl::BeginDownloadInternal(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&BeginDownload, std::move(params),
std::move(blob_data_handle),
- browser_context_->GetResourceContext(), id,
+ browser_context_->GetResourceContext(), is_new_download,
weak_factory_.GetWeakPtr()));
}
}
diff --git a/chromium/content/browser/download/download_manager_impl.h b/chromium/content/browser/download/download_manager_impl.h
index 041492c4347..4f07f57f252 100644
--- a/chromium/content/browser/download/download_manager_impl.h
+++ b/chromium/content/browser/download/download_manager_impl.h
@@ -128,6 +128,8 @@ class CONTENT_EXPORT DownloadManagerImpl
int NonMaliciousInProgressCount() const override;
BrowserContext* GetBrowserContext() const override;
void CheckForHistoryFilesRemoval() override;
+ void OnHistoryQueryComplete(
+ base::OnceClosure load_history_downloads_cb) override;
download::DownloadItem* GetDownload(uint32_t id) override;
download::DownloadItem* GetDownloadByGuid(const std::string& guid) override;
@@ -194,14 +196,27 @@ class CONTENT_EXPORT DownloadManagerImpl
// InProgressDownloadManager::Delegate implementations.
bool InterceptDownload(const download::DownloadCreateInfo& info) override;
base::FilePath GetDefaultDownloadDirectory() override;
- download::DownloadItemImpl* GetDownloadItem(
- uint32_t id,
- bool new_download,
- const download::DownloadCreateInfo& info) override;
+ void StartDownloadItem(
+ std::unique_ptr<download::DownloadCreateInfo> info,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started,
+ download::InProgressDownloadManager::StartDownloadItemCallback callback)
+ override;
net::URLRequestContextGetter* GetURLRequestContextGetter(
const download::DownloadCreateInfo& info) override;
- void OnNewDownloadStarted(download::DownloadItem* download) override;
- void GetNextId(const DownloadIdCallback& callback) override;
+
+ // Called when InProgressDownloadManager is initialzed.
+ void OnInProgressDownloadManagerInitialized();
+
+ // Creates a new download item and call |callback|.
+ void CreateNewDownloadItemToStart(
+ std::unique_ptr<download::DownloadCreateInfo> info,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started,
+ download::InProgressDownloadManager::StartDownloadItemCallback callback,
+ uint32_t id);
+
+ // Called to get an ID for a new download. |callback| may be called
+ // synchronously.
+ void GetNextId(const DownloadIdCallback& callback);
// Create a new active item based on the info. Separate from
// StartDownload() for testing.
@@ -209,7 +224,6 @@ class CONTENT_EXPORT DownloadManagerImpl
uint32_t id,
const download::DownloadCreateInfo& info);
-
// Called with the result of DownloadManagerDelegate::CheckForFileExistence.
// Updates the state of the file and then notifies this update to the file's
// observer.
@@ -227,7 +241,6 @@ class CONTENT_EXPORT DownloadManagerImpl
std::string GetApplicationClientIdForFileScanning() const override;
void ResumeInterruptedDownload(
std::unique_ptr<download::DownloadUrlParameters> params,
- uint32_t id,
const GURL& site_url) override;
void OpenDownload(download::DownloadItemImpl* download) override;
bool IsMostRecentDownloadItemAtFilePath(
@@ -248,7 +261,7 @@ class CONTENT_EXPORT DownloadManagerImpl
std::unique_ptr<download::DownloadUrlParameters> params,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- uint32_t id,
+ bool is_new_download,
const GURL& site_url);
void InterceptNavigationOnChecksComplete(
@@ -261,9 +274,8 @@ class CONTENT_EXPORT DownloadManagerImpl
bool is_download_allowed);
void BeginResourceDownloadOnChecksComplete(
std::unique_ptr<download::DownloadUrlParameters> params,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- uint32_t id,
+ bool is_new_download,
const GURL& site_url,
bool is_download_allowed);
@@ -314,6 +326,9 @@ class CONTENT_EXPORT DownloadManagerImpl
std::unique_ptr<download::InProgressDownloadManager> in_progress_manager_;
+ // Callback to run to load all history downloads.
+ base::OnceClosure load_history_downloads_cb_;
+
base::WeakPtrFactory<DownloadManagerImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DownloadManagerImpl);
diff --git a/chromium/content/browser/download/download_manager_impl_unittest.cc b/chromium/content/browser/download/download_manager_impl_unittest.cc
index 9ccc49d3df7..c4e5f80b78f 100644
--- a/chromium/content/browser/download/download_manager_impl_unittest.cc
+++ b/chromium/content/browser/download/download_manager_impl_unittest.cc
@@ -320,6 +320,36 @@ class MockByteStreamReader : public ByteStreamReader {
MOCK_METHOD1(RegisterCallback, void(const base::Closure&));
};
+class TestInProgressManager : public download::InProgressDownloadManager {
+ public:
+ TestInProgressManager();
+ ~TestInProgressManager() override = default;
+
+ std::vector<std::unique_ptr<download::DownloadItemImpl>>
+ TakeInProgressDownloads() override;
+
+ void AddDownloadItem(std::unique_ptr<download::DownloadItemImpl> item);
+
+ private:
+ std::vector<std::unique_ptr<download::DownloadItemImpl>> download_items_;
+};
+
+TestInProgressManager::TestInProgressManager()
+ : download::InProgressDownloadManager(
+ nullptr,
+ base::FilePath(),
+ download::InProgressDownloadManager::IsOriginSecureCallback()) {}
+
+void TestInProgressManager::AddDownloadItem(
+ std::unique_ptr<download::DownloadItemImpl> item) {
+ download_items_.emplace_back(std::move(item));
+}
+
+std::vector<std::unique_ptr<download::DownloadItemImpl>>
+TestInProgressManager::TakeInProgressDownloads() {
+ return std::move(download_items_);
+}
+
} // namespace
class DownloadManagerTest : public testing::Test {
@@ -450,6 +480,15 @@ class DownloadManagerTest : public testing::Test {
base::Unretained(this)));
}
+ void OnInProgressDownloadManagerInitialized() {
+ download_manager_->OnInProgressDownloadManagerInitialized();
+ }
+
+ void SetInProgressDownloadManager(
+ std::unique_ptr<download::InProgressDownloadManager> manager) {
+ download_manager_->in_progress_manager_ = std::move(manager);
+ }
+
protected:
// Key test variable; we'll keep it available to sub-classes.
std::unique_ptr<DownloadManagerImpl> download_manager_;
@@ -609,4 +648,34 @@ TEST_F(DownloadManagerTest, RemoveDownloadsByURL) {
EXPECT_EQ(remove_count, 1);
}
+// Confirm that in-progress downloads will be taken and managed by
+// DownloadManager.
+TEST_F(DownloadManagerTest, OnInProgressDownloadsLoaded) {
+ auto in_progress_manager = std::make_unique<TestInProgressManager>();
+ const char kGuid[] = "8DF158E8-C980-4618-BB03-EBA3242EB48B";
+ auto in_progress_item = std::make_unique<download::DownloadItemImpl>(
+ in_progress_manager.get(), kGuid, 10, base::FilePath(), base::FilePath(),
+ std::vector<GURL>(), GURL("http://example.com/a"),
+ GURL("http://example.com/a"), GURL("http://example.com/a"),
+ GURL("http://example.com/a"), "application/octet-stream",
+ "application/octet-stream", base::Time::Now(), base::Time::Now(),
+ std::string(), std::string(), 10, 10, std::string(),
+ download::DownloadItem::INTERRUPTED,
+ download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, false,
+ base::Time::Now(), true,
+ std::vector<download::DownloadItem::ReceivedSlice>());
+ in_progress_manager->AddDownloadItem(std::move(in_progress_item));
+ SetInProgressDownloadManager(std::move(in_progress_manager));
+ EXPECT_CALL(GetMockObserver(), OnDownloadCreated(download_manager_.get(), _))
+ .WillOnce(Return());
+ OnInProgressDownloadManagerInitialized();
+ ASSERT_TRUE(download_manager_->GetDownloadByGuid(kGuid));
+
+ download::DownloadItem* download =
+ download_manager_->GetDownloadByGuid(kGuid);
+ download->Remove();
+ ASSERT_FALSE(download_manager_->GetDownloadByGuid(kGuid));
+}
+
} // namespace content
diff --git a/chromium/content/browser/download/download_request_core.cc b/chromium/content/browser/download/download_request_core.cc
index 3b2045e18ee..fb6a33bcd83 100644
--- a/chromium/content/browser/download/download_request_core.cc
+++ b/chromium/content/browser/download/download_request_core.cc
@@ -56,14 +56,14 @@ class DownloadRequestData : public base::SupportsUserData::Data {
static void Attach(net::URLRequest* request,
download::DownloadUrlParameters* download_parameters,
- uint32_t download_id);
+ bool is_new_download);
static DownloadRequestData* Get(const net::URLRequest* request);
static void Detach(net::URLRequest* request);
std::unique_ptr<download::DownloadSaveInfo> TakeSaveInfo() {
return std::move(save_info_);
}
- uint32_t download_id() const { return download_id_; }
+ bool is_new_download() const { return is_new_download_; }
std::string guid() const { return guid_; }
bool is_transient() const { return transient_; }
bool fetch_error_body() const { return fetch_error_body_; }
@@ -80,7 +80,7 @@ class DownloadRequestData : public base::SupportsUserData::Data {
static const int kKey;
std::unique_ptr<download::DownloadSaveInfo> save_info_;
- uint32_t download_id_ = download::DownloadItem::kInvalidId;
+ bool is_new_download_;
std::string guid_;
bool fetch_error_body_ = false;
download::DownloadUrlParameters::RequestHeadersType request_headers_;
@@ -95,11 +95,11 @@ const int DownloadRequestData::kKey = 0;
// static
void DownloadRequestData::Attach(net::URLRequest* request,
download::DownloadUrlParameters* parameters,
- uint32_t download_id) {
+ bool is_new_download) {
auto request_data = std::make_unique<DownloadRequestData>();
request_data->save_info_.reset(
new download::DownloadSaveInfo(parameters->GetSaveInfo()));
- request_data->download_id_ = download_id;
+ request_data->is_new_download_ = is_new_download;
request_data->guid_ = parameters->guid();
request_data->fetch_error_body_ = parameters->fetch_error_body();
request_data->request_headers_ = parameters->request_headers();
@@ -125,16 +125,15 @@ const int DownloadRequestCore::kDownloadByteStreamSize = 100 * 1024;
// static
std::unique_ptr<net::URLRequest> DownloadRequestCore::CreateRequestOnIOThread(
- uint32_t download_id,
+ bool is_new_download,
download::DownloadUrlParameters* params) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(download_id == download::DownloadItem::kInvalidId ||
- !params->content_initiated())
- << "Content initiated downloads shouldn't specify a download ID";
+ DCHECK(is_new_download || !params->content_initiated())
+ << "Content initiated downloads should be a new download";
std::unique_ptr<net::URLRequest> request = CreateURLRequestOnIOThread(params);
- DownloadRequestData::Attach(request.get(), params, download_id);
+ DownloadRequestData::Attach(request.get(), params, is_new_download);
return request;
}
@@ -155,7 +154,7 @@ DownloadRequestCore::DownloadRequestCore(
download::DownloadSource download_source)
: delegate_(delegate),
request_(request),
- download_id_(download::DownloadItem::kInvalidId),
+ is_new_download_(true),
fetch_error_body_(false),
transient_(false),
bytes_read_(0),
@@ -193,7 +192,7 @@ DownloadRequestCore::DownloadRequestCore(
DownloadRequestData* request_data = DownloadRequestData::Get(request_);
if (request_data) {
save_info_ = request_data->TakeSaveInfo();
- download_id_ = request_data->download_id();
+ is_new_download_ = request_data->is_new_download();
guid_ = request_data->guid();
fetch_error_body_ = request_data->fetch_error_body();
request_headers_ = request_data->request_headers();
@@ -228,8 +227,9 @@ DownloadRequestCore::CreateDownloadCreateInfo(
create_info->connection_info = request()->response_info().connection_info;
create_info->url_chain = request()->url_chain();
create_info->referrer_url = GURL(request()->referrer());
+ create_info->referrer_policy = request()->referrer_policy();
create_info->result = result;
- create_info->download_id = download_id_;
+ create_info->is_new_download = is_new_download_;
create_info->guid = guid_;
create_info->transient = transient_;
create_info->response_headers = request()->response_headers();
diff --git a/chromium/content/browser/download/download_request_core.h b/chromium/content/browser/download/download_request_core.h
index 409e3e3912d..0fdd19edd45 100644
--- a/chromium/content/browser/download/download_request_core.h
+++ b/chromium/content/browser/download/download_request_core.h
@@ -109,7 +109,7 @@ class CONTENT_EXPORT DownloadRequestCore
std::string DebugString() const;
static std::unique_ptr<net::URLRequest> CreateRequestOnIOThread(
- uint32_t download_id,
+ bool is_new_download,
download::DownloadUrlParameters* params);
// Size of the buffer used between the DownloadRequestCore and the
@@ -129,7 +129,7 @@ class CONTENT_EXPORT DownloadRequestCore
// "Passthrough" fields. These are only kept here so that they can be used to
// populate the download::DownloadCreateInfo when the time comes.
std::unique_ptr<download::DownloadSaveInfo> save_info_;
- uint32_t download_id_;
+ bool is_new_download_;
std::string guid_;
bool fetch_error_body_;
download::DownloadUrlParameters::RequestHeadersType request_headers_;
diff --git a/chromium/content/browser/download/download_request_core_unittest.cc b/chromium/content/browser/download/download_request_core_unittest.cc
index 4d9c0db919d..5c6fb4e426b 100644
--- a/chromium/content/browser/download/download_request_core_unittest.cc
+++ b/chromium/content/browser/download/download_request_core_unittest.cc
@@ -46,8 +46,7 @@ class DownloadRequestCoreTest : public testing::Test {
}
void CreateRequestOnIOThread(download::DownloadUrlParameters* params) {
- url_request_ = DownloadRequestCore::CreateRequestOnIOThread(
- download::DownloadItem::kInvalidId, params);
+ url_request_ = DownloadRequestCore::CreateRequestOnIOThread(true, params);
DCHECK(url_request_.get());
}
diff --git a/chromium/content/browser/download/download_resource_handler.cc b/chromium/content/browser/download/download_resource_handler.cc
index d409db6c596..752cc1af42d 100644
--- a/chromium/content/browser/download/download_resource_handler.cc
+++ b/chromium/content/browser/download/download_resource_handler.cc
@@ -24,6 +24,7 @@
#include "content/browser/loader/resource_controller.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/navigation_entry.h"
@@ -109,10 +110,8 @@ void InitializeDownloadTabInfoOnUIThread(
tab_info->tab_url = entry->GetURL();
tab_info->tab_referrer_url = entry->GetReferrer().url;
- tab_info->ukm_source_id = ukm::UkmRecorder::GetNewSourceID();
- download::DownloadUkmHelper::UpdateSourceURL(
- ukm::UkmRecorder::Get(), tab_info->ukm_source_id,
- web_contents->GetLastCommittedURL());
+ tab_info->ukm_source_id = static_cast<WebContentsImpl*>(web_contents)
+ ->GetUkmSourceIdForLastCommittedSource();
}
}
}
@@ -120,14 +119,35 @@ void InitializeDownloadTabInfoOnUIThread(
void DeleteOnUIThread(
std::unique_ptr<DownloadResourceHandler::DownloadTabInfo> tab_info) {}
+void NavigateOnUIThread(
+ const GURL& url,
+ const std::vector<GURL> url_chain,
+ const Referrer& referrer,
+ bool has_user_gesture,
+ const ResourceRequestInfo::WebContentsGetter& wc_getter) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ WebContents* web_contents = wc_getter.Run();
+ if (web_contents) {
+ NavigationController::LoadURLParams params(url);
+ params.has_user_gesture = has_user_gesture;
+ params.referrer = referrer;
+ params.redirect_chain = url_chain;
+ web_contents->GetController().LoadURLWithParams(params);
+ }
+}
+
} // namespace
DownloadResourceHandler::DownloadResourceHandler(
net::URLRequest* request,
const std::string& request_origin,
- download::DownloadSource download_source)
+ download::DownloadSource download_source,
+ bool follow_cross_origin_redirects)
: ResourceHandler(request),
tab_info_(new DownloadTabInfo()),
+ follow_cross_origin_redirects_(follow_cross_origin_redirects),
+ first_origin_(url::Origin::Create(request->url())),
core_(request, this, false, request_origin, download_source) {
// Do UI thread initialization for tab_info_ asap after
// DownloadResourceHandler creation since the tab could be navigated
@@ -157,7 +177,7 @@ std::unique_ptr<ResourceHandler> DownloadResourceHandler::Create(
net::URLRequest* request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<ResourceHandler> handler(new DownloadResourceHandler(
- request, std::string(), download::DownloadSource::NAVIGATION));
+ request, std::string(), download::DownloadSource::NAVIGATION, true));
return handler;
}
@@ -165,10 +185,11 @@ std::unique_ptr<ResourceHandler> DownloadResourceHandler::Create(
std::unique_ptr<ResourceHandler> DownloadResourceHandler::CreateForNewRequest(
net::URLRequest* request,
const std::string& request_origin,
- download::DownloadSource download_source) {
+ download::DownloadSource download_source,
+ bool follow_cross_origin_redirects) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- std::unique_ptr<ResourceHandler> handler(
- new DownloadResourceHandler(request, request_origin, download_source));
+ std::unique_ptr<ResourceHandler> handler(new DownloadResourceHandler(
+ request, request_origin, download_source, follow_cross_origin_redirects));
return handler;
}
@@ -176,6 +197,21 @@ void DownloadResourceHandler::OnRequestRedirected(
const net::RedirectInfo& redirect_info,
network::ResourceResponse* response,
std::unique_ptr<ResourceController> controller) {
+ url::Origin new_origin(url::Origin::Create(redirect_info.new_url));
+ if (!follow_cross_origin_redirects_ &&
+ !first_origin_.IsSameOriginWith(new_origin)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ &NavigateOnUIThread, redirect_info.new_url, request()->url_chain(),
+ Referrer(GURL(redirect_info.new_referrer),
+ Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+ redirect_info.new_referrer_policy)),
+ GetRequestInfo()->HasUserGesture(),
+ GetRequestInfo()->GetWebContentsGetterForRequest()));
+ controller->Cancel();
+ return;
+ }
if (core_.OnRequestRedirected()) {
controller->Resume();
} else {
@@ -242,10 +278,6 @@ void DownloadResourceHandler::OnResponseCompleted(
controller->Resume();
}
-void DownloadResourceHandler::OnDataDownloaded(int bytes_downloaded) {
- NOTREACHED();
-}
-
void DownloadResourceHandler::PauseRequest() {
core_.PauseRequest();
}
@@ -262,7 +294,7 @@ void DownloadResourceHandler::OnStart(
// download entirely.
if (create_info->result ==
download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED &&
- create_info->download_id == download::DownloadItem::kInvalidId) {
+ create_info->is_new_download) {
if (!callback.is_null())
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
diff --git a/chromium/content/browser/download/download_resource_handler.h b/chromium/content/browser/download/download_resource_handler.h
index 39f1982b309..2d206330813 100644
--- a/chromium/content/browser/download/download_resource_handler.h
+++ b/chromium/content/browser/download/download_resource_handler.h
@@ -44,7 +44,8 @@ class CONTENT_EXPORT DownloadResourceHandler
// |id| should be invalid if the id should be automatically assigned.
DownloadResourceHandler(net::URLRequest* request,
const std::string& request_origin,
- download::DownloadSource download_source);
+ download::DownloadSource download_source,
+ bool follow_cross_origin_redirects);
// static
// This function is passed into ResourceDispatcherHostImpl during its
@@ -61,7 +62,8 @@ class CONTENT_EXPORT DownloadResourceHandler
static std::unique_ptr<ResourceHandler> CreateForNewRequest(
net::URLRequest* request,
const std::string& request_origin,
- download::DownloadSource download_source);
+ download::DownloadSource download_source,
+ bool follow_cross_origin_redirects);
void OnRequestRedirected(
const net::RedirectInfo& redirect_info,
@@ -90,9 +92,6 @@ class CONTENT_EXPORT DownloadResourceHandler
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) override;
- // N/A to this flavor of DownloadHandler.
- void OnDataDownloaded(int bytes_downloaded) override;
-
void PauseRequest();
void ResumeRequest();
@@ -120,6 +119,9 @@ class CONTENT_EXPORT DownloadResourceHandler
// deletion must occur on the IO thread.
std::unique_ptr<DownloadTabInfo> tab_info_;
+ bool follow_cross_origin_redirects_;
+ url::Origin first_origin_;
+
DownloadRequestCore core_;
DISALLOW_COPY_AND_ASSIGN(DownloadResourceHandler);
diff --git a/chromium/content/browser/download/download_utils.cc b/chromium/content/browser/download/download_utils.cc
index ab0e360a306..fec2b6a861c 100644
--- a/chromium/content/browser/download/download_utils.cc
+++ b/chromium/content/browser/download/download_utils.cc
@@ -9,8 +9,8 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/task_scheduler/post_task.h"
-#include "components/download/downloader/in_progress/download_entry.h"
-#include "components/download/downloader/in_progress/in_progress_cache.h"
+#include "components/download/database/in_progress/download_entry.h"
+#include "components/download/database/in_progress/in_progress_cache.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_interrupt_reasons_utils.h"
#include "components/download/public/common/download_save_info.h"
diff --git a/chromium/content/browser/download/file_download_url_loader_factory_getter.cc b/chromium/content/browser/download/file_download_url_loader_factory_getter.cc
new file mode 100644
index 00000000000..973baed881d
--- /dev/null
+++ b/chromium/content/browser/download/file_download_url_loader_factory_getter.cc
@@ -0,0 +1,44 @@
+// Copyright 2018 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/file_download_url_loader_factory_getter.h"
+
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_traits.h"
+#include "components/download/public/common/download_task_runner.h"
+#include "content/browser/file_url_loader_factory.h"
+#include "content/browser/url_loader_factory_getter.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+
+namespace content {
+
+FileDownloadURLLoaderFactoryGetter::FileDownloadURLLoaderFactoryGetter(
+ const GURL& url,
+ const base::FilePath& profile_path)
+ : url_(url), profile_path_(profile_path) {
+ DCHECK(url.SchemeIs(url::kFileScheme));
+}
+
+FileDownloadURLLoaderFactoryGetter::~FileDownloadURLLoaderFactoryGetter() =
+ default;
+
+scoped_refptr<network::SharedURLLoaderFactory>
+FileDownloadURLLoaderFactoryGetter::GetURLLoaderFactory() {
+ DCHECK(download::GetIOTaskRunner()->BelongsToCurrentThread());
+
+ network::mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info;
+ mojo::MakeStrongBinding(
+ std::make_unique<FileURLLoaderFactory>(
+ profile_path_, base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
+ MakeRequest(&url_loader_factory_ptr_info));
+
+ return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
+ std::move(url_loader_factory_ptr_info));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/download/file_download_url_loader_factory_getter.h b/chromium/content/browser/download/file_download_url_loader_factory_getter.h
new file mode 100644
index 00000000000..9c3e79c7a13
--- /dev/null
+++ b/chromium/content/browser/download/file_download_url_loader_factory_getter.h
@@ -0,0 +1,36 @@
+// Copyright 2018 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_FILE_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
+#define CONTENT_BROWSER_DOWNLOAD_FILE_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
+
+#include "base/files/file_path.h"
+#include "components/download/public/common/download_url_loader_factory_getter.h"
+#include "url/gurl.h"
+
+namespace content {
+
+// Class for retrieving the URLLoaderFactory for a file URL.
+class FileDownloadURLLoaderFactoryGetter
+ : public download::DownloadURLLoaderFactoryGetter {
+ public:
+ FileDownloadURLLoaderFactoryGetter(const GURL& url,
+ const base::FilePath& profile_path);
+
+ // download::DownloadURLLoaderFactoryGetter implementation.
+ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
+
+ protected:
+ ~FileDownloadURLLoaderFactoryGetter() override;
+
+ private:
+ GURL url_;
+ base::FilePath profile_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileDownloadURLLoaderFactoryGetter);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_FILE_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
diff --git a/chromium/content/browser/download/mhtml_generation_browsertest.cc b/chromium/content/browser/download/mhtml_generation_browsertest.cc
index d3e9279628a..379cc3ac485 100644
--- a/chromium/content/browser/download/mhtml_generation_browsertest.cc
+++ b/chromium/content/browser/download/mhtml_generation_browsertest.cc
@@ -13,7 +13,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_restrictions.h"
#include "components/download/public/common/download_task_runner.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
diff --git a/chromium/content/browser/download/save_package.cc b/chromium/content/browser/download/save_package.cc
index 7035f3e49d4..0310f540c34 100644
--- a/chromium/content/browser/download/save_package.cc
+++ b/chromium/content/browser/download/save_package.cc
@@ -44,6 +44,7 @@
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
@@ -257,7 +258,8 @@ void SavePackage::InternalInit() {
download::RecordSavePackageEvent(download::SAVE_PACKAGE_STARTED);
- ukm_source_id_ = ukm::UkmRecorder::GetNewSourceID();
+ ukm_source_id_ = static_cast<WebContentsImpl*>(web_contents())
+ ->GetUkmSourceIdForLastCommittedSource();
ukm_download_id_ = download::GetUniqueDownloadId();
download::DownloadUkmHelper::RecordDownloadStarted(
ukm_download_id_, ukm_source_id_, download::DownloadContent::TEXT,
@@ -284,9 +286,6 @@ bool SavePackage::Init(
std::unique_ptr<download::DownloadRequestHandleInterface> request_handle(
new SavePackageRequestHandle(AsWeakPtr()));
- download::DownloadUkmHelper::UpdateSourceURL(
- ukm::UkmRecorder::Get(), ukm_source_id_,
- web_contents()->GetLastCommittedURL());
RenderFrameHost* frame_host = web_contents()->GetMainFrame();
download_manager_->CreateSavePackageDownloadItem(
saved_main_file_path_, page_url_,
diff --git a/chromium/content/browser/download/url_downloader.cc b/chromium/content/browser/download/url_downloader.cc
index 034fadddce8..e44234a31f5 100644
--- a/chromium/content/browser/download/url_downloader.cc
+++ b/chromium/content/browser/download/url_downloader.cc
@@ -13,6 +13,7 @@
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_request_handle_interface.h"
#include "components/download/public/common/download_url_parameters.h"
+#include "components/download/public/common/url_download_request_handle.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/byte_stream_input_stream.h"
#include "content/public/browser/browser_thread.h"
@@ -25,43 +26,6 @@
namespace content {
-class UrlDownloader::RequestHandle
- : public download::DownloadRequestHandleInterface {
- public:
- RequestHandle(base::WeakPtr<UrlDownloader> downloader,
- scoped_refptr<base::SequencedTaskRunner> downloader_task_runner)
- : downloader_(downloader),
- downloader_task_runner_(downloader_task_runner) {}
- RequestHandle(RequestHandle&& other)
- : downloader_(std::move(other.downloader_)),
- downloader_task_runner_(std::move(other.downloader_task_runner_)) {}
- RequestHandle& operator=(RequestHandle&& other) {
- downloader_ = std::move(other.downloader_);
- downloader_task_runner_ = std::move(other.downloader_task_runner_);
- return *this;
- }
-
- // DownloadRequestHandleInterface
- void PauseRequest() override {
- downloader_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&UrlDownloader::PauseRequest, downloader_));
- }
- void ResumeRequest() override {
- downloader_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&UrlDownloader::ResumeRequest, downloader_));
- }
- void CancelRequest(bool user_cancel) override {
- downloader_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&UrlDownloader::CancelRequest, downloader_));
- }
-
- private:
- base::WeakPtr<UrlDownloader> downloader_;
- scoped_refptr<base::SequencedTaskRunner> downloader_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(RequestHandle);
-};
-
// static
std::unique_ptr<UrlDownloader> UrlDownloader::BeginDownload(
base::WeakPtr<download::UrlDownloadHandler::Delegate> delegate,
@@ -221,7 +185,7 @@ void UrlDownloader::OnStart(
std::unique_ptr<download::DownloadCreateInfo> create_info,
std::unique_ptr<ByteStreamReader> stream_reader,
const download::DownloadUrlParameters::OnStartedCallback& callback) {
- create_info->request_handle.reset(new RequestHandle(
+ create_info->request_handle.reset(new download::UrlDownloadRequestHandle(
weak_ptr_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get()));
BrowserThread::PostTask(
diff --git a/chromium/content/browser/download/url_downloader.h b/chromium/content/browser/download/url_downloader.h
index 0ee10feddf7..e5b7289ea15 100644
--- a/chromium/content/browser/download/url_downloader.h
+++ b/chromium/content/browser/download/url_downloader.h
@@ -42,8 +42,6 @@ class UrlDownloader : public net::URLRequest::Delegate,
bool is_parallel_request);
private:
- class RequestHandle;
-
void Start();
// URLRequest::Delegate:
@@ -64,9 +62,10 @@ class UrlDownloader : public net::URLRequest::Delegate,
override;
void OnReadyToRead() override;
- void PauseRequest();
- void ResumeRequest();
- void CancelRequest();
+ // UrlDownloadHandler implementations.
+ void PauseRequest() override;
+ void ResumeRequest() override;
+ void CancelRequest() override;
// Called when the UrlDownloader is done with the request. Posts a task to
// remove itself from its download manager, which in turn would cause the
diff --git a/chromium/content/browser/download/url_downloader_factory.cc b/chromium/content/browser/download/url_downloader_factory.cc
index 752cea70a5d..5a66bd2b9fa 100644
--- a/chromium/content/browser/download/url_downloader_factory.cc
+++ b/chromium/content/browser/download/url_downloader_factory.cc
@@ -23,8 +23,7 @@ UrlDownloaderFactory::CreateUrlDownloadHandler(
url_loader_factory_getter,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
std::unique_ptr<net::URLRequest> url_request =
- DownloadRequestCore::CreateRequestOnIOThread(
- download::DownloadItem::kInvalidId, params.get());
+ DownloadRequestCore::CreateRequestOnIOThread(true, params.get());
return download::UrlDownloadHandler::UniqueUrlDownloadHandlerPtr(
UrlDownloader::BeginDownload(delegate, std::move(url_request),
diff --git a/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc
new file mode 100644
index 00000000000..c4873157c81
--- /dev/null
+++ b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc
@@ -0,0 +1,33 @@
+// Copyright 2018 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/web_ui_download_url_loader_factory_getter.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_ui_url_loader_factory.h"
+#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
+
+namespace content {
+
+WebUIDownloadURLLoaderFactoryGetter::WebUIDownloadURLLoaderFactoryGetter(
+ RenderFrameHost* rfh,
+ const GURL& url) {
+ auto factory_request = mojo::MakeRequest(&factory_info_);
+ factory_ =
+ CreateWebUIURLLoader(rfh, url.scheme(), base::flat_set<std::string>());
+ factory_->Clone(std::move(factory_request));
+}
+
+WebUIDownloadURLLoaderFactoryGetter::~WebUIDownloadURLLoaderFactoryGetter() {
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)
+ ->DeleteSoon(FROM_HERE, std::move(factory_));
+}
+
+scoped_refptr<network::SharedURLLoaderFactory>
+WebUIDownloadURLLoaderFactoryGetter::GetURLLoaderFactory() {
+ return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
+ std::move(factory_info_));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.h b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.h
new file mode 100644
index 00000000000..5f39fd718c4
--- /dev/null
+++ b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.h
@@ -0,0 +1,40 @@
+// Copyright 2018 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_WEB_UI_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
+#define CONTENT_BROWSER_DOWNLOAD_WEB_UI_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
+
+#include "base/files/file_path.h"
+#include "components/download/public/common/download_url_loader_factory_getter.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+
+class GURL;
+
+namespace content {
+class RenderFrameHost;
+
+// Class for retrieving the URLLoaderFactory for a webui URL.
+class WebUIDownloadURLLoaderFactoryGetter
+ : public download::DownloadURLLoaderFactoryGetter {
+ public:
+ WebUIDownloadURLLoaderFactoryGetter(RenderFrameHost* rfh, const GURL& url);
+
+ // download::DownloadURLLoaderFactoryGetter implementation.
+ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
+
+ protected:
+ ~WebUIDownloadURLLoaderFactoryGetter() override;
+
+ private:
+ network::mojom::URLLoaderFactoryPtrInfo factory_info_;
+
+ // Lives on the UI thread and must be deleted there.
+ std::unique_ptr<network::mojom::URLLoaderFactory> factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebUIDownloadURLLoaderFactoryGetter);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_WEB_UI_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_