Commit c02048ed authored by Antonio Gomes's avatar Antonio Gomes Committed by Commit Bot

[chromeos] Migrate AttestationCAClient to SimpleURLLoader

URLFetcher will stop working with advent of Network Service, and
SimpleURLLoader is the replacement API for most clients.
This CL migrates chromeos::chromeos::AttestationCAClient and the
respective unittests away from URLFetcher.

BUG=773295,879782

Change-Id: I9ccdad3a73108ad3e3e7ab4f148b93048433b3bd
Reviewed-on: https://chromium-review.googlesource.com/1202223
Commit-Queue: Antonio Gomes <tonikitoo@igalia.com>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590089}
parent f88d7835
...@@ -11,8 +11,9 @@ ...@@ -11,8 +11,9 @@
#include "chromeos/chromeos_switches.h" #include "chromeos/chromeos_switches.h"
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_status.h" #include "net/url_request/url_request_status.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace { namespace {
...@@ -75,38 +76,36 @@ void AttestationCAClient::SendCertificateRequest( ...@@ -75,38 +76,36 @@ void AttestationCAClient::SendCertificateRequest(
request, on_response); request, on_response);
} }
void AttestationCAClient::OnURLFetchComplete(const net::URLFetcher* source) { void AttestationCAClient::OnURLLoadComplete(
FetcherCallbackMap::iterator iter = pending_requests_.find(source); std::list<std::unique_ptr<network::SimpleURLLoader>>::iterator it,
if (iter == pending_requests_.end()) { const DataCallback& callback,
LOG(WARNING) << "Callback from unknown source."; std::unique_ptr<std::string> response_body) {
return; // Move the loader out of the active loaders list.
} std::unique_ptr<network::SimpleURLLoader> url_loader = std::move(*it);
url_loaders_.erase(it);
DataCallback callback = iter->second; DCHECK(url_loader);
pending_requests_.erase(iter);
std::unique_ptr<const net::URLFetcher> scoped_source(source);
if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS) { int response_code = -1;
LOG(ERROR) << "Attestation CA request failed, status: " if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) {
<< source->GetStatus().status() << ", error: " response_code = url_loader->ResponseInfo()->headers->response_code();
<< source->GetStatus().error(); }
if (response_code < 200 || response_code > 299) {
LOG(ERROR) << "Attestation CA sent an error response: " << response_code;
callback.Run(false, ""); callback.Run(false, "");
return; return;
} }
if (source->GetResponseCode() != net::HTTP_OK) { if (!response_body) {
LOG(ERROR) << "Attestation CA sent an error response: " LOG(ERROR) << "Attestation CA request failed, error: "
<< source->GetResponseCode(); << url_loader->NetError();
callback.Run(false, ""); callback.Run(false, "");
return; return;
} }
std::string response;
bool result = source->GetResponseAsString(&response);
DCHECK(result) << "Invalid fetcher setting.";
// Run the callback last because it may delete |this|. // Run the callback last because it may delete |this|.
callback.Run(true, response); callback.Run(true, *response_body);
} }
void AttestationCAClient::FetchURL(const std::string& url, void AttestationCAClient::FetchURL(const std::string& url,
...@@ -140,18 +139,25 @@ void AttestationCAClient::FetchURL(const std::string& url, ...@@ -140,18 +139,25 @@ void AttestationCAClient::FetchURL(const std::string& url,
"cannot be controlled by a policy or through settings." "cannot be controlled by a policy or through settings."
policy_exception_justification: "Not implemented." policy_exception_justification: "Not implemented."
})"); })");
// The first argument allows the use of TestURLFetcherFactory in tests. auto resource_request = std::make_unique<network::ResourceRequest>();
net::URLFetcher* fetcher = resource_request->url = GURL(url);
net::URLFetcher::Create(0, GURL(url), net::URLFetcher::POST, this, resource_request->method = "POST";
traffic_annotation) resource_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
.release(); net::LOAD_DO_NOT_SAVE_COOKIES |
fetcher->SetRequestContext(g_browser_process->system_request_context()); net::LOAD_DISABLE_CACHE;
fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES | auto url_loader = network::SimpleURLLoader::Create(
net::LOAD_DISABLE_CACHE); std::move(resource_request), traffic_annotation);
fetcher->SetUploadData(kMimeContentType, request); url_loader->AttachStringForUpload(request, kMimeContentType);
pending_requests_[fetcher] = on_response;
fetcher->Start(); auto* raw_url_loader = url_loader.get();
url_loaders_.push_back(std::move(url_loader));
raw_url_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
g_browser_process->shared_url_loader_factory().get(),
base::BindOnce(&AttestationCAClient::OnURLLoadComplete,
base::Unretained(this), std::move(--url_loaders_.end()),
on_response));
} }
PrivacyCAType AttestationCAClient::GetType() { PrivacyCAType AttestationCAClient::GetType() {
......
...@@ -5,21 +5,24 @@ ...@@ -5,21 +5,24 @@
#ifndef CHROME_BROWSER_CHROMEOS_ATTESTATION_ATTESTATION_CA_CLIENT_H_ #ifndef CHROME_BROWSER_CHROMEOS_ATTESTATION_ATTESTATION_CA_CLIENT_H_
#define CHROME_BROWSER_CHROMEOS_ATTESTATION_ATTESTATION_CA_CLIENT_H_ #define CHROME_BROWSER_CHROMEOS_ATTESTATION_ATTESTATION_CA_CLIENT_H_
#include <list>
#include <map> #include <map>
#include <string> #include <string>
#include "base/macros.h" #include "base/macros.h"
#include "chromeos/attestation/attestation_flow.h" #include "chromeos/attestation/attestation_flow.h"
#include "chromeos/dbus/attestation_constants.h" #include "chromeos/dbus/attestation_constants.h"
#include "net/url_request/url_fetcher_delegate.h"
namespace network {
class SimpleURLLoader;
}
namespace chromeos { namespace chromeos {
namespace attestation { namespace attestation {
// This class is a ServerProxy implementation for the Chrome OS attestation // This class is a ServerProxy implementation for the Chrome OS attestation
// flow. It sends all requests to an Attestation CA via HTTPS. // flow. It sends all requests to an Attestation CA via HTTPS.
class AttestationCAClient : public ServerProxy, class AttestationCAClient : public ServerProxy {
public net::URLFetcherDelegate {
public: public:
AttestationCAClient(); AttestationCAClient();
~AttestationCAClient() override; ~AttestationCAClient() override;
...@@ -30,24 +33,24 @@ class AttestationCAClient : public ServerProxy, ...@@ -30,24 +33,24 @@ class AttestationCAClient : public ServerProxy,
void SendCertificateRequest(const std::string& request, void SendCertificateRequest(const std::string& request,
const DataCallback& on_response) override; const DataCallback& on_response) override;
// net::URLFetcherDelegate: void OnURLLoadComplete(
void OnURLFetchComplete(const net::URLFetcher* source) override; std::list<std::unique_ptr<network::SimpleURLLoader>>::iterator it,
const DataCallback& on_response,
std::unique_ptr<std::string> response_body);
PrivacyCAType GetType() override; PrivacyCAType GetType() override;
private: private:
PrivacyCAType pca_type_; PrivacyCAType pca_type_;
typedef std::map<const net::URLFetcher*, DataCallback> FetcherCallbackMap;
// POSTs |request| data to |url| and calls |on_response| with the response // POSTs |request| data to |url| and calls |on_response| with the response
// data when the fetch is complete. // data when the fetch is complete.
void FetchURL(const std::string& url, void FetchURL(const std::string& url,
const std::string& request, const std::string& request,
const DataCallback& on_response); const DataCallback& on_response);
// Tracks all URL requests we have started. // Loaders used for the processing the requests. Invalidated after completion.
FetcherCallbackMap pending_requests_; std::list<std::unique_ptr<network::SimpleURLLoader>> url_loaders_;
DISALLOW_COPY_AND_ASSIGN(AttestationCAClient); DISALLOW_COPY_AND_ASSIGN(AttestationCAClient);
}; };
......
...@@ -6,13 +6,16 @@ ...@@ -6,13 +6,16 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/test/bind_test_util.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chromeos/chromeos_switches.h" #include "chromeos/chromeos_switches.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_status.h" #include "net/url_request/url_request_status.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace chromeos { namespace chromeos {
...@@ -20,10 +23,25 @@ namespace attestation { ...@@ -20,10 +23,25 @@ namespace attestation {
class AttestationCAClientTest : public ::testing::Test { class AttestationCAClientTest : public ::testing::Test {
public: public:
AttestationCAClientTest() : num_invocations_(0), result_(false) {} AttestationCAClientTest()
: test_shared_url_loader_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_)),
num_invocations_(0),
result_(false) {}
~AttestationCAClientTest() override {} ~AttestationCAClientTest() override {}
void SetUp() override {
TestingBrowserProcess::GetGlobal()->SetSharedURLLoaderFactory(
test_shared_url_loader_factory_);
test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
[&](const network::ResourceRequest& request) {
last_resource_request_ = request;
}));
}
void DataCallback(bool result, const std::string& data) { void DataCallback(bool result, const std::string& data) {
++num_invocations_; ++num_invocations_;
result_ = result; result_ = result;
...@@ -41,29 +59,36 @@ class AttestationCAClientTest : public ::testing::Test { ...@@ -41,29 +59,36 @@ class AttestationCAClientTest : public ::testing::Test {
void CheckURLAndSendResponse(GURL expected_url, void CheckURLAndSendResponse(GURL expected_url,
net::Error error, net::Error error,
int response_code) { int response_code) {
net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); CHECK(test_url_loader_factory_.NumPending() == 1);
CHECK(fetcher); EXPECT_EQ(expected_url, last_resource_request_.url);
EXPECT_EQ(expected_url, fetcher->GetOriginalURL()); std::string response =
SendFetcherResponse(fetcher, error, response_code); network::GetUploadData(last_resource_request_) + "_response";
test_url_loader_factory_.AddResponse(last_resource_request_.url.spec(),
response);
base::RunLoop().RunUntilIdle();
} }
void SendResponse(net::Error error, int response_code) { void SendResponse(net::Error error, net::HttpStatusCode response_code) {
net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); CHECK(test_url_loader_factory_.NumPending() == 1);
CHECK(fetcher); auto resource_response_head =
SendFetcherResponse(fetcher, error, response_code); network::CreateResourceResponseHead(response_code);
} network::URLLoaderCompletionStatus completion_status(error);
std::string response =
void SendFetcherResponse(net::TestURLFetcher* fetcher, network::GetUploadData(last_resource_request_) + "_response";
net::Error error,
int response_code) { test_url_loader_factory_.AddResponse(last_resource_request_.url,
fetcher->set_status(net::URLRequestStatus::FromError(error)); resource_response_head, response,
fetcher->set_response_code(response_code); completion_status);
fetcher->SetResponseString(fetcher->upload_data() + "_response"); base::RunLoop().RunUntilIdle();
fetcher->delegate()->OnURLFetchComplete(fetcher);
} }
content::TestBrowserThreadBundle test_browser_thread_bundle_; content::TestBrowserThreadBundle test_browser_thread_bundle_;
net::TestURLFetcherFactory url_fetcher_factory_;
network::TestURLLoaderFactory test_url_loader_factory_;
scoped_refptr<network::SharedURLLoaderFactory>
test_shared_url_loader_factory_;
network::ResourceRequest last_resource_request_;
// For use with DataCallback. // For use with DataCallback.
int num_invocations_; int num_invocations_;
......
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