Commit 19a83d7a authored by Mark Pilgrim's avatar Mark Pilgrim Committed by Commit Bot

Migrate ResetReportUploader to SimpleURLLoader

The previous attempt was reverted because it crashed. This attempt
features a crash test which reproduces the crash when run against
the previous CL, and confirms that this CL does not crash.

The cause of the crash was a reference to simple_url_loader after it
had been std:move'd. This CL instead gets a reference to the newly
moved pointer.

previous CL: https://chromium-review.googlesource.com/c/chromium/src/+/1025068
revert CL: https://chromium-review.googlesource.com/c/chromium/src/+/1030590

Bug: 773295
Test: ResetReportUploaderTest.NoCrash
Change-Id: I7092ec501872dfa0019d37e8f9e10454458499db
Reviewed-on: https://chromium-review.googlesource.com/1042359
Commit-Queue: Mark Pilgrim <pilgrim@chromium.org>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556447}
parent d3b7ba4a
...@@ -13,8 +13,9 @@ ...@@ -13,8 +13,9 @@
#include "net/base/escape.h" #include "net/base/escape.h"
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h" #include "services/network/public/cpp/resource_request.h"
#include "net/url_request/url_request_context_getter.h" #include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace { namespace {
const char kResetReportUrl[] = const char kResetReportUrl[] =
...@@ -31,10 +32,9 @@ GURL GetClientReportUrl(const std::string& report_url) { ...@@ -31,10 +32,9 @@ GURL GetClientReportUrl(const std::string& report_url) {
} // namespace } // namespace
ResetReportUploader::ResetReportUploader(content::BrowserContext* context) ResetReportUploader::ResetReportUploader(
: url_request_context_getter_( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
content::BrowserContext::GetDefaultStoragePartition(context)-> : url_loader_factory_(std::move(url_loader_factory)) {}
GetURLRequestContext()) {}
ResetReportUploader::~ResetReportUploader() {} ResetReportUploader::~ResetReportUploader() {}
...@@ -43,6 +43,11 @@ void ResetReportUploader::DispatchReport( ...@@ -43,6 +43,11 @@ void ResetReportUploader::DispatchReport(
std::string request_data; std::string request_data;
CHECK(report.SerializeToString(&request_data)); CHECK(report.SerializeToString(&request_data));
DispatchReportInternal(request_data);
}
void ResetReportUploader::DispatchReportInternal(
const std::string& request_data) {
// Create traffic annotation tag. // Create traffic annotation tag.
net::NetworkTrafficAnnotationTag traffic_annotation = net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("profile_resetter_upload", R"( net::DefineNetworkTrafficAnnotation("profile_resetter_upload", R"(
...@@ -72,19 +77,31 @@ void ResetReportUploader::DispatchReport( ...@@ -72,19 +77,31 @@ void ResetReportUploader::DispatchReport(
"send the data." "send the data."
})"); })");
// Note fetcher will be deleted by OnURLFetchComplete. auto resource_request = std::make_unique<network::ResourceRequest>();
net::URLFetcher* fetcher = resource_request->url = GetClientReportUrl(kResetReportUrl);
net::URLFetcher::Create(GetClientReportUrl(kResetReportUrl), resource_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
net::URLFetcher::POST, this, traffic_annotation) net::LOAD_DO_NOT_SAVE_COOKIES |
.release(); net::LOAD_DISABLE_CACHE;
fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | resource_request->method = "POST";
net::LOAD_DO_NOT_SAVE_COOKIES | std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
net::LOAD_DISABLE_CACHE); network::SimpleURLLoader::Create(std::move(resource_request),
fetcher->SetRequestContext(url_request_context_getter_.get()); traffic_annotation);
fetcher->SetUploadData("application/octet-stream", request_data); simple_url_loader->AttachStringForUpload(request_data,
fetcher->Start(); "application/octet-stream");
auto it = simple_url_loaders_.insert(simple_url_loaders_.begin(),
std::move(simple_url_loader));
it->get()->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
url_loader_factory_.get(),
base::BindOnce(&ResetReportUploader::OnSimpleLoaderComplete,
base::Unretained(this), std::move(it)));
}
void ResetReportUploader::OnSimpleLoaderComplete(
SimpleURLLoaderList::iterator it,
std::unique_ptr<std::string> response_body) {
simple_url_loaders_.erase(it);
} }
void ResetReportUploader::OnURLFetchComplete(const net::URLFetcher* source) { GURL ResetReportUploader::GetClientReportUrlForTesting() {
delete source; return GetClientReportUrl(kResetReportUrl);
} }
...@@ -5,18 +5,16 @@ ...@@ -5,18 +5,16 @@
#ifndef CHROME_BROWSER_PROFILE_RESETTER_RESET_REPORT_UPLOADER_H_ #ifndef CHROME_BROWSER_PROFILE_RESETTER_RESET_REPORT_UPLOADER_H_
#define CHROME_BROWSER_PROFILE_RESETTER_RESET_REPORT_UPLOADER_H_ #define CHROME_BROWSER_PROFILE_RESETTER_RESET_REPORT_UPLOADER_H_
#include <list>
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "net/url_request/url_fetcher_delegate.h" #include "url/gurl.h"
namespace content {
class BrowserContext;
}
namespace net { namespace network {
class URLFetcher; class SimpleURLLoader;
class URLRequestContextGetter; class SharedURLLoaderFactory;
} }
namespace reset_report { namespace reset_report {
...@@ -24,18 +22,27 @@ class ChromeResetReport; ...@@ -24,18 +22,27 @@ class ChromeResetReport;
} }
// Service whose job is up upload ChromeResetReports. // Service whose job is up upload ChromeResetReports.
class ResetReportUploader : public KeyedService, class ResetReportUploader : public KeyedService {
private net::URLFetcherDelegate {
public: public:
explicit ResetReportUploader(content::BrowserContext* context); explicit ResetReportUploader(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
~ResetReportUploader() override; ~ResetReportUploader() override;
void DispatchReport(const reset_report::ChromeResetReport& report); void DispatchReport(const reset_report::ChromeResetReport& report);
// Visible for testing:
void DispatchReportInternal(const std::string& request_data);
static GURL GetClientReportUrlForTesting();
private: private:
void OnURLFetchComplete(const net::URLFetcher* source) override; using SimpleURLLoaderList =
std::list<std::unique_ptr<network::SimpleURLLoader>>;
void OnSimpleLoaderComplete(SimpleURLLoaderList::iterator it,
std::unique_ptr<std::string> response_body);
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
SimpleURLLoaderList simple_url_loaders_;
DISALLOW_COPY_AND_ASSIGN(ResetReportUploader); DISALLOW_COPY_AND_ASSIGN(ResetReportUploader);
}; };
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "chrome/browser/profile_resetter/reset_report_uploader.h" #include "chrome/browser/profile_resetter/reset_report_uploader.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
// static // static
ResetReportUploaderFactory* ResetReportUploaderFactory::GetInstance() { ResetReportUploaderFactory* ResetReportUploaderFactory::GetInstance() {
...@@ -29,5 +31,7 @@ ResetReportUploaderFactory::~ResetReportUploaderFactory() {} ...@@ -29,5 +31,7 @@ ResetReportUploaderFactory::~ResetReportUploaderFactory() {}
KeyedService* ResetReportUploaderFactory::BuildServiceInstanceFor( KeyedService* ResetReportUploaderFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const { content::BrowserContext* context) const {
return new ResetReportUploader(context); return new ResetReportUploader(
content::BrowserContext::GetDefaultStoragePartition(context)
->GetURLLoaderFactoryForBrowserProcess());
} }
// 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 "chrome/browser/profile_resetter/reset_report_uploader.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/common/weak_wrapper_shared_url_loader_factory.h"
#include "content/public/test/test_utils.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
class ResetReportUploaderTest : public testing::Test {
public:
ResetReportUploaderTest()
: test_shared_loader_factory_(
base::MakeRefCounted<content::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_)) {}
protected:
scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory() {
return test_shared_loader_factory_;
}
network::TestURLLoaderFactory* test_url_loader_factory() {
return &test_url_loader_factory_;
}
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
network::TestURLLoaderFactory test_url_loader_factory_;
scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
};
TEST_F(ResetReportUploaderTest, NoCrash) {
test_url_loader_factory()->AddResponse(
ResetReportUploader::GetClientReportUrlForTesting().spec(), "");
ResetReportUploader* uploader =
new ResetReportUploader(shared_url_loader_factory());
uploader->DispatchReportInternal("");
}
...@@ -2934,6 +2934,7 @@ test("unit_tests") { ...@@ -2934,6 +2934,7 @@ test("unit_tests") {
"../browser/platform_util_unittest.cc", "../browser/platform_util_unittest.cc",
"../browser/policy/policy_path_parser_unittest.cc", "../browser/policy/policy_path_parser_unittest.cc",
"../browser/profile_resetter/profile_resetter_unittest.cc", "../browser/profile_resetter/profile_resetter_unittest.cc",
"../browser/profile_resetter/reset_report_uploader_unittest.cc",
"../browser/profile_resetter/triggered_profile_resetter_win_unittest.cc", "../browser/profile_resetter/triggered_profile_resetter_win_unittest.cc",
"../browser/renderer_context_menu/render_view_context_menu_unittest.cc", "../browser/renderer_context_menu/render_view_context_menu_unittest.cc",
"../browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc", "../browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment