diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-09-29 16:16:15 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-11-09 10:04:06 +0000 |
commit | a95a7417ad456115a1ef2da4bb8320531c0821f1 (patch) | |
tree | edcd59279e486d2fd4a8f88a7ed025bcf925c6e6 /chromium/net/url_request | |
parent | 33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (diff) | |
download | qtwebengine-chromium-a95a7417ad456115a1ef2da4bb8320531c0821f1.tar.gz |
BASELINE: Update Chromium to 106.0.5249.126
Change-Id: Ib0bb21c437a7d1686e21c33f2d329f2ac425b7ab
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438936
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/url_request')
45 files changed, 667 insertions, 5869 deletions
diff --git a/chromium/net/url_request/http_with_dns_over_https_unittest.cc b/chromium/net/url_request/http_with_dns_over_https_unittest.cc index 43c94daca53..3707c5a17c8 100644 --- a/chromium/net/url_request/http_with_dns_over_https_unittest.cc +++ b/chromium/net/url_request/http_with_dns_over_https_unittest.cc @@ -34,6 +34,8 @@ #include "net/http/http_stream_factory_test_util.h" #include "net/log/net_log.h" #include "net/socket/transport_client_socket_pool.h" +#include "net/ssl/ssl_config_service.h" +#include "net/ssl/test_ssl_config_service.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" @@ -72,7 +74,7 @@ class TestHostResolverProc : public HostResolverProc { AddressList* addrlist, int* os_error) override { insecure_queries_served_++; - *addrlist = AddressList::CreateFromIPAddress(IPAddress(127, 0, 0, 1), 443); + *addrlist = AddressList::CreateFromIPAddress(IPAddress(127, 0, 0, 1), 0); return OK; } @@ -159,11 +161,14 @@ class DnsOverHttpsIntegrationTest : public TestWithTaskEnvironment { // HostResolverManager::HaveTestProcOverride disables the built-in DNS // client. auto* resolver_raw = resolver.get(); - resolver->SetProcParamsForTesting( - ProcTaskParams(host_resolver_proc_.get(), 1)); + resolver->SetProcParamsForTesting(ProcTaskParams(host_resolver_proc_, 1)); auto context_builder = CreateTestURLRequestContextBuilder(); context_builder->set_host_resolver(std::move(resolver)); + auto ssl_config_service = + std::make_unique<TestSSLConfigService>(SSLContextConfig()); + ssl_config_service_ = ssl_config_service.get(); + context_builder->set_ssl_config_service(std::move(ssl_config_service)); request_context_ = context_builder->Build(); if (mode == SecureDnsMode::kAutomatic) { @@ -172,7 +177,7 @@ class DnsOverHttpsIntegrationTest : public TestWithTaskEnvironment { } } - void AddHostWithEch(const url::SchemeHostPort host, + void AddHostWithEch(const url::SchemeHostPort& host, const IPAddress& address, base::span<const uint8_t> ech_config_list) { doh_server_.AddAddressRecord(host.host(), address); @@ -186,6 +191,7 @@ class DnsOverHttpsIntegrationTest : public TestWithTaskEnvironment { TestDohServer doh_server_; scoped_refptr<net::TestHostResolverProc> host_resolver_proc_; std::unique_ptr<URLRequestContext> request_context_; + raw_ptr<TestSSLConfigService> ssl_config_service_; }; // A convenience wrapper over `DnsOverHttpsIntegrationTest` that also starts an @@ -206,8 +212,7 @@ class HttpsWithDnsOverHttpsTest : public DnsOverHttpsIntegrationTest { std::unique_ptr<test_server::HttpResponse> HandleDefaultRequest( const test_server::HttpRequest& request) { - std::unique_ptr<test_server::BasicHttpResponse> http_response( - new test_server::BasicHttpResponse); + auto http_response = std::make_unique<test_server::BasicHttpResponse>(); test_https_requests_served_++; http_response->set_content(kTestBody); http_response->set_content_type("text/html"); @@ -365,6 +370,7 @@ TEST_F(HttpsWithDnsOverHttpsTest, HttpsUpgrade) { base::test::ScopedFeatureList features; features.InitAndEnableFeatureWithParameters( features::kUseDnsHttpsSvcb, {{"UseDnsHttpsSvcbHttpUpgrade", "true"}}); + ResetContext(); GURL https_url = https_server_.GetURL(kHostname, "/test"); EXPECT_TRUE(https_url.SchemeIs(url::kHttpsScheme)); @@ -408,6 +414,7 @@ TEST_F(HttpsWithDnsOverHttpsTest, HttpsMetadata) { base::test::ScopedFeatureList features; features.InitAndEnableFeatureWithParameters( features::kUseDnsHttpsSvcb, {{"UseDnsHttpsSvcbHttpUpgrade", "true"}}); + ResetContext(); GURL main_url = https_server_.GetURL(kHostname, "/test"); EXPECT_TRUE(main_url.SchemeIs(url::kHttpsScheme)); @@ -457,10 +464,10 @@ TEST_F(DnsOverHttpsIntegrationTest, EncryptedClientHello) { AddHostWithEch(url::SchemeHostPort(url), addr.front().address(), ech_config_list); - for (bool ech_enabled : {true, false}) { - SCOPED_TRACE(ech_enabled); + for (bool feature_enabled : {true, false}) { + SCOPED_TRACE(feature_enabled); base::test::ScopedFeatureList features; - if (ech_enabled) { + if (feature_enabled) { features.InitWithFeatures( /*enabled_features=*/{features::kUseDnsHttpsSvcb, features::kEncryptedClientHello}, @@ -471,22 +478,32 @@ TEST_F(DnsOverHttpsIntegrationTest, EncryptedClientHello) { /*disabled_features=*/{features::kEncryptedClientHello}); } - // Create a new `URLRequestContext`, to ensure there are no cached sockets, - // etc., from the previous loop iteration. - ResetContext(); - TestDelegate d; - std::unique_ptr<URLRequest> r = context()->CreateRequest( - url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS); - r->Start(); - EXPECT_TRUE(r->is_pending()); + for (bool config_enabled : {true, false}) { + SCOPED_TRACE(config_enabled); + bool ech_enabled = feature_enabled && config_enabled; - d.RunUntilComplete(); + // Create a new `URLRequestContext`, to ensure there are no cached + // sockets, etc., from the previous loop iteration. + ResetContext(); - EXPECT_THAT(d.request_status(), IsOk()); - EXPECT_EQ(1, d.response_started_count()); - EXPECT_FALSE(d.received_data_before_response()); - EXPECT_NE(0, d.bytes_received()); - EXPECT_EQ(ech_enabled, r->ssl_info().encrypted_client_hello); + SSLContextConfig config; + config.ech_enabled = config_enabled; + ssl_config_service_->UpdateSSLConfigAndNotify(config); + + TestDelegate d; + std::unique_ptr<URLRequest> r = context()->CreateRequest( + url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS); + r->Start(); + EXPECT_TRUE(r->is_pending()); + + d.RunUntilComplete(); + + EXPECT_THAT(d.request_status(), IsOk()); + EXPECT_EQ(1, d.response_started_count()); + EXPECT_FALSE(d.received_data_before_response()); + EXPECT_NE(0, d.bytes_received()); + EXPECT_EQ(ech_enabled, r->ssl_info().encrypted_client_hello); + } } } @@ -499,6 +516,7 @@ TEST_F(DnsOverHttpsIntegrationTest, EncryptedClientHelloStaleKey) { /*enabled_features=*/{features::kEncryptedClientHello, features::kUseDnsHttpsSvcb}, /*disabled_features=*/{}); + ResetContext(); static constexpr char kRealNameStale[] = "secret1.example"; static constexpr char kRealNameWrongPublicName[] = "secret2.example"; @@ -579,6 +597,7 @@ TEST_F(DnsOverHttpsIntegrationTest, EncryptedClientHelloFallback) { /*enabled_features=*/{features::kEncryptedClientHello, features::kUseDnsHttpsSvcb}, /*disabled_features=*/{}); + ResetContext(); static constexpr char kRealNameStale[] = "secret1.example"; static constexpr char kRealNameWrongPublicName[] = "secret2.example"; @@ -649,6 +668,7 @@ TEST_F(DnsOverHttpsIntegrationTest, EncryptedClientHelloFallbackTLS12) { /*enabled_features=*/{features::kEncryptedClientHello, features::kUseDnsHttpsSvcb}, /*disabled_features=*/{}); + ResetContext(); static constexpr char kRealNameStale[] = "secret1.example"; static constexpr char kRealNameWrongPublicName[] = "secret2.example"; diff --git a/chromium/net/url_request/report_sender.cc b/chromium/net/url_request/report_sender.cc index 269658b6314..e2deec544c7 100644 --- a/chromium/net/url_request/report_sender.cc +++ b/chromium/net/url_request/report_sender.cc @@ -80,8 +80,7 @@ void ReportSender::Send(const GURL& report_uri, url_request->set_method("POST"); std::vector<char> report_data(report.begin(), report.end()); - std::unique_ptr<UploadElementReader> reader( - new UploadOwnedBytesElementReader(&report_data)); + auto reader = std::make_unique<UploadOwnedBytesElementReader>(&report_data); url_request->set_upload( ElementsUploadDataStream::CreateWithReader(std::move(reader), 0)); diff --git a/chromium/net/url_request/report_sender_unittest.cc b/chromium/net/url_request/report_sender_unittest.cc index e1f5d814892..56eec03aed9 100644 --- a/chromium/net/url_request/report_sender_unittest.cc +++ b/chromium/net/url_request/report_sender_unittest.cc @@ -91,7 +91,7 @@ class MockServerErrorJob : public URLRequestJob { protected: void GetResponseInfo(HttpResponseInfo* info) override { - info->headers = new HttpResponseHeaders( + info->headers = base::MakeRefCounted<HttpResponseHeaders>( "HTTP/1.1 500 Internal Server Error\n" "Content-type: text/plain\n" "Content-Length: 0\n"); @@ -215,8 +215,7 @@ class ReportSenderTest : public TestWithTaskEnvironment { URLRequestMockDataJob::AddUrlHandler(); URLRequestFilter::GetInstance()->AddHostnameInterceptor( "http", kServerErrorHostname, - std::unique_ptr<URLRequestInterceptor>( - new MockServerErrorJobInterceptor())); + std::make_unique<MockServerErrorJobInterceptor>()); } void TearDown() override { URLRequestFilter::GetInstance()->ClearHandlers(); } @@ -334,8 +333,8 @@ TEST_F(ReportSenderTest, PendingRequestGetsDeleted) { EXPECT_EQ(0u, network_delegate().num_requests()); - std::unique_ptr<ReportSender> reporter( - new ReportSender(context(), TRAFFIC_ANNOTATION_FOR_TESTS)); + auto reporter = + std::make_unique<ReportSender>(context(), TRAFFIC_ANNOTATION_FOR_TESTS); reporter->Send(url, "application/foobar", kDummyReport, NetworkIsolationKey(), base::OnceCallback<void()>(), base::OnceCallback<void(const GURL&, int, int)>()); diff --git a/chromium/net/url_request/test_url_fetcher_factory.cc b/chromium/net/url_request/test_url_fetcher_factory.cc deleted file mode 100644 index 76af8176afb..00000000000 --- a/chromium/net/url_request/test_url_fetcher_factory.cc +++ /dev/null @@ -1,397 +0,0 @@ -// Copyright (c) 2012 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 "net/url_request/test_url_fetcher_factory.h" - -#include <memory> -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/compiler_specific.h" -#include "base/files/file_util.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/weak_ptr.h" -#include "base/task/sequenced_task_runner.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/threading/thread_restrictions.h" -#include "net/base/completion_once_callback.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/base/upload_data_stream.h" -#include "net/http/http_response_headers.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/url_fetcher_delegate.h" -#include "net/url_request/url_fetcher_impl.h" -#include "net/url_request/url_fetcher_response_writer.h" - -namespace net { - -ScopedURLFetcherFactory::ScopedURLFetcherFactory( - URLFetcherFactory* factory) { - DCHECK(!URLFetcherImpl::factory()); - URLFetcherImpl::set_factory(factory); -} - -ScopedURLFetcherFactory::~ScopedURLFetcherFactory() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(URLFetcherImpl::factory()); - URLFetcherImpl::set_factory(nullptr); -} - -TestURLFetcher::TestURLFetcher(int id, const GURL& url, URLFetcherDelegate* d) - : id_(id), original_url_(url), delegate_(d) { - CHECK(original_url_.is_valid()); -} - -TestURLFetcher::~TestURLFetcher() { - if (delegate_for_tests_) - delegate_for_tests_->OnRequestEnd(id_); -} - -void TestURLFetcher::SetUploadData(const std::string& upload_content_type, - const std::string& upload_content) { - upload_content_type_ = upload_content_type; - upload_data_ = upload_content; -} - -void TestURLFetcher::SetUploadFilePath( - const std::string& upload_content_type, - const base::FilePath& file_path, - uint64_t range_offset, - uint64_t range_length, - scoped_refptr<base::TaskRunner> file_task_runner) { - upload_file_path_ = file_path; -} - -void TestURLFetcher::SetUploadStreamFactory( - const std::string& upload_content_type, - const CreateUploadStreamCallback& factory) { -} - -void TestURLFetcher::SetChunkedUpload(const std::string& upload_content_type) { -} - -void TestURLFetcher::AppendChunkToUpload(const std::string& data, - bool is_last_chunk) { - DCHECK(!did_receive_last_chunk_); - did_receive_last_chunk_ = is_last_chunk; - chunks_.push_back(data); - if (delegate_for_tests_) - delegate_for_tests_->OnChunkUpload(id_); -} - -void TestURLFetcher::SetLoadFlags(int load_flags) { - fake_load_flags_= load_flags; -} - -int TestURLFetcher::GetLoadFlags() const { - return fake_load_flags_; -} - -void TestURLFetcher::SetReferrer(const std::string& referrer) { -} - -void TestURLFetcher::SetReferrerPolicy(ReferrerPolicy referrer_policy) {} - -void TestURLFetcher::ClearExtraRequestHeaders() { - fake_extra_request_headers_.Clear(); -} - -void TestURLFetcher::AddExtraRequestHeader(const std::string& name, - const std::string& value) { - fake_extra_request_headers_.SetHeader(name, value); -} - -void TestURLFetcher::SetRequestContext( - URLRequestContextGetter* request_context_getter) { -} - -void TestURLFetcher::SetInitiator( - const absl::optional<url::Origin>& initiator) {} - -void TestURLFetcher::SetURLRequestUserData( - const void* key, - const CreateDataCallback& create_data_callback) { -} - -void TestURLFetcher::SetStopOnRedirect(bool stop_on_redirect) { -} - -void TestURLFetcher::SetAutomaticallyRetryOn5xx(bool retry) { -} - -void TestURLFetcher::SetMaxRetriesOn5xx(int max_retries) { - fake_max_retries_ = max_retries; -} - -int TestURLFetcher::GetMaxRetriesOn5xx() const { - return fake_max_retries_; -} - -base::TimeDelta TestURLFetcher::GetBackoffDelay() const { - return base::TimeDelta(); -} - -void TestURLFetcher::SetAutomaticallyRetryOnNetworkChanges(int max_retries) { -} - -void TestURLFetcher::SaveResponseToFileAtPath( - const base::FilePath& file_path, - scoped_refptr<base::SequencedTaskRunner> file_task_runner) { - write_response_file_ = true; - SetResponseFilePath(file_path); - // Asynchronous IO is not supported, so file_task_runner is ignored. -} - -void TestURLFetcher::SaveResponseToTemporaryFile( - scoped_refptr<base::SequencedTaskRunner> file_task_runner) { - base::FilePath path; - if (!base::CreateTemporaryFile(&path)) - DLOG(ERROR) << "SaveResponseToTemporaryFile failed creating temp file"; - SaveResponseToFileAtPath(path, file_task_runner); -} - -void TestURLFetcher::SaveResponseWithWriter( - std::unique_ptr<URLFetcherResponseWriter> response_writer) { - // In class URLFetcherCore this method is called by all three: - // GetResponseAsString() / SaveResponseToFileAtPath() / - // SaveResponseToTemporaryFile(). But here (in TestURLFetcher), this method - // is never used by any of these three methods. So, file writing is expected - // to be done in SaveResponseToFileAtPath(), and this method supports only - // URLFetcherStringWriter (for testing of this method only). - if (fake_response_destination_ == STRING) { - response_writer_ = std::move(response_writer); - int response = response_writer_->Initialize(CompletionOnceCallback()); - // The TestURLFetcher doesn't handle asynchronous writes. - DCHECK_EQ(OK, response); - - scoped_refptr<IOBuffer> buffer = - base::MakeRefCounted<StringIOBuffer>(fake_response_string_); - response = response_writer_->Write( - buffer.get(), fake_response_string_.size(), CompletionOnceCallback()); - DCHECK_EQ(static_cast<int>(fake_response_string_.size()), response); - response = response_writer_->Finish(OK, CompletionOnceCallback()); - DCHECK_EQ(OK, response); - } else if (fake_response_destination_ == TEMP_FILE) { - // SaveResponseToFileAtPath() should be called instead of this method to - // save file. Asynchronous file writing using URLFetcherFileWriter is not - // supported. - NOTIMPLEMENTED(); - } else { - NOTREACHED(); - } -} - -HttpResponseHeaders* TestURLFetcher::GetResponseHeaders() const { - return fake_response_headers_.get(); -} - -IPEndPoint TestURLFetcher::GetSocketAddress() const { - NOTIMPLEMENTED(); - return IPEndPoint(); -} - -const ProxyServer& TestURLFetcher::ProxyServerUsed() const { - return fake_proxy_server_; -} - -bool TestURLFetcher::WasCached() const { - return fake_was_cached_; -} - -int64_t TestURLFetcher::GetReceivedResponseContentLength() const { - return fake_response_bytes_; -} - -int64_t TestURLFetcher::GetTotalReceivedBytes() const { - return fake_was_cached_ ? 0 : fake_response_bytes_; -} - -void TestURLFetcher::Start() { - // Overriden to do nothing. It is assumed the caller will notify the delegate. - if (delegate_for_tests_) - delegate_for_tests_->OnRequestStart(id_); - - // If the response should go into a file, write it out now. - if (fake_error_ == net::OK && fake_response_code_ == net::HTTP_OK && - write_response_file_ && !fake_response_file_path_.empty()) { - base::ScopedAllowBlockingForTesting allow_blocking; - size_t written_bytes = - base::WriteFile(fake_response_file_path_, fake_response_string_.c_str(), - fake_response_string_.size()); - DCHECK_EQ(fake_response_string_.size(), written_bytes); - } -} - -const GURL& TestURLFetcher::GetOriginalURL() const { - return original_url_; -} - -const GURL& TestURLFetcher::GetURL() const { - return fake_url_; -} - -Error TestURLFetcher::GetError() const { - return fake_error_; -} - -int TestURLFetcher::GetResponseCode() const { - return fake_response_code_; -} - -void TestURLFetcher::ReceivedContentWasMalformed() { -} - -bool TestURLFetcher::GetResponseAsString( - std::string* out_response_string) const { - if (fake_response_destination_ != STRING) - return false; - - *out_response_string = fake_response_string_; - return true; -} - -bool TestURLFetcher::GetResponseAsFilePath( - bool take_ownership, base::FilePath* out_response_path) const { - if (fake_response_destination_ != TEMP_FILE) - return false; - - *out_response_path = fake_response_file_path_; - return true; -} - -void TestURLFetcher::GetExtraRequestHeaders( - HttpRequestHeaders* headers) const { - *headers = fake_extra_request_headers_; -} - -void TestURLFetcher::set_was_cached(bool flag) { - fake_was_cached_ = flag; -} - -void TestURLFetcher::set_response_headers( - scoped_refptr<HttpResponseHeaders> headers) { - fake_response_headers_ = headers; -} - -void TestURLFetcher::SetDelegateForTests(DelegateForTests* delegate_for_tests) { - delegate_for_tests_ = delegate_for_tests; -} - -void TestURLFetcher::SetResponseString(const std::string& response) { - fake_response_destination_ = STRING; - fake_response_string_ = response; - fake_response_bytes_ = response.size(); -} - -void TestURLFetcher::SetResponseFilePath(const base::FilePath& path) { - fake_response_destination_ = TEMP_FILE; - fake_response_file_path_ = path; -} - -FakeURLFetcher::FakeURLFetcher(const GURL& url, - URLFetcherDelegate* d, - const std::string& response_data, - HttpStatusCode response_code, - Error error) - : TestURLFetcher(0, url, d) { - set_error(error); - set_response_code(response_code); - SetResponseString(response_data); - response_bytes_ = response_data.size(); -} - -FakeURLFetcher::~FakeURLFetcher() = default; - -void FakeURLFetcher::Start() { - TestURLFetcher::Start(); - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&FakeURLFetcher::RunDelegate, weak_factory_.GetWeakPtr())); -} - -void FakeURLFetcher::RunDelegate() { - // OnURLFetchDownloadProgress may delete this URLFetcher. We keep track of - // this with a weak pointer, and only call OnURLFetchComplete if this still - // exists. - auto weak_this = weak_factory_.GetWeakPtr(); - delegate()->OnURLFetchDownloadProgress(this, response_bytes_, response_bytes_, - response_bytes_); - if (weak_this.get()) - delegate()->OnURLFetchComplete(this); -} - -const GURL& FakeURLFetcher::GetURL() const { - return TestURLFetcher::GetOriginalURL(); -} - -FakeURLFetcherFactory::FakeURLFetcherFactory(URLFetcherFactory* default_factory) - : ScopedURLFetcherFactory(this), - creator_(base::BindRepeating(&DefaultFakeURLFetcherCreator)), - default_factory_(default_factory) {} - -FakeURLFetcherFactory::FakeURLFetcherFactory( - URLFetcherFactory* default_factory, - const FakeURLFetcherCreator& creator) - : ScopedURLFetcherFactory(this), - creator_(creator), - default_factory_(default_factory) { -} - -std::unique_ptr<FakeURLFetcher> -FakeURLFetcherFactory::DefaultFakeURLFetcherCreator( - const GURL& url, - URLFetcherDelegate* delegate, - const std::string& response_data, - HttpStatusCode response_code, - Error error) { - return std::make_unique<FakeURLFetcher>(url, delegate, response_data, - response_code, error); -} - -FakeURLFetcherFactory::~FakeURLFetcherFactory() = default; - -std::unique_ptr<URLFetcher> FakeURLFetcherFactory::CreateURLFetcher( - int id, - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - NetworkTrafficAnnotationTag traffic_annotation) { - FakeResponseMap::const_iterator it = fake_responses_.find(url); - if (it == fake_responses_.end()) { - if (default_factory_ == nullptr) { - // If we don't have a baked response for that URL we return NULL. - DLOG(ERROR) << "No baked response for URL: " << url.spec(); - return nullptr; - } else { - return default_factory_->CreateURLFetcher(id, url, request_type, d, - traffic_annotation); - } - } - - std::unique_ptr<URLFetcher> fake_fetcher = - creator_.Run(url, d, it->second.response_data, it->second.response_code, - it->second.error); - return fake_fetcher; -} - -void FakeURLFetcherFactory::SetFakeResponse(const GURL& url, - const std::string& response_data, - HttpStatusCode response_code, - Error error) { - // Overwrite existing URL if it already exists. - FakeURLResponse response; - response.response_data = response_data; - response.response_code = response_code; - response.error = error; - fake_responses_[url] = response; -} - -void FakeURLFetcherFactory::ClearFakeResponses() { - fake_responses_.clear(); -} - -} // namespace net diff --git a/chromium/net/url_request/test_url_fetcher_factory.h b/chromium/net/url_request/test_url_fetcher_factory.h deleted file mode 100644 index 412c1514d5d..00000000000 --- a/chromium/net/url_request/test_url_fetcher_factory.h +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright (c) 2012 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 NET_URL_REQUEST_TEST_URL_FETCHER_FACTORY_H_ -#define NET_URL_REQUEST_TEST_URL_FETCHER_FACTORY_H_ - -#include <stdint.h> - -#include <list> -#include <map> -#include <memory> -#include <string> -#include <utility> - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/files/file_path.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/task/sequenced_task_runner.h" -#include "base/threading/thread_checker.h" -#include "net/base/ip_endpoint.h" -#include "net/base/net_errors.h" -#include "net/base/proxy_server.h" -#include "net/http/http_request_headers.h" -#include "net/http/http_status_code.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/referrer_policy.h" -#include "net/url_request/url_fetcher_factory.h" -#include "url/gurl.h" - -namespace net { - -// Changes URLFetcher's Factory for the lifetime of the object. -// Note that this scoper cannot be nested (to make it even harder to misuse). -class ScopedURLFetcherFactory { - public: - explicit ScopedURLFetcherFactory(URLFetcherFactory* factory); - - ScopedURLFetcherFactory(const ScopedURLFetcherFactory&) = delete; - ScopedURLFetcherFactory& operator=(const ScopedURLFetcherFactory&) = delete; - - virtual ~ScopedURLFetcherFactory(); - - private: - THREAD_CHECKER(thread_checker_); -}; - -// TestURLFetcher and TestURLFetcherFactory are used for testing consumers of -// URLFetcher. TestURLFetcherFactory is a URLFetcherFactory that creates -// TestURLFetchers. TestURLFetcher::Start is overriden to do nothing. It is -// expected that you'll grab the delegate from the TestURLFetcher and invoke -// the callback method when appropriate. In this way it's easy to mock a -// URLFetcher. -// Typical usage: -// // TestURLFetcher requires a MessageLoop and an IO thread to release -// // URLRequestContextGetter in URLFetcher::Core. -// BrowserTaskEnvironment task_environment_; -// // Create factory (it automatically sets itself as URLFetcher's factory). -// TestURLFetcherFactory factory; -// // Do something that triggers creation of a URLFetcher. -// ... -// TestURLFetcher* fetcher = factory.GetFetcherByID(expected_id); -// DCHECK(fetcher); -// // Notify delegate with whatever data you want. -// fetcher->delegate()->OnURLFetchComplete(...); -// // Make sure consumer of URLFetcher does the right thing. -// ... -// -// Note: if you don't know when your request objects will be created you -// might want to use the FakeURLFetcher and FakeURLFetcherFactory classes -// below. - -class TestURLFetcherFactory; -class TestURLFetcher : public URLFetcher { - public: - // Interface for tests to intercept production code classes using URLFetcher. - // Allows even-driven mock server classes to analyze the correctness of - // requests / uploads events and forge responses back at the right moment. - class DelegateForTests { - public: - // Callback issued correspondingly to the call to the |Start()| method. - virtual void OnRequestStart(int fetcher_id) = 0; - - // Callback issued correspondingly to the call to |AppendChunkToUpload|. - // Uploaded chunks can be retrieved with the |upload_chunks()| getter. - virtual void OnChunkUpload(int fetcher_id) = 0; - - // Callback issued correspondingly to the destructor. - virtual void OnRequestEnd(int fetcher_id) = 0; - }; - - TestURLFetcher(int id, - const GURL& url, - URLFetcherDelegate* d); - - TestURLFetcher(const TestURLFetcher&) = delete; - TestURLFetcher& operator=(const TestURLFetcher&) = delete; - - ~TestURLFetcher() override; - - // URLFetcher implementation - void SetUploadData(const std::string& upload_content_type, - const std::string& upload_content) override; - void SetUploadFilePath( - const std::string& upload_content_type, - const base::FilePath& file_path, - uint64_t range_offset, - uint64_t range_length, - scoped_refptr<base::TaskRunner> file_task_runner) override; - void SetUploadStreamFactory( - const std::string& upload_content_type, - const CreateUploadStreamCallback& callback) override; - void SetChunkedUpload(const std::string& upload_content_type) override; - // Overriden to cache the chunks uploaded. Caller can read back the uploaded - // chunks with the upload_chunks() accessor. - void AppendChunkToUpload(const std::string& data, - bool is_last_chunk) override; - void SetLoadFlags(int load_flags) override; - int GetLoadFlags() const override; - void SetAllowCredentials(bool allow_credentials) override {} - void SetReferrer(const std::string& referrer) override; - void SetReferrerPolicy(ReferrerPolicy referrer_policy) override; - void ClearExtraRequestHeaders() override; - void AddExtraRequestHeader(const std::string& name, - const std::string& value) override; - void SetRequestContext( - URLRequestContextGetter* request_context_getter) override; - void SetInitiator(const absl::optional<url::Origin>& initiator) override; - void SetURLRequestUserData( - const void* key, - const CreateDataCallback& create_data_callback) override; - void SetStopOnRedirect(bool stop_on_redirect) override; - void SetAutomaticallyRetryOn5xx(bool retry) override; - void SetMaxRetriesOn5xx(int max_retries) override; - int GetMaxRetriesOn5xx() const override; - base::TimeDelta GetBackoffDelay() const override; - void SetAutomaticallyRetryOnNetworkChanges(int max_retries) override; - void SaveResponseToFileAtPath( - const base::FilePath& file_path, - scoped_refptr<base::SequencedTaskRunner> file_task_runner) override; - void SaveResponseToTemporaryFile( - scoped_refptr<base::SequencedTaskRunner> file_task_runner) override; - void SaveResponseWithWriter( - std::unique_ptr<URLFetcherResponseWriter> response_writer) override; - HttpResponseHeaders* GetResponseHeaders() const override; - IPEndPoint GetSocketAddress() const override; - const ProxyServer& ProxyServerUsed() const override; - bool WasCached() const override; - // Only valid when the response was set via SetResponseString(). - int64_t GetReceivedResponseContentLength() const override; - // Only valid when the response was set via SetResponseString(), or - // set_was_cached(true) was called. - int64_t GetTotalReceivedBytes() const override; - void Start() override; - - // URL we were created with. Because of how we're using URLFetcher GetURL() - // always returns an empty URL. Chances are you'll want to use - // GetOriginalURL() in your tests. - const GURL& GetOriginalURL() const override; - const GURL& GetURL() const override; - Error GetError() const override; - int GetResponseCode() const override; - void ReceivedContentWasMalformed() override; - // Override response access functions to return fake data. - bool GetResponseAsString(std::string* out_response_string) const override; - bool GetResponseAsFilePath(bool take_ownership, - base::FilePath* out_response_path) const override; - - void GetExtraRequestHeaders(HttpRequestHeaders* headers) const; - - // Unique ID in our factory. - int id() const { return id_; } - - // Returns the data uploaded on this URLFetcher. - const std::string& upload_content_type() const { - return upload_content_type_; - } - const std::string& upload_data() const { return upload_data_; } - const base::FilePath& upload_file_path() const { return upload_file_path_; } - - // Returns the chunks of data uploaded on this URLFetcher. - const std::list<std::string>& upload_chunks() const { return chunks_; } - - // Checks whether the last call to |AppendChunkToUpload(...)| was final. - bool did_receive_last_chunk() const { return did_receive_last_chunk_; } - - // Returns the delegate installed on the URLFetcher. - URLFetcherDelegate* delegate() const { return delegate_; } - - void set_url(const GURL& url) { fake_url_ = url; } - void set_error(Error error) { fake_error_ = error; } - void set_response_code(int response_code) { - fake_response_code_ = response_code; - } - void set_was_cached(bool flag); - void set_response_headers(scoped_refptr<HttpResponseHeaders> headers); - void SetDelegateForTests(DelegateForTests* delegate_for_tests); - - // Set string data. - void SetResponseString(const std::string& response); - - // Set File data. - void SetResponseFilePath(const base::FilePath& path); - - private: - enum ResponseDestinationType { - STRING, // Default: In a std::string - TEMP_FILE // Write to a temp file - }; - - const int id_; - const GURL original_url_; - raw_ptr<URLFetcherDelegate> delegate_; - raw_ptr<DelegateForTests> delegate_for_tests_ = nullptr; - std::string upload_content_type_; - std::string upload_data_; - base::FilePath upload_file_path_; - std::list<std::string> chunks_; - bool did_receive_last_chunk_ = false; - - // User can use set_* methods to provide values returned by getters. - // Setting the real values is not possible, because the real class - // has no setters. The data is a private member of a class defined - // in a .cc file, so we can't get at it with friendship. - int fake_load_flags_ = 0; - GURL fake_url_; - Error fake_error_; - int fake_response_code_ = -1; - ResponseDestinationType fake_response_destination_ = STRING; - std::string fake_response_string_; - base::FilePath fake_response_file_path_; - bool write_response_file_ = false; - ProxyServer fake_proxy_server_; - bool fake_was_cached_ = false; - int64_t fake_response_bytes_ = 0; - scoped_refptr<HttpResponseHeaders> fake_response_headers_; - HttpRequestHeaders fake_extra_request_headers_; - int fake_max_retries_ = 0; - std::unique_ptr<URLFetcherResponseWriter> response_writer_; -}; - -// The FakeURLFetcher and FakeURLFetcherFactory classes are similar to the -// ones above but don't require you to know when exactly the URLFetcher objects -// will be created. -// -// These classes let you set pre-baked HTTP responses for particular URLs. -// E.g., if the user requests http://a.com/ then respond with an HTTP/500. -// -// We assume that the thread that is calling Start() on the URLFetcher object -// has a message loop running. - -// FakeURLFetcher can be used to create a URLFetcher that will emit a fake -// response when started. This class can be used in place of an actual -// URLFetcher. -// -// Example usage: -// FakeURLFetcher fake_fetcher("http://a.com", some_delegate, -// "<html><body>hello world</body></html>", -// HTTP_OK); -// -// // Will schedule a call to some_delegate->OnURLFetchComplete(&fake_fetcher). -// fake_fetcher.Start(); -class FakeURLFetcher : public TestURLFetcher { - public: - // Normal URL fetcher constructor but also takes in a pre-baked response. - FakeURLFetcher(const GURL& url, - URLFetcherDelegate* d, - const std::string& response_data, - HttpStatusCode response_code, - Error error); - - // Start the request. This will call the given delegate asynchronously - // with the pre-baked response as parameter. - void Start() override; - - const GURL& GetURL() const override; - - FakeURLFetcher(const FakeURLFetcher&) = delete; - FakeURLFetcher& operator=(const FakeURLFetcher&) = delete; - - ~FakeURLFetcher() override; - - private: - // This is the method which actually calls the delegate that is passed in the - // constructor. - void RunDelegate(); - - int64_t response_bytes_; - base::WeakPtrFactory<FakeURLFetcher> weak_factory_{this}; -}; - -// FakeURLFetcherFactory is a factory for FakeURLFetcher objects. When -// instantiated, it sets itself up as the default URLFetcherFactory. Fake -// responses for given URLs can be set using SetFakeResponse. -// -// This class is not thread-safe. You should not call SetFakeResponse or -// ClearFakeResponse at the same time you call CreateURLFetcher. However, it is -// OK to start URLFetcher objects while setting or clearing fake responses -// since already created URLFetcher objects will not be affected by any changes -// made to the fake responses (once a URLFetcher object is created you cannot -// change its fake response). -// -// Example usage: -// FakeURLFetcherFactory factory; -// -// // You know that class SomeService will request http://a.com/success and you -// // want to respond with a simple html page and an HTTP/200 code. -// factory.SetFakeResponse("http://a.com/success", -// "<html><body>hello world</body></html>", -// HTTP_OK, -// OK); -// // You know that class SomeService will request url http://a.com/servererror -// // and you want to test the service class by returning a server error. -// factory.SetFakeResponse("http://a.com/servererror", -// "", -// HTTP_INTERNAL_SERVER_ERROR, -// OK); -// // You know that class SomeService will request url http://a.com/autherror -// // and you want to test the service class by returning a specific error -// // code, say, a HTTP/401 error. -// factory.SetFakeResponse("http://a.com/autherror", -// "some_response", -// HTTP_UNAUTHORIZED, -// OK); -// -// // You know that class SomeService will request url http://a.com/failure -// // and you want to test the service class by returning a failure in the -// // network layer. -// factory.SetFakeResponse("http://a.com/failure", -// "", -// HTTP_INTERNAL_SERVER_ERROR, -// ERR_FAILED); -// -// SomeService service; -// service.Run(); // Will eventually request these three URLs. -class FakeURLFetcherFactory : public URLFetcherFactory, - public ScopedURLFetcherFactory { - public: - // Parameters to FakeURLFetcherCreator: url, delegate, response_data, - // response_code - // |url| URL for instantiated FakeURLFetcher - // |delegate| Delegate for FakeURLFetcher - // |response_data| response data for FakeURLFetcher - // |response_code| response code for FakeURLFetcher - // |error| URL fetch error for FakeURLFetcher - // These arguments should by default be used in instantiating FakeURLFetcher - // like so: - // new FakeURLFetcher(url, delegate, response_data, response_code, error) - typedef base::RepeatingCallback<std::unique_ptr<FakeURLFetcher>( - const GURL&, - URLFetcherDelegate*, - const std::string&, - HttpStatusCode, - Error)> - FakeURLFetcherCreator; - - // |default_factory|, which can be NULL, is a URLFetcherFactory that - // will be used to construct a URLFetcher in case the URL being created - // has no pre-baked response. If it is NULL, a URLFetcherImpl will be - // created in this case. - explicit FakeURLFetcherFactory(URLFetcherFactory* default_factory); - - // |default_factory|, which can be NULL, is a URLFetcherFactory that - // will be used to construct a URLFetcher in case the URL being created - // has no pre-baked response. If it is NULL, a URLFetcherImpl will be - // created in this case. - // |creator| is a callback that returns will be called to create a - // FakeURLFetcher if a response is found to a given URL. It can be - // set to MakeFakeURLFetcher. - FakeURLFetcherFactory(URLFetcherFactory* default_factory, - const FakeURLFetcherCreator& creator); - - FakeURLFetcherFactory(const FakeURLFetcherFactory&) = delete; - FakeURLFetcherFactory& operator=(const FakeURLFetcherFactory&) = delete; - - ~FakeURLFetcherFactory() override; - - // If no fake response is set for the given URL this method will delegate the - // call to |default_factory_| if it is not NULL, or return NULL if it is - // NULL. - // Otherwise, it will return a URLFetcher object which will respond with the - // pre-baked response that the client has set by calling SetFakeResponse(). - std::unique_ptr<URLFetcher> CreateURLFetcher( - int id, - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - NetworkTrafficAnnotationTag traffic_annotation) override; - - // Sets the fake response for a given URL. The |response_data| may be empty. - // The |response_code| may be any HttpStatusCode. For instance, HTTP_OK will - // return an HTTP/200 and HTTP_INTERNAL_SERVER_ERROR will return an HTTP/500. - // The |error| argument may be any Error value. Typically, requests that - // return a valid HttpStatusCode have the OK error, while requests that - // indicate a failure to connect to the server have the ERR_FAILED error. - void SetFakeResponse(const GURL& url, - const std::string& response_data, - HttpStatusCode response_code, - Error error); - - // Clear all the fake responses that were previously set via - // SetFakeResponse(). - void ClearFakeResponses(); - - private: - struct FakeURLResponse { - std::string response_data; - HttpStatusCode response_code; - Error error; - }; - typedef std::map<GURL, FakeURLResponse> FakeResponseMap; - - const FakeURLFetcherCreator creator_; - FakeResponseMap fake_responses_; - const raw_ptr<URLFetcherFactory> default_factory_; - - static std::unique_ptr<FakeURLFetcher> DefaultFakeURLFetcherCreator( - const GURL& url, - URLFetcherDelegate* delegate, - const std::string& response_data, - HttpStatusCode response_code, - Error error); -}; - -} // namespace net - -#endif // NET_URL_REQUEST_TEST_URL_FETCHER_FACTORY_H_ diff --git a/chromium/net/url_request/url_fetcher.cc b/chromium/net/url_request/url_fetcher.cc deleted file mode 100644 index 7057dc89623..00000000000 --- a/chromium/net/url_request/url_fetcher.cc +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2012 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 "net/url_request/url_fetcher.h" - -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "net/url_request/url_fetcher_factory.h" -#include "net/url_request/url_fetcher_impl.h" - -namespace net { - -URLFetcher::~URLFetcher() = default; - -// static -void URLFetcher::CancelAll() { - URLFetcherImpl::CancelAll(); -} - -// static -void URLFetcher::SetIgnoreCertificateRequests(bool ignored) { - URLFetcherImpl::SetIgnoreCertificateRequests(ignored); -} - -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if !BUILDFLAG(IS_WIN) && \ - !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) -// static -std::unique_ptr<URLFetcher> URLFetcher::Create( - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d) { - return URLFetcher::Create(0, url, request_type, d); -} - -// static -std::unique_ptr<URLFetcher> URLFetcher::Create( - int id, - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d) { - return Create(id, url, request_type, d, MISSING_TRAFFIC_ANNOTATION); -} -#endif - -// static -std::unique_ptr<URLFetcher> URLFetcher::Create( - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - NetworkTrafficAnnotationTag traffic_annotation) { - return URLFetcher::Create(0, url, request_type, d, traffic_annotation); -} - -// static -std::unique_ptr<URLFetcher> URLFetcher::Create( - int id, - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - NetworkTrafficAnnotationTag traffic_annotation) { - URLFetcherFactory* factory = URLFetcherImpl::factory(); - return factory ? factory->CreateURLFetcher(id, url, request_type, d, - traffic_annotation) - : std::unique_ptr<URLFetcher>(new URLFetcherImpl( - url, request_type, d, traffic_annotation)); -} - -} // namespace net diff --git a/chromium/net/url_request/url_fetcher.h b/chromium/net/url_request/url_fetcher.h deleted file mode 100644 index f9c7120cc8e..00000000000 --- a/chromium/net/url_request/url_fetcher.h +++ /dev/null @@ -1,401 +0,0 @@ -// Copyright (c) 2012 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 NET_URL_REQUEST_URL_FETCHER_H_ -#define NET_URL_REQUEST_URL_FETCHER_H_ - -#include <stdint.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" -#include "base/supports_user_data.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" -#include "net/base/ip_endpoint.h" -#include "net/base/net_errors.h" -#include "net/base/net_export.h" -#include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/referrer_policy.h" -#include "net/url_request/url_request.h" -#include "third_party/abseil-cpp/absl/types/optional.h" - -class GURL; - -namespace base { -class FilePath; -class SequencedTaskRunner; -class TaskRunner; -class TimeDelta; -} - -namespace url { -class Origin; -} - -namespace remoting { -class GstaticJsonFetcher; -} - -namespace net { -class HttpResponseHeaders; -class URLFetcherDelegate; -class URLFetcherResponseWriter; -class URLRequestContextGetter; - -// NOTE: This class should not be used by content embedders, as it requires an -// in-process network stack. Content embedders should use -// network::SimpleURLLoader instead, which works with both in-process and -// out-of-process network stacks. -// -// To use this class, create an instance with the desired URL and a pointer to -// the object to be notified when the URL has been loaded: -// std::unique_ptr<URLFetcher> fetcher = -// URLFetcher::Create(GURL("http://www.google.com"), -// URLFetcher::GET, -// this); -// -// You must also set a request context getter: -// -// fetcher->SetRequestContext(&my_request_context_getter); -// -// Then, optionally set properties on this object, like the request context or -// extra headers: -// fetcher->AddExtraRequestHeader("X-Foo: bar"); -// -// Finally, start the request: -// fetcher->Start(); -// -// You may cancel the request by destroying the URLFetcher: -// fetcher.reset(); -// -// The object you supply as a delegate must inherit from URLFetcherDelegate. -// When the fetch is completed, OnURLFetchComplete() will be called with a -// pointer to the URLFetcher. From that point until the original URLFetcher -// instance is destroyed, you may use accessor methods to see the result of the -// fetch. You should copy these objects if you need them to live longer than -// the URLFetcher instance. If the URLFetcher instance is destroyed before the -// callback happens, the fetch will be canceled and no callback will occur. -// -// You may create the URLFetcher instance on any sequence; OnURLFetchComplete() -// will be called back on the same sequence you use to create the instance. -// -// -// NOTE: By default URLFetcher requests are NOT intercepted, except when -// interception is explicitly enabled in tests. -class NET_EXPORT URLFetcher { - public: - // Imposible http response code. Used to signal that no http response code - // was received. - enum ResponseCode { - RESPONSE_CODE_INVALID = -1 - }; - - enum RequestType { - GET, - POST, - HEAD, - DELETE_REQUEST, // DELETE is already taken on Windows. - // <winnt.h> defines a DELETE macro. - PUT, - PATCH, - }; - - // Used by SetURLRequestUserData. The callback should make a fresh - // base::SupportsUserData::Data object every time it's called. - typedef base::RepeatingCallback< - std::unique_ptr<base::SupportsUserData::Data>()> - CreateDataCallback; - - // Used by SetUploadStreamFactory. The callback should assign a fresh upload - // data stream every time it's called. - typedef base::RepeatingCallback<std::unique_ptr<UploadDataStream>()> - CreateUploadStreamCallback; - - virtual ~URLFetcher(); - - // Cancels all existing URLFetchers. Will notify the URLFetcherDelegates. - // Note that any new URLFetchers created while this is running will not be - // cancelled. Typically, one would call this in the CleanUp() method of an IO - // thread, so that no new URLRequests would be able to start on the IO thread - // anyway. This doesn't prevent new URLFetchers from trying to post to the IO - // thread though, even though the task won't ever run. - static void CancelAll(); - - // Normally, URLFetcher will abort loads that request SSL client certificate - // authentication, but this method may be used to cause URLFetchers to ignore - // requests for client certificates and continue anonymously. Because such - // behaviour affects the URLRequestContext's shared network state and socket - // pools, it should only be used for testing. - static void SetIgnoreCertificateRequests(bool ignored); - - // Sets data only needed by POSTs. All callers making POST requests should - // call one of the SetUpload* methods before the request is started. - // |upload_content_type| is the MIME type of the content, while - // |upload_content| is the data to be sent (the Content-Length header value - // will be set to the length of this data). - virtual void SetUploadData(const std::string& upload_content_type, - const std::string& upload_content) = 0; - - // Sets data only needed by POSTs. All callers making POST requests should - // call one of the SetUpload* methods before the request is started. - // |upload_content_type| is the MIME type of the content, while - // |file_path| is the path to the file containing the data to be sent (the - // Content-Length header value will be set to the length of this file). - // |range_offset| and |range_length| specify the range of the part - // to be uploaded. To upload the whole file, (0, kuint64max) can be used. - // |file_task_runner| will be used for all file operations. - virtual void SetUploadFilePath( - const std::string& upload_content_type, - const base::FilePath& file_path, - uint64_t range_offset, - uint64_t range_length, - scoped_refptr<base::TaskRunner> file_task_runner) = 0; - - // Sets data only needed by POSTs. All callers making POST requests should - // call one of the SetUpload* methods before the request is started. - // |upload_content_type| is the MIME type of the content, while |callback| is - // the callback to create the upload data stream (the Content-Length header - // value will be set to the length of this data). |callback| may be called - // mutliple times if the request is retried. - virtual void SetUploadStreamFactory( - const std::string& upload_content_type, - const CreateUploadStreamCallback& callback) = 0; - - // Indicates that the POST data is sent via chunked transfer encoding. - // This may only be called before calling Start(). - // Use AppendChunkToUpload() to give the data chunks after calling Start(). - virtual void SetChunkedUpload(const std::string& upload_content_type) = 0; - - // Adds the given bytes to a request's POST data transmitted using chunked - // transfer encoding. - // This method should be called ONLY after calling Start(). - virtual void AppendChunkToUpload(const std::string& data, - bool is_last_chunk) = 0; - - // Set one or more load flags as defined in net/base/load_flags.h. Must be - // called before the request is started. - virtual void SetLoadFlags(int load_flags) = 0; - - // Set whether credentials should be included on the request. Must be called - // before the request is started. - virtual void SetAllowCredentials(bool allow_credentials) = 0; - - // Returns the current load flags. - virtual int GetLoadFlags() const = 0; - - // The referrer URL for the request. Must be called before the request is - // started. - virtual void SetReferrer(const std::string& referrer) = 0; - - // The referrer policy to apply when updating the referrer during redirects. - // The referrer policy may only be changed before Start() is called. - virtual void SetReferrerPolicy(ReferrerPolicy referrer_policy) = 0; - - // Clear all extra headers on the request (if any have been set before). - // Must be called before the request is started. - virtual void ClearExtraRequestHeaders() = 0; - - // Add an extra header to the request headers. Must be called before the - // request is started. - // This appends the header to the current extra request headers. - virtual void AddExtraRequestHeader(const std::string& name, - const std::string& value) = 0; - - // Set the URLRequestContext on the request. Must be called before the - // request is started. - virtual void SetRequestContext( - URLRequestContextGetter* request_context_getter) = 0; - - // Set the origin that should be considered as "initiating" the fetch. This - // URL will be considered the "first-party" when applying cookie blocking - // policy to requests, and treated as the request's initiator. - virtual void SetInitiator(const absl::optional<url::Origin>& initiator) = 0; - - // Set the key and data callback that is used when setting the user - // data on any URLRequest objects this object creates. - virtual void SetURLRequestUserData( - const void* key, - const CreateDataCallback& create_data_callback) = 0; - - // If |stop_on_redirect| is true, 3xx responses will cause the fetch to halt - // immediately rather than continue through the redirect. OnURLFetchComplete - // will be called, with the URLFetcher's URL set to the redirect destination, - // its status set to CANCELED, and its response code set to the relevant 3xx - // server response code. - virtual void SetStopOnRedirect(bool stop_on_redirect) = 0; - - // If |retry| is false, 5xx responses will be propagated to the observer. If - // it is true URLFetcher will automatically re-execute the request, after - // backoff_delay() elapses, up to the maximum number of retries allowed by - // SetMaxRetriesOn5xx. Defaults to true. - virtual void SetAutomaticallyRetryOn5xx(bool retry) = 0; - - // |max_retries| is the maximum number of times URLFetcher will retry a - // request that receives a 5XX response. Depends on - // SetAutomaticallyRetryOn5xx. Defaults to 0. - virtual void SetMaxRetriesOn5xx(int max_retries) = 0; - virtual int GetMaxRetriesOn5xx() const = 0; - - // Returns the back-off delay before the request will be retried, - // when a 5xx response was received. - virtual base::TimeDelta GetBackoffDelay() const = 0; - - // Retries up to |max_retries| times when requests fail with - // ERR_NETWORK_CHANGED. If ERR_NETWORK_CHANGED is received after having - // retried |max_retries| times then it is propagated to the observer. - virtual void SetAutomaticallyRetryOnNetworkChanges(int max_retries) = 0; - - // By default, the response is saved in a string. Call this method to save the - // response to a file instead. Must be called before Start(). - // |file_task_runner| will be used for all file operations. - // To save to a temporary file, use SaveResponseToTemporaryFile(). - // The created file is removed when the URLFetcher is deleted unless you - // take ownership by calling GetResponseAsFilePath(). - virtual void SaveResponseToFileAtPath( - const base::FilePath& file_path, - scoped_refptr<base::SequencedTaskRunner> file_task_runner) = 0; - - // By default, the response is saved in a string. Call this method to save the - // response to a temporary file instead. Must be called before Start(). - // |file_task_runner| will be used for all file operations. - // The created file is removed when the URLFetcher is deleted unless you - // take ownership by calling GetResponseAsFilePath(). - virtual void SaveResponseToTemporaryFile( - scoped_refptr<base::SequencedTaskRunner> file_task_runner) = 0; - - // By default, the response is saved in a string. Call this method to use the - // specified writer to save the response. Must be called before Start(). - virtual void SaveResponseWithWriter( - std::unique_ptr<URLFetcherResponseWriter> response_writer) = 0; - - // Retrieve the response headers from the request. Must only be called after - // the OnURLFetchComplete callback has run. - virtual HttpResponseHeaders* GetResponseHeaders() const = 0; - - // Retrieve the remote socket address from the request. Must only - // be called after the OnURLFetchComplete callback has run and if - // the request has not failed. - virtual IPEndPoint GetSocketAddress() const = 0; - - // Returns the proxy server that proxied the request. Must only be called - // after the OnURLFetchComplete callback has run and the request has not - // failed. - virtual const ProxyServer& ProxyServerUsed() const = 0; - - // Returns true if the response body was served from the cache. This includes - // responses for which revalidation was required. - virtual bool WasCached() const = 0; - - // The number of bytes in the raw response body (before response filters are - // applied, to decompress it, for instance). - virtual int64_t GetReceivedResponseContentLength() const = 0; - - // The number of bytes received over the network during the processing of this - // request. This includes redirect headers, but not redirect bodies. It also - // excludes SSL and proxy handshakes. - virtual int64_t GetTotalReceivedBytes() const = 0; - - // Start the request. After this is called, you may not change any other - // settings. - virtual void Start() = 0; - - // Return the URL that we were asked to fetch. - virtual const GURL& GetOriginalURL() const = 0; - - // Return the URL that this fetcher is processing. - virtual const GURL& GetURL() const = 0; - - // The error from the URL fetch. - virtual Error GetError() const = 0; - - // The http response code received. Will return RESPONSE_CODE_INVALID - // if an error prevented any response from being received. - virtual int GetResponseCode() const = 0; - - // Reports that the received content was malformed. - virtual void ReceivedContentWasMalformed() = 0; - - // Get the response as a string. Return false if the fetcher was not - // set to store the response as a string. - virtual bool GetResponseAsString(std::string* out_response_string) const = 0; - - // Get the path to the file containing the response body. Returns false - // if the response body was not saved to a file. If take_ownership is - // true, caller takes responsibility for the file, and it will not - // be removed once the URLFetcher is destroyed. User should not take - // ownership more than once, or call this method after taking ownership. - virtual bool GetResponseAsFilePath( - bool take_ownership, - base::FilePath* out_response_path) const = 0; - - private: - // This class is deprecated, and no new code should be using it. Construction - // methods are private and pre-existing consumers are friended. - friend class remoting::GstaticJsonFetcher; - - // The unannotated Create() methods are not available on desktop Linux + - // Windows. They are available on other platforms, since we only audit network - // annotations on Linux & Windows. -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if (!BUILDFLAG(IS_WIN) && \ - !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))) || \ - BUILDFLAG(IS_CHROMEOS) - // |url| is the URL to send the request to. It must be valid. - // |request_type| is the type of request to make. - // |d| the object that will receive the callback on fetch completion. - // This function should not be used in Chromium, please use the version with - // NetworkTrafficAnnotationTag below instead. - static std::unique_ptr<URLFetcher> Create( - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d); - - // Like above, but if there's a URLFetcherFactory registered with the - // implementation it will be used. |id| may be used during testing to identify - // who is creating the URLFetcher. - // This function should not be used in Chromium, please use the version with - // NetworkTrafficAnnotationTag below instead. - static std::unique_ptr<URLFetcher> Create( - int id, - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d); -#endif - - // |url| is the URL to send the request to. It must be valid. - // |request_type| is the type of request to make. - // |d| the object that will receive the callback on fetch completion. - // |traffic_annotation| metadata about the network traffic send via this - // URLFetcher, see net::DefineNetworkTrafficAnnotation. Note that: - // - net provides the API for tagging requests with an opaque identifier. - // - chrome/browser/privacy/traffic_annotation.proto contains the Chrome - // specific .proto describing the verbose annotation format that Chrome's - // callsites are expected to follow. - // - tools/traffic_annotation/ contains sample and template for annotation and - // tools will be added for verification following crbug.com/690323. - static std::unique_ptr<URLFetcher> Create( - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - NetworkTrafficAnnotationTag traffic_annotation); - - // Like above, but if there's a URLFetcherFactory registered with the - // implementation it will be used. |id| may be used during testing to identify - // who is creating the URLFetcher. - static std::unique_ptr<URLFetcher> Create( - int id, - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - NetworkTrafficAnnotationTag traffic_annotation); -}; - -} // namespace net - -#endif // NET_URL_REQUEST_URL_FETCHER_H_ diff --git a/chromium/net/url_request/url_fetcher_core.cc b/chromium/net/url_request/url_fetcher_core.cc deleted file mode 100644 index 05fd10cbce3..00000000000 --- a/chromium/net/url_request/url_fetcher_core.cc +++ /dev/null @@ -1,932 +0,0 @@ -// Copyright (c) 2012 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 "net/url_request/url_fetcher_core.h" - -#include <stdint.h> -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/callback_helpers.h" -#include "base/check_op.h" -#include "base/containers/contains.h" -#include "base/notreached.h" -#include "base/stl_util.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/single_thread_task_runner.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "net/base/elements_upload_data_stream.h" -#include "net/base/io_buffer.h" -#include "net/base/load_flags.h" -#include "net/base/net_errors.h" -#include "net/base/request_priority.h" -#include "net/base/upload_bytes_element_reader.h" -#include "net/base/upload_data_stream.h" -#include "net/base/upload_file_element_reader.h" -#include "net/cert/x509_certificate.h" -#include "net/http/http_response_headers.h" -#include "net/ssl/ssl_private_key.h" -#include "net/url_request/redirect_info.h" -#include "net/url_request/url_fetcher_delegate.h" -#include "net/url_request/url_fetcher_response_writer.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" -#include "net/url_request/url_request_throttler_manager.h" -#include "url/origin.h" - -namespace { - -const int kBufferSize = 4096; -const int kUploadProgressTimerInterval = 100; -bool g_ignore_certificate_requests = false; - -} // namespace - -namespace net { - -// URLFetcherCore::Registry --------------------------------------------------- - -URLFetcherCore::Registry::Registry() = default; -URLFetcherCore::Registry::~Registry() = default; - -void URLFetcherCore::Registry::AddURLFetcherCore(URLFetcherCore* core) { - DCHECK(!base::Contains(fetchers_, core)); - fetchers_.insert(core); -} - -void URLFetcherCore::Registry::RemoveURLFetcherCore(URLFetcherCore* core) { - DCHECK(base::Contains(fetchers_, core)); - fetchers_.erase(core); -} - -void URLFetcherCore::Registry::CancelAll() { - while (!fetchers_.empty()) - (*fetchers_.begin())->CancelURLRequest(ERR_ABORTED); -} - -// URLFetcherCore ------------------------------------------------------------- - -// static -base::LazyInstance<URLFetcherCore::Registry>::DestructorAtExit - URLFetcherCore::g_registry = LAZY_INSTANCE_INITIALIZER; - -URLFetcherCore::URLFetcherCore( - URLFetcher* fetcher, - const GURL& original_url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - net::NetworkTrafficAnnotationTag traffic_annotation) - : fetcher_(fetcher), - original_url_(original_url), - request_type_(request_type), - delegate_(d), - delegate_task_runner_(base::SequencedTaskRunnerHandle::Get()), - allow_credentials_(absl::nullopt), - traffic_annotation_(traffic_annotation) { - CHECK(original_url_.is_valid()); -} - -void URLFetcherCore::Start() { - DCHECK(delegate_task_runner_); - DCHECK(request_context_getter_.get()) << "We need an URLRequestContext!"; - if (network_task_runner_.get()) { - DCHECK_EQ(network_task_runner_, - request_context_getter_->GetNetworkTaskRunner()); - } else { - network_task_runner_ = request_context_getter_->GetNetworkTaskRunner(); - } - DCHECK(network_task_runner_.get()) << "We need an IO task runner"; - - network_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&URLFetcherCore::StartOnIOThread, this)); -} - -void URLFetcherCore::Stop() { - if (delegate_task_runner_) // May be NULL in tests. - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - - delegate_ = nullptr; - fetcher_ = nullptr; - if (!network_task_runner_.get()) - return; - if (network_task_runner_->RunsTasksInCurrentSequence()) { - CancelURLRequest(ERR_ABORTED); - } else { - network_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&URLFetcherCore::CancelURLRequest, this, ERR_ABORTED)); - } -} - -void URLFetcherCore::SetUploadData(const std::string& upload_content_type, - const std::string& upload_content) { - AssertHasNoUploadData(); - DCHECK(!is_chunked_upload_); - DCHECK(upload_content_type_.empty()); - - // Empty |upload_content_type| is allowed iff the |upload_content| is empty. - DCHECK(upload_content.empty() || !upload_content_type.empty()); - - upload_content_type_ = upload_content_type; - upload_content_ = upload_content; - upload_content_set_ = true; -} - -void URLFetcherCore::SetUploadFilePath( - const std::string& upload_content_type, - const base::FilePath& file_path, - uint64_t range_offset, - uint64_t range_length, - scoped_refptr<base::TaskRunner> file_task_runner) { - AssertHasNoUploadData(); - DCHECK(!is_chunked_upload_); - DCHECK_EQ(upload_range_offset_, 0ULL); - DCHECK_EQ(upload_range_length_, 0ULL); - DCHECK(upload_content_type_.empty()); - DCHECK(!upload_content_type.empty()); - - upload_content_type_ = upload_content_type; - upload_file_path_ = file_path; - upload_range_offset_ = range_offset; - upload_range_length_ = range_length; - upload_file_task_runner_ = file_task_runner; - upload_content_set_ = true; -} - -void URLFetcherCore::SetUploadStreamFactory( - const std::string& upload_content_type, - const URLFetcher::CreateUploadStreamCallback& factory) { - AssertHasNoUploadData(); - DCHECK(!is_chunked_upload_); - DCHECK(upload_content_type_.empty()); - - upload_content_type_ = upload_content_type; - upload_stream_factory_ = factory; - upload_content_set_ = true; -} - -void URLFetcherCore::SetChunkedUpload(const std::string& content_type) { - if (!is_chunked_upload_) { - AssertHasNoUploadData(); - DCHECK(upload_content_type_.empty()); - } - - // Empty |content_type| is not allowed here, because it is impossible - // to ensure non-empty upload content as it is not yet supplied. - DCHECK(!content_type.empty()); - - upload_content_type_ = content_type; - base::STLClearObject(&upload_content_); - is_chunked_upload_ = true; -} - -void URLFetcherCore::AppendChunkToUpload(const std::string& content, - bool is_last_chunk) { - DCHECK(delegate_task_runner_); - DCHECK(network_task_runner_.get()); - DCHECK(is_chunked_upload_); - network_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&URLFetcherCore::CompleteAddingUploadDataChunk, - this, content, is_last_chunk)); -} - -void URLFetcherCore::SetLoadFlags(int load_flags) { - load_flags_ = load_flags; -} - -void URLFetcherCore::SetAllowCredentials(bool allow_credentials) { - allow_credentials_ = absl::make_optional<bool>(allow_credentials); -} - -int URLFetcherCore::GetLoadFlags() const { - return load_flags_; -} - -void URLFetcherCore::SetReferrer(const std::string& referrer) { - referrer_ = referrer; -} - -void URLFetcherCore::SetReferrerPolicy(ReferrerPolicy referrer_policy) { - referrer_policy_ = referrer_policy; -} - -void URLFetcherCore::ClearExtraRequestHeaders() { - extra_request_headers_.Clear(); -} - -void URLFetcherCore::AddExtraRequestHeader(const std::string& name, - const std::string& value) { - extra_request_headers_.SetHeader(name, value); -} - -void URLFetcherCore::SetRequestContext( - URLRequestContextGetter* request_context_getter) { - DCHECK(!request_context_getter_.get()); - DCHECK(request_context_getter); - request_context_getter_ = request_context_getter; -} - -void URLFetcherCore::SetInitiator( - const absl::optional<url::Origin>& initiator) { - DCHECK(!initiator_.has_value()); - initiator_ = initiator; -} - -void URLFetcherCore::SetURLRequestUserData( - const void* key, - const URLFetcher::CreateDataCallback& create_data_callback) { - DCHECK(key); - DCHECK(!create_data_callback.is_null()); - url_request_data_key_ = key; - url_request_create_data_callback_ = create_data_callback; -} - -void URLFetcherCore::SetStopOnRedirect(bool stop_on_redirect) { - stop_on_redirect_ = stop_on_redirect; -} - -void URLFetcherCore::SetAutomaticallyRetryOn5xx(bool retry) { - automatically_retry_on_5xx_ = retry; -} - -void URLFetcherCore::SetMaxRetriesOn5xx(int max_retries) { - max_retries_on_5xx_ = max_retries; -} - -int URLFetcherCore::GetMaxRetriesOn5xx() const { - return max_retries_on_5xx_; -} - -base::TimeDelta URLFetcherCore::GetBackoffDelay() const { - return backoff_delay_; -} - -void URLFetcherCore::SetAutomaticallyRetryOnNetworkChanges(int max_retries) { - max_retries_on_network_changes_ = max_retries; -} - -void URLFetcherCore::SaveResponseToFileAtPath( - const base::FilePath& file_path, - scoped_refptr<base::SequencedTaskRunner> file_task_runner) { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - SaveResponseWithWriter(std::unique_ptr<URLFetcherResponseWriter>( - new URLFetcherFileWriter(file_task_runner, file_path))); -} - -void URLFetcherCore::SaveResponseToTemporaryFile( - scoped_refptr<base::SequencedTaskRunner> file_task_runner) { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - SaveResponseWithWriter(std::unique_ptr<URLFetcherResponseWriter>( - new URLFetcherFileWriter(file_task_runner, base::FilePath()))); -} - -void URLFetcherCore::SaveResponseWithWriter( - std::unique_ptr<URLFetcherResponseWriter> response_writer) { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - response_writer_ = std::move(response_writer); -} - -HttpResponseHeaders* URLFetcherCore::GetResponseHeaders() const { - return response_headers_.get(); -} - -// TODO(panayiotis): remote_endpoint_ is written in the IO thread, -// if this is accessed in the UI thread, this could result in a race. -// Same for response_headers_ above. -IPEndPoint URLFetcherCore::GetSocketAddress() const { - return remote_endpoint_; -} - -const ProxyServer& URLFetcherCore::ProxyServerUsed() const { - return proxy_server_; -} - -bool URLFetcherCore::WasCached() const { - return was_cached_; -} - -int64_t URLFetcherCore::GetReceivedResponseContentLength() const { - return received_response_content_length_; -} - -int64_t URLFetcherCore::GetTotalReceivedBytes() const { - return total_received_bytes_; -} - -const GURL& URLFetcherCore::GetOriginalURL() const { - return original_url_; -} - -const GURL& URLFetcherCore::GetURL() const { - return url_; -} - -Error URLFetcherCore::GetError() const { - return error_; -} - -int URLFetcherCore::GetResponseCode() const { - return response_code_; -} - -void URLFetcherCore::ReceivedContentWasMalformed() { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - if (network_task_runner_.get()) { - network_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&URLFetcherCore::NotifyMalformedContent, this)); - } -} - -bool URLFetcherCore::GetResponseAsString( - std::string* out_response_string) const { - URLFetcherStringWriter* string_writer = - response_writer_ ? response_writer_->AsStringWriter() : nullptr; - if (!string_writer) - return false; - - *out_response_string = string_writer->data(); - return true; -} - -bool URLFetcherCore::GetResponseAsFilePath(bool take_ownership, - base::FilePath* out_response_path) { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - - URLFetcherFileWriter* file_writer = - response_writer_ ? response_writer_->AsFileWriter() : nullptr; - if (!file_writer) - return false; - - *out_response_path = file_writer->file_path(); - - if (take_ownership) { - // Intentionally calling a file_writer_ method directly without posting - // the task to network_task_runner_. - // - // This is for correctly handling the case when file_writer_->DisownFile() - // is soon followed by URLFetcherCore::Stop(). We have to make sure that - // DisownFile takes effect before Stop deletes file_writer_. - // - // This direct call should be thread-safe, since DisownFile itself does no - // file operation. It just flips the state to be referred in destruction. - file_writer->DisownFile(); - } - return true; -} - -void URLFetcherCore::OnReceivedRedirect(URLRequest* request, - const RedirectInfo& redirect_info, - bool* defer_redirect) { - DCHECK_EQ(request, request_.get()); - DCHECK(network_task_runner_->BelongsToCurrentThread()); - if (stop_on_redirect_) { - stopped_on_redirect_ = true; - url_ = redirect_info.new_url; - response_code_ = request_->GetResponseCode(); - response_headers_ = request_->response_headers(); - proxy_server_ = request_->proxy_server(); - was_cached_ = request_->was_cached(); - total_received_bytes_ += request_->GetTotalReceivedBytes(); - int result = request->Cancel(); - OnReadCompleted(request, result); - } -} - -void URLFetcherCore::OnResponseStarted(URLRequest* request, int net_error) { - DCHECK_EQ(request, request_.get()); - DCHECK(network_task_runner_->BelongsToCurrentThread()); - DCHECK_NE(ERR_IO_PENDING, net_error); - - if (net_error == OK) { - response_code_ = request_->GetResponseCode(); - response_headers_ = request_->response_headers(); - remote_endpoint_ = request_->GetResponseRemoteEndpoint(); - proxy_server_ = request_->proxy_server(); - was_cached_ = request_->was_cached(); - total_response_bytes_ = request_->GetExpectedContentSize(); - } - - DCHECK(!buffer_); - if (request_type_ != URLFetcher::HEAD) - buffer_ = base::MakeRefCounted<IOBuffer>(kBufferSize); - ReadResponse(); -} - -void URLFetcherCore::OnCertificateRequested( - URLRequest* request, - SSLCertRequestInfo* cert_request_info) { - DCHECK_EQ(request, request_.get()); - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (g_ignore_certificate_requests) { - request->ContinueWithCertificate(nullptr, nullptr); - } else { - request->Cancel(); - } -} - -void URLFetcherCore::OnReadCompleted(URLRequest* request, - int bytes_read) { - DCHECK_EQ(request, request_.get()); - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (!stopped_on_redirect_) - url_ = request->url(); - URLRequestThrottlerManager* throttler_manager = - request->context()->throttler_manager(); - if (throttler_manager) - url_throttler_entry_ = throttler_manager->RegisterRequestUrl(url_); - - while (bytes_read > 0) { - current_response_bytes_ += bytes_read; - InformDelegateDownloadProgress(); - - const int result = WriteBuffer( - base::MakeRefCounted<DrainableIOBuffer>(buffer_, bytes_read)); - if (result < 0) { - // Write failed or waiting for write completion. - return; - } - bytes_read = request_->Read(buffer_.get(), kBufferSize); - } - - // See comments re: HEAD requests in ReadResponse(). - if (bytes_read != ERR_IO_PENDING || request_type_ == URLFetcher::HEAD) { - error_ = static_cast<Error>(bytes_read); - received_response_content_length_ = - request_->received_response_content_length(); - total_received_bytes_ += request_->GetTotalReceivedBytes(); - ReleaseRequest(); - - // No more data to write. - const int result = response_writer_->Finish( - bytes_read > 0 ? OK : bytes_read, - base::BindOnce(&URLFetcherCore::DidFinishWriting, this)); - if (result != ERR_IO_PENDING) - DidFinishWriting(result); - } -} - -void URLFetcherCore::OnContextShuttingDown() { - DCHECK(request_); - CancelRequestAndInformDelegate(ERR_CONTEXT_SHUT_DOWN); -} - -void URLFetcherCore::CancelAll() { - g_registry.Get().CancelAll(); -} - -int URLFetcherCore::GetNumFetcherCores() { - return g_registry.Get().size(); -} - -void URLFetcherCore::SetIgnoreCertificateRequests(bool ignored) { - g_ignore_certificate_requests = ignored; -} - -URLFetcherCore::~URLFetcherCore() { - // |request_| should be NULL. If not, it's unsafe to delete it here since we - // may not be on the IO thread. - DCHECK(!request_.get()); -} - -void URLFetcherCore::StartOnIOThread() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - // Create ChunkedUploadDataStream, if needed, so the consumer can start - // appending data. Have to do it here because StartURLRequest() may be called - // asynchonously. - if (is_chunked_upload_) { - chunked_stream_ = std::make_unique<ChunkedUploadDataStream>(0); - chunked_stream_writer_ = chunked_stream_->CreateWriter(); - } - - if (!response_writer_) - response_writer_ = std::make_unique<URLFetcherStringWriter>(); - - const int result = response_writer_->Initialize( - base::BindOnce(&URLFetcherCore::DidInitializeWriter, this)); - if (result != ERR_IO_PENDING) - DidInitializeWriter(result); -} - -void URLFetcherCore::StartURLRequest() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (was_cancelled_) { - // Since StartURLRequest() is posted as a *delayed* task, it may - // run after the URLFetcher was already stopped. - return; - } - - DCHECK(request_context_getter_); - if (!request_context_getter_->GetURLRequestContext()) { - CancelRequestAndInformDelegate(ERR_CONTEXT_SHUT_DOWN); - return; - } - - DCHECK(!request_.get()); - - g_registry.Get().AddURLFetcherCore(this); - current_response_bytes_ = 0; - request_context_getter_->AddObserver(this); - request_ = request_context_getter_->GetURLRequestContext()->CreateRequest( - original_url_, DEFAULT_PRIORITY, this, traffic_annotation_); - int flags = request_->load_flags() | load_flags_; - - // TODO(mmenke): This should really be with the other code to set the upload - // body, below. - if (chunked_stream_) - request_->set_upload(std::move(chunked_stream_)); - - request_->SetLoadFlags(flags); - if (allow_credentials_) { - request_->set_allow_credentials(allow_credentials_.value()); - } - request_->SetReferrer(referrer_); - request_->set_referrer_policy(referrer_policy_); - request_->set_site_for_cookies(SiteForCookies::FromUrl( - initiator_.has_value() && !initiator_.value().opaque() - ? initiator_.value().GetURL() - : original_url_)); - request_->set_initiator(initiator_); - if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) { - request_->SetUserData(url_request_data_key_, - url_request_create_data_callback_.Run()); - } - - switch (request_type_) { - case URLFetcher::GET: - break; - - case URLFetcher::POST: - case URLFetcher::PUT: - case URLFetcher::PATCH: { - // Upload content must be set. - DCHECK(is_chunked_upload_ || upload_content_set_); - - request_->set_method( - request_type_ == URLFetcher::POST ? "POST" : - request_type_ == URLFetcher::PUT ? "PUT" : "PATCH"); - if (!upload_content_type_.empty()) { - extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType, - upload_content_type_); - } - if (!upload_content_.empty()) { - std::unique_ptr<UploadElementReader> reader( - new UploadBytesElementReader(upload_content_.data(), - upload_content_.size())); - request_->set_upload( - ElementsUploadDataStream::CreateWithReader(std::move(reader), 0)); - } else if (!upload_file_path_.empty()) { - std::unique_ptr<UploadElementReader> reader(new UploadFileElementReader( - upload_file_task_runner_.get(), upload_file_path_, - upload_range_offset_, upload_range_length_, base::Time())); - request_->set_upload( - ElementsUploadDataStream::CreateWithReader(std::move(reader), 0)); - } else if (!upload_stream_factory_.is_null()) { - std::unique_ptr<UploadDataStream> stream = upload_stream_factory_.Run(); - DCHECK(stream); - request_->set_upload(std::move(stream)); - } - - current_upload_bytes_ = -1; - // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the - // layer and avoid using timer here. - upload_progress_checker_timer_ = std::make_unique<base::RepeatingTimer>(); - upload_progress_checker_timer_->Start( - FROM_HERE, base::Milliseconds(kUploadProgressTimerInterval), this, - &URLFetcherCore::InformDelegateUploadProgress); - break; - } - - case URLFetcher::HEAD: - request_->set_method("HEAD"); - break; - - case URLFetcher::DELETE_REQUEST: - request_->set_method("DELETE"); - break; - - default: - NOTREACHED(); - } - - if (!extra_request_headers_.IsEmpty()) - request_->SetExtraRequestHeaders(extra_request_headers_); - - request_->Start(); -} - -void URLFetcherCore::DidInitializeWriter(int result) { - if (result != OK) { - CancelRequestAndInformDelegate(result); - return; - } - StartURLRequestWhenAppropriate(); -} - -void URLFetcherCore::StartURLRequestWhenAppropriate() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (was_cancelled_) - return; - - DCHECK(request_context_getter_.get()); - - // Check if the request should be delayed, and if so, post a task to start it - // after the delay has expired. Otherwise, start it now. - - URLRequestContext* context = request_context_getter_->GetURLRequestContext(); - // If the context has been shut down, or there's no ThrottlerManager, just - // start the request. In the former case, StartURLRequest() will just inform - // the URLFetcher::Delegate the request has been canceled. - if (context && context->throttler_manager()) { - if (!original_url_throttler_entry_.get()) { - original_url_throttler_entry_ = - context->throttler_manager()->RegisterRequestUrl(original_url_); - } - - if (original_url_throttler_entry_.get()) { - int64_t delay = - original_url_throttler_entry_->ReserveSendingTimeForNextRequest( - GetBackoffReleaseTime()); - if (delay != 0) { - network_task_runner_->PostDelayedTask( - FROM_HERE, base::BindOnce(&URLFetcherCore::StartURLRequest, this), - base::Milliseconds(delay)); - return; - } - } - } - - StartURLRequest(); -} - -void URLFetcherCore::CancelURLRequest(int error) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (request_.get()) { - request_->CancelWithError(error); - ReleaseRequest(); - } - error_ = static_cast<Error>(error); - - // Release the reference to the request context. There could be multiple - // references to URLFetcher::Core at this point so it may take a while to - // delete the object, but we cannot delay the destruction of the request - // context. - request_context_getter_ = nullptr; - initiator_.reset(); - url_request_data_key_ = nullptr; - url_request_create_data_callback_.Reset(); - was_cancelled_ = true; -} - -void URLFetcherCore::OnCompletedURLRequest( - base::TimeDelta backoff_delay) { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - - // Save the status and backoff_delay so that delegates can read it. - if (delegate_) { - backoff_delay_ = backoff_delay; - InformDelegateFetchIsComplete(); - } -} - -void URLFetcherCore::InformDelegateFetchIsComplete() { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - if (delegate_) - delegate_->OnURLFetchComplete(fetcher_); -} - -void URLFetcherCore::NotifyMalformedContent() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - if (url_throttler_entry_.get()) { - int status_code = response_code_; - if (status_code == URLFetcher::RESPONSE_CODE_INVALID) { - // The status code will generally be known by the time clients - // call the |ReceivedContentWasMalformed()| function (which ends up - // calling the current function) but if it's not, we need to assume - // the response was successful so that the total failure count - // used to calculate exponential back-off goes up. - status_code = 200; - } - url_throttler_entry_->ReceivedContentWasMalformed(status_code); - } -} - -void URLFetcherCore::DidFinishWriting(int result) { - if (result != OK) { - CancelRequestAndInformDelegate(result); - return; - } - // If the file was successfully closed, then the URL request is complete. - RetryOrCompleteUrlFetch(); -} - -void URLFetcherCore::RetryOrCompleteUrlFetch() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - base::TimeDelta backoff_delay; - - // Checks the response from server. - if (response_code_ >= 500 || error_ == ERR_TEMPORARILY_THROTTLED) { - // When encountering a server error, we will send the request again - // after backoff time. - ++num_retries_on_5xx_; - - // Note that backoff_delay may be 0 because (a) the - // URLRequestThrottlerManager and related code does not - // necessarily back off on the first error, (b) it only backs off - // on some of the 5xx status codes, (c) not all URLRequestContexts - // have a throttler manager. - base::TimeTicks backoff_release_time = GetBackoffReleaseTime(); - backoff_delay = backoff_release_time - base::TimeTicks::Now(); - if (backoff_delay.is_negative()) - backoff_delay = base::TimeDelta(); - - if (automatically_retry_on_5xx_ && - num_retries_on_5xx_ <= max_retries_on_5xx_) { - StartOnIOThread(); - return; - } - } else { - backoff_delay = base::TimeDelta(); - } - - // Retry if the request failed due to network changes. - if (error_ == ERR_NETWORK_CHANGED && - num_retries_on_network_changes_ < max_retries_on_network_changes_) { - ++num_retries_on_network_changes_; - - // Retry soon, after flushing all the current tasks which may include - // further network change observers. - network_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&URLFetcherCore::StartOnIOThread, this)); - return; - } - - request_context_getter_ = nullptr; - initiator_.reset(); - url_request_data_key_ = nullptr; - url_request_create_data_callback_.Reset(); - bool posted = delegate_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&URLFetcherCore::OnCompletedURLRequest, this, - backoff_delay)); - - // If the delegate message loop does not exist any more, then the delegate - // should be gone too. - DCHECK(posted || !delegate_); -} - -void URLFetcherCore::CancelRequestAndInformDelegate(int result) { - CancelURLRequest(result); - delegate_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&URLFetcherCore::InformDelegateFetchIsComplete, this)); -} - -void URLFetcherCore::ReleaseRequest() { - request_context_getter_->RemoveObserver(this); - upload_progress_checker_timer_.reset(); - request_.reset(); - buffer_ = nullptr; - g_registry.Get().RemoveURLFetcherCore(this); -} - -base::TimeTicks URLFetcherCore::GetBackoffReleaseTime() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - if (!original_url_throttler_entry_.get()) - return base::TimeTicks(); - - base::TimeTicks original_url_backoff = - original_url_throttler_entry_->GetExponentialBackoffReleaseTime(); - base::TimeTicks destination_url_backoff; - if (url_throttler_entry_.get() && - original_url_throttler_entry_.get() != url_throttler_entry_.get()) { - destination_url_backoff = - url_throttler_entry_->GetExponentialBackoffReleaseTime(); - } - - return original_url_backoff > destination_url_backoff ? - original_url_backoff : destination_url_backoff; -} - -void URLFetcherCore::CompleteAddingUploadDataChunk( - const std::string& content, bool is_last_chunk) { - DCHECK(is_chunked_upload_); - DCHECK(!content.empty()); - chunked_stream_writer_->AppendData( - content.data(), static_cast<int>(content.length()), is_last_chunk); -} - -int URLFetcherCore::WriteBuffer(scoped_refptr<DrainableIOBuffer> data) { - while (data->BytesRemaining() > 0) { - const int result = response_writer_->Write( - data.get(), data->BytesRemaining(), - base::BindOnce(&URLFetcherCore::DidWriteBuffer, this, data)); - if (result < 0) { - if (result != ERR_IO_PENDING) - DidWriteBuffer(data, result); - return result; - } - data->DidConsume(result); - } - return OK; -} - -void URLFetcherCore::DidWriteBuffer(scoped_refptr<DrainableIOBuffer> data, - int result) { - if (result < 0) { // Handle errors. - response_writer_->Finish(result, base::DoNothing()); - CancelRequestAndInformDelegate(result); - return; - } - - // Continue writing. - data->DidConsume(result); - if (WriteBuffer(data) < 0) - return; - - // Finished writing buffer_. Read some more, unless the request has been - // cancelled and deleted. - DCHECK_EQ(0, data->BytesRemaining()); - if (request_.get()) - ReadResponse(); -} - -void URLFetcherCore::ReadResponse() { - // Some servers may treat HEAD requests as GET requests. To free up the - // network connection as soon as possible, signal that the request has - // completed immediately, without trying to read any data back (all we care - // about is the response code and headers, which we already have). - int bytes_read = 0; - if (request_type_ != URLFetcher::HEAD) - bytes_read = request_->Read(buffer_.get(), kBufferSize); - - OnReadCompleted(request_.get(), bytes_read); -} - -void URLFetcherCore::InformDelegateUploadProgress() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - if (request_.get()) { - int64_t current = request_->GetUploadProgress().position(); - if (current_upload_bytes_ != current) { - current_upload_bytes_ = current; - int64_t total = -1; - if (!is_chunked_upload_) { - total = static_cast<int64_t>(request_->GetUploadProgress().size()); - // Total may be zero if the UploadDataStream::Init has not been called - // yet. Don't send the upload progress until the size is initialized. - if (!total) - return; - } - delegate_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &URLFetcherCore::InformDelegateUploadProgressInDelegateSequence, - this, current, total)); - } - } -} - -void URLFetcherCore::InformDelegateUploadProgressInDelegateSequence( - int64_t current, - int64_t total) { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - if (delegate_) - delegate_->OnURLFetchUploadProgress(fetcher_, current, total); -} - -void URLFetcherCore::InformDelegateDownloadProgress() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - delegate_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &URLFetcherCore::InformDelegateDownloadProgressInDelegateSequence, - this, current_response_bytes_, total_response_bytes_, - request_->GetTotalReceivedBytes())); -} - -void URLFetcherCore::InformDelegateDownloadProgressInDelegateSequence( - int64_t current, - int64_t total, - int64_t current_network_bytes) { - DCHECK(delegate_task_runner_->RunsTasksInCurrentSequence()); - if (delegate_) - delegate_->OnURLFetchDownloadProgress(fetcher_, current, total, - current_network_bytes); -} - -void URLFetcherCore::AssertHasNoUploadData() const { - DCHECK(!upload_content_set_); - DCHECK(upload_content_.empty()); - DCHECK(upload_file_path_.empty()); - DCHECK(upload_stream_factory_.is_null()); -} - -} // namespace net diff --git a/chromium/net/url_request/url_fetcher_core.h b/chromium/net/url_request/url_fetcher_core.h deleted file mode 100644 index e030539981e..00000000000 --- a/chromium/net/url_request/url_fetcher_core.h +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright (c) 2012 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 NET_URL_REQUEST_URL_FETCHER_CORE_H_ -#define NET_URL_REQUEST_URL_FETCHER_CORE_H_ - -#include <stdint.h> - -#include <memory> -#include <set> -#include <string> - -#include "base/compiler_specific.h" -#include "base/files/file_path.h" -#include "base/lazy_instance.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_refptr.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "net/base/chunked_upload_data_stream.h" -#include "net/base/ip_endpoint.h" -#include "net/base/net_errors.h" -#include "net/base/proxy_server.h" -#include "net/http/http_request_headers.h" -#include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/referrer_policy.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_context_getter_observer.h" -#include "url/gurl.h" - -namespace base { -class SequencedTaskRunner; -class SingleThreadTaskRunner; -} // namespace base - -namespace net { -class DrainableIOBuffer; -class HttpResponseHeaders; -class IOBuffer; -class URLFetcherDelegate; -class URLFetcherResponseWriter; -class URLRequestContextGetter; -class URLRequestThrottlerEntryInterface; - -class URLFetcherCore : public base::RefCountedThreadSafe<URLFetcherCore>, - public URLRequest::Delegate, - public URLRequestContextGetterObserver { - public: - URLFetcherCore(URLFetcher* fetcher, - const GURL& original_url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - net::NetworkTrafficAnnotationTag traffic_annotation); - - URLFetcherCore(const URLFetcherCore&) = delete; - URLFetcherCore& operator=(const URLFetcherCore&) = delete; - - // Starts the load. It's important that this not happen in the constructor - // because it causes the IO thread to begin AddRef()ing and Release()ing - // us. If our caller hasn't had time to fully construct us and take a - // reference, the IO thread could interrupt things, run a task, Release() - // us, and destroy us, leaving the caller with an already-destroyed object - // when construction finishes. - void Start(); - - // Stops any in-progress load and ensures no callback will happen. It is - // safe to call this multiple times. - void Stop(); - - // URLFetcher-like functions. - - // For POST requests, set |content_type| to the MIME type of the - // content and set |content| to the data to upload. - void SetUploadData(const std::string& upload_content_type, - const std::string& upload_content); - void SetUploadFilePath(const std::string& upload_content_type, - const base::FilePath& file_path, - uint64_t range_offset, - uint64_t range_length, - scoped_refptr<base::TaskRunner> file_task_runner); - void SetUploadStreamFactory( - const std::string& upload_content_type, - const URLFetcher::CreateUploadStreamCallback& callback); - void SetChunkedUpload(const std::string& upload_content_type); - // Adds a block of data to be uploaded in a POST body. This can only be - // called after Start(). - void AppendChunkToUpload(const std::string& data, bool is_last_chunk); - // |flags| are flags to apply to the load operation--these should be - // one or more of the LOAD_* flags defined in net/base/load_flags.h. - void SetLoadFlags(int load_flags); - int GetLoadFlags() const; - void SetAllowCredentials(bool allow_credentials); - void SetReferrer(const std::string& referrer); - void SetReferrerPolicy(ReferrerPolicy referrer_policy); - void ClearExtraRequestHeaders(); - void AddExtraRequestHeader(const std::string& name, const std::string& value); - void SetRequestContext(URLRequestContextGetter* request_context_getter); - // Set the origin that should be considered as "initiating" the fetch. This - // URL - // will be considered the "first-party" when applying cookie blocking policy - // to requests, and treated as the request's initiator. - void SetInitiator(const absl::optional<url::Origin>& initiator); - // Set the key and data callback that is used when setting the user - // data on any URLRequest objects this object creates. - void SetURLRequestUserData( - const void* key, - const URLFetcher::CreateDataCallback& create_data_callback); - void SetStopOnRedirect(bool stop_on_redirect); - void SetAutomaticallyRetryOn5xx(bool retry); - void SetMaxRetriesOn5xx(int max_retries); - int GetMaxRetriesOn5xx() const; - base::TimeDelta GetBackoffDelay() const; - void SetAutomaticallyRetryOnNetworkChanges(int max_retries); - void SaveResponseToFileAtPath( - const base::FilePath& file_path, - scoped_refptr<base::SequencedTaskRunner> file_task_runner); - void SaveResponseToTemporaryFile( - scoped_refptr<base::SequencedTaskRunner> file_task_runner); - void SaveResponseWithWriter( - std::unique_ptr<URLFetcherResponseWriter> response_writer); - HttpResponseHeaders* GetResponseHeaders() const; - IPEndPoint GetSocketAddress() const; - const ProxyServer& ProxyServerUsed() const; - bool WasFetchedViaProxy() const; - bool WasCached() const; - const GURL& GetOriginalURL() const; - const GURL& GetURL() const; - Error GetError() const; - int GetResponseCode() const; - int64_t GetReceivedResponseContentLength() const; - int64_t GetTotalReceivedBytes() const; - // Reports that the received content was malformed (i.e. failed parsing - // or validation). This makes the throttling logic that does exponential - // back-off when servers are having problems treat the current request as - // a failure. Your call to this method will be ignored if your request is - // already considered a failure based on the HTTP response code or response - // headers. - void ReceivedContentWasMalformed(); - bool GetResponseAsString(std::string* out_response_string) const; - bool GetResponseAsFilePath(bool take_ownership, - base::FilePath* out_response_path); - - // Overridden from URLRequest::Delegate: - void OnReceivedRedirect(URLRequest* request, - const RedirectInfo& redirect_info, - bool* defer_redirect) override; - void OnResponseStarted(URLRequest* request, int net_error) override; - void OnReadCompleted(URLRequest* request, int bytes_read) override; - void OnCertificateRequested(URLRequest* request, - SSLCertRequestInfo* cert_request_info) override; - - // Overridden from URLRequestContextGetterObserver: - void OnContextShuttingDown() override; - - URLFetcherDelegate* delegate() const { return delegate_; } - static void CancelAll(); - static int GetNumFetcherCores(); - static void SetEnableInterceptionForTests(bool enabled); - static void SetIgnoreCertificateRequests(bool ignored); - - private: - friend class base::RefCountedThreadSafe<URLFetcherCore>; - - // TODO(mmenke): Remove this class. - class Registry { - public: - Registry(); - - Registry(const Registry&) = delete; - Registry& operator=(const Registry&) = delete; - - ~Registry(); - - void AddURLFetcherCore(URLFetcherCore* core); - void RemoveURLFetcherCore(URLFetcherCore* core); - - void CancelAll(); - - int size() const { - return fetchers_.size(); - } - - private: - std::set<URLFetcherCore*> fetchers_; - }; - - ~URLFetcherCore() override; - - // Wrapper functions that allow us to ensure actions happen on the right - // thread. - void StartOnIOThread(); - void StartURLRequest(); - void DidInitializeWriter(int result); - void StartURLRequestWhenAppropriate(); - void CancelURLRequest(int error); - void OnCompletedURLRequest(base::TimeDelta backoff_delay); - void InformDelegateFetchIsComplete(); - void NotifyMalformedContent(); - void DidFinishWriting(int result); - void RetryOrCompleteUrlFetch(); - - // Cancels the URLRequest and informs the delegate that it failed with the - // specified error. Must be called on network thread. - void CancelRequestAndInformDelegate(int result); - - // Deletes the request, removes it from the registry, and removes the - // destruction observer. - void ReleaseRequest(); - - // Returns the max value of exponential back-off release time for - // |original_url_| and |url_|. - base::TimeTicks GetBackoffReleaseTime(); - - void CompleteAddingUploadDataChunk(const std::string& data, - bool is_last_chunk); - - // Writes all bytes stored in |data| with |response_writer_|. - // Returns OK if all bytes in |data| get written synchronously. Otherwise, - // returns ERR_IO_PENDING or a network error code. - int WriteBuffer(scoped_refptr<DrainableIOBuffer> data); - - // Used to implement WriteBuffer(). - void DidWriteBuffer(scoped_refptr<DrainableIOBuffer> data, int result); - - // Read response bytes from the request. - void ReadResponse(); - - // Notify Delegate about the progress of upload/download. - void InformDelegateUploadProgress(); - void InformDelegateUploadProgressInDelegateSequence(int64_t current, - int64_t total); - void InformDelegateDownloadProgress(); - void InformDelegateDownloadProgressInDelegateSequence( - int64_t current, - int64_t total, - int64_t current_network_bytes); - - // Check if any upload data is set or not. - void AssertHasNoUploadData() const; - - raw_ptr<URLFetcher> fetcher_; // Corresponding fetcher object - GURL original_url_; // The URL we were asked to fetch - GURL url_; // The URL we eventually wound up at - URLFetcher::RequestType request_type_; // What type of request is this? - Error error_; // Error from the request - raw_ptr<URLFetcherDelegate> delegate_; // Object to notify on completion - // Task runner for the creating sequence. Used to interact with the delegate. - const scoped_refptr<base::SequencedTaskRunner> delegate_task_runner_; - // Task runner for network operations. - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - // Task runner for upload file access. - scoped_refptr<base::TaskRunner> upload_file_task_runner_; - std::unique_ptr<URLRequest> request_; // The actual request this wraps - int load_flags_ = LOAD_NORMAL; // Flags for the load operation - // Whether credentials are sent along with the request. - absl::optional<bool> allow_credentials_; - int response_code_ = - URLFetcher::RESPONSE_CODE_INVALID; // HTTP status code for the request - scoped_refptr<IOBuffer> buffer_; - // Read buffer - scoped_refptr<URLRequestContextGetter> request_context_getter_; - // Cookie/cache info for the request - absl::optional<url::Origin> initiator_; // The request's initiator - // The user data to add to each newly-created URLRequest. - raw_ptr<const void> url_request_data_key_ = nullptr; - URLFetcher::CreateDataCallback url_request_create_data_callback_; - HttpRequestHeaders extra_request_headers_; - scoped_refptr<HttpResponseHeaders> response_headers_; - ProxyServer proxy_server_; - bool was_cached_ = false; - int64_t received_response_content_length_ = 0; - int64_t total_received_bytes_ = 0; - IPEndPoint remote_endpoint_; - - bool upload_content_set_ = false; // SetUploadData has been called - std::string upload_content_; // HTTP POST payload - base::FilePath upload_file_path_; // Path to file containing POST payload - uint64_t upload_range_offset_ = 0; // Offset from the beginning of the file - // to be uploaded. - uint64_t upload_range_length_ = 0; // The length of the part of file to be - // uploaded. - URLFetcher::CreateUploadStreamCallback - upload_stream_factory_; // Callback to create HTTP POST payload. - std::string upload_content_type_; // MIME type of POST payload - std::string referrer_; // HTTP Referer header value and policy - ReferrerPolicy referrer_policy_ = - ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE; - bool is_chunked_upload_ = false; // True if using chunked transfer encoding - - // Used to write to |chunked_stream|, even after ownership has been passed to - // the URLRequest. Continues to be valid even after the request deletes its - // upload data. - std::unique_ptr<ChunkedUploadDataStream::Writer> chunked_stream_writer_; - - // Temporary storage of ChunkedUploadDataStream, before request is created. - std::unique_ptr<ChunkedUploadDataStream> chunked_stream_; - - // Used to determine how long to wait before making a request or doing a - // retry. - // - // Both of them can only be accessed on the IO thread. - // - // To determine the proper backoff timing, throttler entries for - // both |original_URL| and |url| are needed. For example, consider - // the case that URL A redirects to URL B, for which the server - // returns a 500 response. In this case, the exponential back-off - // release time of URL A won't increase. If only the backoff - // constraints for URL A are considered, too many requests for URL A - // may be sent in a short period of time. - // - // Both of these will be NULL if - // URLRequestContext::throttler_manager() is NULL. - scoped_refptr<URLRequestThrottlerEntryInterface> - original_url_throttler_entry_; - scoped_refptr<URLRequestThrottlerEntryInterface> url_throttler_entry_; - - // True if the URLFetcher has been cancelled. - bool was_cancelled_ = false; - - // Writer object to write response to the destination like file and string. - std::unique_ptr<URLFetcherResponseWriter> response_writer_; - - // By default any server-initiated redirects are automatically followed. If - // this flag is set to true, however, a redirect will halt the fetch and call - // back to to the delegate immediately. - bool stop_on_redirect_ = false; - // True when we're actually stopped due to a redirect halted by the above. We - // use this to ensure that |url_| is set to the redirect destination rather - // than the originally-fetched URL. - bool stopped_on_redirect_ = false; - - // If |automatically_retry_on_5xx_| is false, 5xx responses will be - // propagated to the observer, if it is true URLFetcher will automatically - // re-execute the request, after the back-off delay has expired. - // true by default. - bool automatically_retry_on_5xx_ = true; - // |num_retries_on_5xx_| indicates how many times we've failed to successfully - // fetch this URL due to 5xx responses. Once this value exceeds the maximum - // number of retries specified by the owner URLFetcher instance, - // we'll give up. - int num_retries_on_5xx_ = 0; - // Maximum retries allowed when 5xx responses are received. - int max_retries_on_5xx_ = 0; - // Back-off time delay. 0 by default. - base::TimeDelta backoff_delay_; - - // The number of retries that have been attempted due to ERR_NETWORK_CHANGED. - int num_retries_on_network_changes_ = 0; - // Maximum retries allowed when the request fails with ERR_NETWORK_CHANGED. - // 0 by default. - int max_retries_on_network_changes_ = 0; - - // Timer to poll the progress of uploading for POST and PUT requests. - // When crbug.com/119629 is fixed, scoped_ptr is not necessary here. - std::unique_ptr<base::RepeatingTimer> upload_progress_checker_timer_; - // Number of bytes sent so far. - int64_t current_upload_bytes_ = -1; - // Number of bytes received so far. - int64_t current_response_bytes_ = 0; - // Total expected bytes to receive (-1 if it cannot be determined). - int64_t total_response_bytes_ = -1; - - const net::NetworkTrafficAnnotationTag traffic_annotation_; - - static base::LazyInstance<Registry>::DestructorAtExit g_registry; -}; - -} // namespace net - -#endif // NET_URL_REQUEST_URL_FETCHER_CORE_H_ diff --git a/chromium/net/url_request/url_fetcher_delegate.cc b/chromium/net/url_request/url_fetcher_delegate.cc deleted file mode 100644 index 359b8172725..00000000000 --- a/chromium/net/url_request/url_fetcher_delegate.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2012 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 "net/url_request/url_fetcher_delegate.h" - -namespace net { - -void URLFetcherDelegate::OnURLFetchDownloadProgress( - const URLFetcher* source, - int64_t current, - int64_t total, - int64_t current_network_bytes) {} - -void URLFetcherDelegate::OnURLFetchUploadProgress(const URLFetcher* source, - int64_t current, - int64_t total) {} - -URLFetcherDelegate::~URLFetcherDelegate() = default; - -} // namespace net diff --git a/chromium/net/url_request/url_fetcher_delegate.h b/chromium/net/url_request/url_fetcher_delegate.h deleted file mode 100644 index 1d3f260863f..00000000000 --- a/chromium/net/url_request/url_fetcher_delegate.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2012 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 NET_URL_REQUEST_URL_FETCHER_DELEGATE_H_ -#define NET_URL_REQUEST_URL_FETCHER_DELEGATE_H_ - -#include <stdint.h> - -#include "net/base/net_export.h" - -namespace net { - -class URLFetcher; - -// A delegate interface for users of URLFetcher. -class NET_EXPORT URLFetcherDelegate { - public: - // This will be called when the URL has been fetched, successfully or not. - // Use accessor methods on |source| to get the results. - virtual void OnURLFetchComplete(const URLFetcher* source) = 0; - - // This will be called when some part of the response is read. |current| - // denotes the number of bytes received up to the call, and |total| is the - // expected total size of the response (or -1 if not determined). - // |current_network_bytes| denotes the number of network bytes received - // up to the call, excluding redirect bodies, SSL and proxy handshakes. - virtual void OnURLFetchDownloadProgress(const URLFetcher* source, - int64_t current, - int64_t total, - int64_t current_network_bytes); - - // This will be called when uploading of POST or PUT requests proceeded. - // |current| denotes the number of bytes sent so far, and |total| is the - // total size of uploading data (or -1 if chunked upload is enabled). - virtual void OnURLFetchUploadProgress(const URLFetcher* source, - int64_t current, - int64_t total); - - protected: - virtual ~URLFetcherDelegate(); -}; - -} // namespace net - -#endif // NET_URL_REQUEST_URL_FETCHER_DELEGATE_H_ diff --git a/chromium/net/url_request/url_fetcher_factory.h b/chromium/net/url_request/url_fetcher_factory.h deleted file mode 100644 index 2a771bf48bc..00000000000 --- a/chromium/net/url_request/url_fetcher_factory.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2012 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 NET_URL_REQUEST_URL_FETCHER_FACTORY_H_ -#define NET_URL_REQUEST_URL_FETCHER_FACTORY_H_ - -#include "net/url_request/url_fetcher.h" - -namespace net { -class URLFetcherDelegate; - -// URLFetcher::Create uses the currently registered Factory to create the -// URLFetcher. Factory is intended for testing. -class URLFetcherFactory { - public: - virtual std::unique_ptr<URLFetcher> CreateURLFetcher( - int id, - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* delegate, - NetworkTrafficAnnotationTag traffic_annotation) = 0; - - protected: - virtual ~URLFetcherFactory() {} -}; - -} // namespace net - -#endif // NET_URL_REQUEST_URL_FETCHER_FACTORY_H_ diff --git a/chromium/net/url_request/url_fetcher_impl.cc b/chromium/net/url_request/url_fetcher_impl.cc deleted file mode 100644 index 7fc9de2fd10..00000000000 --- a/chromium/net/url_request/url_fetcher_impl.cc +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright (c) 2012 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 "net/url_request/url_fetcher_impl.h" - -#include <utility> - -#include "base/bind.h" -#include "base/task/sequenced_task_runner.h" -#include "net/base/upload_data_stream.h" -#include "net/url_request/url_fetcher_core.h" -#include "net/url_request/url_fetcher_factory.h" -#include "net/url_request/url_fetcher_response_writer.h" - -namespace net { - -static URLFetcherFactory* g_factory = nullptr; - -URLFetcherImpl::~URLFetcherImpl() { - core_->Stop(); -} - -void URLFetcherImpl::SetUploadData(const std::string& upload_content_type, - const std::string& upload_content) { - core_->SetUploadData(upload_content_type, upload_content); -} - -void URLFetcherImpl::SetUploadFilePath( - const std::string& upload_content_type, - const base::FilePath& file_path, - uint64_t range_offset, - uint64_t range_length, - scoped_refptr<base::TaskRunner> file_task_runner) { - core_->SetUploadFilePath(upload_content_type, - file_path, - range_offset, - range_length, - file_task_runner); -} - -void URLFetcherImpl::SetUploadStreamFactory( - const std::string& upload_content_type, - const CreateUploadStreamCallback& callback) { - core_->SetUploadStreamFactory(upload_content_type, callback); -} - -void URLFetcherImpl::SetChunkedUpload(const std::string& content_type) { - core_->SetChunkedUpload(content_type); -} - -void URLFetcherImpl::AppendChunkToUpload(const std::string& data, - bool is_last_chunk) { - DCHECK(data.length()); - core_->AppendChunkToUpload(data, is_last_chunk); -} - -void URLFetcherImpl::SetReferrer(const std::string& referrer) { - core_->SetReferrer(referrer); -} - -void URLFetcherImpl::SetReferrerPolicy(ReferrerPolicy referrer_policy) { - core_->SetReferrerPolicy(referrer_policy); -} - -void URLFetcherImpl::SetLoadFlags(int load_flags) { - core_->SetLoadFlags(load_flags); -} - -void URLFetcherImpl::SetAllowCredentials(bool allow_credentials) { - core_->SetAllowCredentials(allow_credentials); -} - -int URLFetcherImpl::GetLoadFlags() const { - return core_->GetLoadFlags(); -} - -void URLFetcherImpl::ClearExtraRequestHeaders() { - core_->ClearExtraRequestHeaders(); -} - -void URLFetcherImpl::AddExtraRequestHeader(const std::string& name, - const std::string& value) { - core_->AddExtraRequestHeader(name, value); -} - -void URLFetcherImpl::SetRequestContext( - URLRequestContextGetter* request_context_getter) { - core_->SetRequestContext(request_context_getter); -} - -void URLFetcherImpl::SetInitiator( - const absl::optional<url::Origin>& initiator) { - core_->SetInitiator(initiator); -} - -void URLFetcherImpl::SetURLRequestUserData( - const void* key, - const CreateDataCallback& create_data_callback) { - core_->SetURLRequestUserData(key, create_data_callback); -} - -void URLFetcherImpl::SetStopOnRedirect(bool stop_on_redirect) { - core_->SetStopOnRedirect(stop_on_redirect); -} - -void URLFetcherImpl::SetAutomaticallyRetryOn5xx(bool retry) { - core_->SetAutomaticallyRetryOn5xx(retry); -} - -void URLFetcherImpl::SetMaxRetriesOn5xx(int max_retries) { - core_->SetMaxRetriesOn5xx(max_retries); -} - -int URLFetcherImpl::GetMaxRetriesOn5xx() const { - return core_->GetMaxRetriesOn5xx(); -} - - -base::TimeDelta URLFetcherImpl::GetBackoffDelay() const { - return core_->GetBackoffDelay(); -} - -void URLFetcherImpl::SetAutomaticallyRetryOnNetworkChanges(int max_retries) { - core_->SetAutomaticallyRetryOnNetworkChanges(max_retries); -} - -void URLFetcherImpl::SaveResponseToFileAtPath( - const base::FilePath& file_path, - scoped_refptr<base::SequencedTaskRunner> file_task_runner) { - core_->SaveResponseToFileAtPath(file_path, file_task_runner); -} - -void URLFetcherImpl::SaveResponseToTemporaryFile( - scoped_refptr<base::SequencedTaskRunner> file_task_runner) { - core_->SaveResponseToTemporaryFile(file_task_runner); -} - -void URLFetcherImpl::SaveResponseWithWriter( - std::unique_ptr<URLFetcherResponseWriter> response_writer) { - core_->SaveResponseWithWriter(std::move(response_writer)); -} - -HttpResponseHeaders* URLFetcherImpl::GetResponseHeaders() const { - return core_->GetResponseHeaders(); -} - -IPEndPoint URLFetcherImpl::GetSocketAddress() const { - return core_->GetSocketAddress(); -} - -const ProxyServer& URLFetcherImpl::ProxyServerUsed() const { - return core_->ProxyServerUsed(); -} - -bool URLFetcherImpl::WasCached() const { - return core_->WasCached(); -} - -int64_t URLFetcherImpl::GetReceivedResponseContentLength() const { - return core_->GetReceivedResponseContentLength(); -} - -int64_t URLFetcherImpl::GetTotalReceivedBytes() const { - return core_->GetTotalReceivedBytes(); -} - -void URLFetcherImpl::Start() { - core_->Start(); -} - -const GURL& URLFetcherImpl::GetOriginalURL() const { - return core_->GetOriginalURL(); -} - -const GURL& URLFetcherImpl::GetURL() const { - return core_->GetURL(); -} - -Error URLFetcherImpl::GetError() const { - return core_->GetError(); -} - -int URLFetcherImpl::GetResponseCode() const { - return core_->GetResponseCode(); -} - -void URLFetcherImpl::ReceivedContentWasMalformed() { - core_->ReceivedContentWasMalformed(); -} - -bool URLFetcherImpl::GetResponseAsString( - std::string* out_response_string) const { - return core_->GetResponseAsString(out_response_string); -} - -bool URLFetcherImpl::GetResponseAsFilePath( - bool take_ownership, - base::FilePath* out_response_path) const { - return core_->GetResponseAsFilePath(take_ownership, out_response_path); -} - -// static -void URLFetcherImpl::CancelAll() { - URLFetcherCore::CancelAll(); -} - -// static -void URLFetcherImpl::SetIgnoreCertificateRequests(bool ignored) { - URLFetcherCore::SetIgnoreCertificateRequests(ignored); -} - -// static -int URLFetcherImpl::GetNumFetcherCores() { - return URLFetcherCore::GetNumFetcherCores(); -} - -URLFetcherDelegate* URLFetcherImpl::delegate() const { - return core_->delegate(); -} - -// static -URLFetcherFactory* URLFetcherImpl::factory() { - return g_factory; -} - -// static -void URLFetcherImpl::set_factory(URLFetcherFactory* factory) { - g_factory = factory; -} - -URLFetcherImpl::URLFetcherImpl( - const GURL& url, - RequestType request_type, - URLFetcherDelegate* d, - net::NetworkTrafficAnnotationTag traffic_annotation) - : core_( - new URLFetcherCore(this, url, request_type, d, traffic_annotation)) {} - -} // namespace net diff --git a/chromium/net/url_request/url_fetcher_impl.h b/chromium/net/url_request/url_fetcher_impl.h deleted file mode 100644 index 78c8a2e3920..00000000000 --- a/chromium/net/url_request/url_fetcher_impl.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2012 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. - -// This file contains URLFetcher, a wrapper around URLRequest that handles -// low-level details like thread safety, ref counting, and incremental buffer -// reading. This is useful for callers who simply want to get the data from a -// URL and don't care about all the nitty-gritty details. -// -// NOTE(willchan): Only one "IO" thread is supported for URLFetcher. This is a -// temporary situation. We will work on allowing support for multiple "io" -// threads per process. - -#ifndef NET_URL_REQUEST_URL_FETCHER_IMPL_H_ -#define NET_URL_REQUEST_URL_FETCHER_IMPL_H_ - -#include <stdint.h> - -#include <string> - -#include "base/task/sequenced_task_runner.h" -#include "net/base/ip_endpoint.h" -#include "net/base/net_export.h" -#include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/referrer_policy.h" -#include "net/url_request/url_fetcher.h" - -namespace net { -class URLFetcherCore; -class URLFetcherDelegate; -class URLFetcherFactory; - -class NET_EXPORT_PRIVATE URLFetcherImpl : public URLFetcher { - public: - URLFetcherImpl(const URLFetcherImpl&) = delete; - URLFetcherImpl& operator=(const URLFetcherImpl&) = delete; - - ~URLFetcherImpl() override; - - // URLFetcher implementation: - void SetUploadData(const std::string& upload_content_type, - const std::string& upload_content) override; - void SetUploadFilePath( - const std::string& upload_content_type, - const base::FilePath& file_path, - uint64_t range_offset, - uint64_t range_length, - scoped_refptr<base::TaskRunner> file_task_runner) override; - void SetUploadStreamFactory( - const std::string& upload_content_type, - const CreateUploadStreamCallback& callback) override; - void SetChunkedUpload(const std::string& upload_content_type) override; - void AppendChunkToUpload(const std::string& data, - bool is_last_chunk) override; - void SetLoadFlags(int load_flags) override; - void SetAllowCredentials(bool allow_credentials) override; - int GetLoadFlags() const override; - void SetReferrer(const std::string& referrer) override; - void SetReferrerPolicy(ReferrerPolicy referrer_policy) override; - void ClearExtraRequestHeaders() override; - void AddExtraRequestHeader(const std::string& name, - const std::string& value) override; - void SetRequestContext( - URLRequestContextGetter* request_context_getter) override; - void SetInitiator(const absl::optional<url::Origin>& initiator) override; - void SetURLRequestUserData( - const void* key, - const CreateDataCallback& create_data_callback) override; - void SetStopOnRedirect(bool stop_on_redirect) override; - void SetAutomaticallyRetryOn5xx(bool retry) override; - void SetMaxRetriesOn5xx(int max_retries) override; - int GetMaxRetriesOn5xx() const override; - base::TimeDelta GetBackoffDelay() const override; - void SetAutomaticallyRetryOnNetworkChanges(int max_retries) override; - void SaveResponseToFileAtPath( - const base::FilePath& file_path, - scoped_refptr<base::SequencedTaskRunner> file_task_runner) override; - void SaveResponseToTemporaryFile( - scoped_refptr<base::SequencedTaskRunner> file_task_runner) override; - void SaveResponseWithWriter( - std::unique_ptr<URLFetcherResponseWriter> response_writer) override; - HttpResponseHeaders* GetResponseHeaders() const override; - IPEndPoint GetSocketAddress() const override; - const ProxyServer& ProxyServerUsed() const override; - bool WasCached() const override; - int64_t GetReceivedResponseContentLength() const override; - int64_t GetTotalReceivedBytes() const override; - void Start() override; - const GURL& GetOriginalURL() const override; - const GURL& GetURL() const override; - Error GetError() const override; - int GetResponseCode() const override; - void ReceivedContentWasMalformed() override; - bool GetResponseAsString(std::string* out_response_string) const override; - bool GetResponseAsFilePath(bool take_ownership, - base::FilePath* out_response_path) const override; - - static void CancelAll(); - - static void SetIgnoreCertificateRequests(bool ignored); - - // TODO(akalin): Make these private again once URLFetcher::Create() - // is in net/. - - static URLFetcherFactory* factory(); - - // Sets the factory used by the static method Create to create a URLFetcher. - // URLFetcher does not take ownership of |factory|. A value of NULL results - // in a URLFetcher being created directly. - // - // NOTE: for safety, this should only be used through ScopedURLFetcherFactory! - static void set_factory(URLFetcherFactory* factory); - - protected: - // Returns the delegate. - URLFetcherDelegate* delegate() const; - - private: - friend class URLFetcherTest; - friend class URLFetcher; - friend class WaitingURLFetcherDelegate; - - // |url| is the URL to send the request to. - // |request_type| is the type of request to make. - // |d| the object that will receive the callback on fetch completion. - URLFetcherImpl(const GURL& url, - RequestType request_type, - URLFetcherDelegate* d, - net::NetworkTrafficAnnotationTag traffic_annotation); - - // Only used by URLFetcherTest, returns the number of URLFetcher::Core objects - // actively running. - static int GetNumFetcherCores(); - - const scoped_refptr<URLFetcherCore> core_; -}; - -} // namespace net - -#endif // NET_URL_REQUEST_URL_FETCHER_IMPL_H_ diff --git a/chromium/net/url_request/url_fetcher_impl_unittest.cc b/chromium/net/url_request/url_fetcher_impl_unittest.cc deleted file mode 100644 index dad77942da7..00000000000 --- a/chromium/net/url_request/url_fetcher_impl_unittest.cc +++ /dev/null @@ -1,1637 +0,0 @@ -// Copyright (c) 2012 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 "net/url_request/url_fetcher_impl.h" - -#include <stdint.h> -#include <string.h> - -#include <algorithm> -#include <limits> -#include <memory> -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/location.h" -#include "base/memory/raw_ptr.h" -#include "base/message_loop/message_pump_type.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/synchronization/waitable_event.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/thread_pool.h" -#include "base/test/test_timeouts.h" -#include "base/threading/platform_thread.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "net/base/elements_upload_data_stream.h" -#include "net/base/network_change_notifier.h" -#include "net/base/proxy_string_util.h" -#include "net/base/upload_bytes_element_reader.h" -#include "net/base/upload_element_reader.h" -#include "net/base/upload_file_element_reader.h" -#include "net/dns/mock_host_resolver.h" -#include "net/http/http_response_headers.h" -#include "net/proxy_resolution/configured_proxy_resolution_service.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "net/test/gtest_util.h" -#include "net/test/test_with_task_environment.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/url_fetcher_delegate.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_builder.h" -#include "net/url_request/url_request_context_getter.h" -#include "net/url_request/url_request_test_util.h" -#include "net/url_request/url_request_throttler_manager.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -using base::Time; -using net::test::IsError; -using net::test::IsOk; - -// Simple URLRequestDelegate that waits for the specified fetcher to complete. -// Can only be used once. -class WaitingURLFetcherDelegate : public URLFetcherDelegate { - public: - WaitingURLFetcherDelegate() = default; - - WaitingURLFetcherDelegate(const WaitingURLFetcherDelegate&) = delete; - WaitingURLFetcherDelegate& operator=(const WaitingURLFetcherDelegate&) = - delete; - - void CreateFetcher( - const GURL& url, - URLFetcher::RequestType request_type, - scoped_refptr<net::URLRequestContextGetter> context_getter) { - if (!on_complete_or_cancel_) { - run_loop_ = std::make_unique<base::RunLoop>(); - on_complete_or_cancel_ = run_loop_->QuitClosure(); - } - fetcher_.reset(new URLFetcherImpl(url, request_type, this, - TRAFFIC_ANNOTATION_FOR_TESTS)); - fetcher_->SetRequestContext(context_getter.get()); - } - - URLFetcher* fetcher() const { return fetcher_.get(); } - - // Wait until the request has completed or been canceled. - void StartFetcherAndWait() { - fetcher_->Start(); - WaitForComplete(); - } - - // Wait until the request has completed or been canceled. Does not start the - // request. - void WaitForComplete() { - EXPECT_TRUE(task_runner_->RunsTasksInCurrentSequence()); - run_loop_->Run(); - } - - // Cancels the fetch by deleting the fetcher. - void CancelFetch() { - EXPECT_TRUE(fetcher_); - fetcher_.reset(); - std::move(on_complete_or_cancel_).Run(); - } - - // URLFetcherDelegate: - void OnURLFetchComplete(const URLFetcher* source) override { - EXPECT_FALSE(did_complete_); - EXPECT_TRUE(fetcher_); - EXPECT_EQ(fetcher_.get(), source); - did_complete_ = true; - std::move(on_complete_or_cancel_).Run(); - } - - void OnURLFetchDownloadProgress(const URLFetcher* source, - int64_t current, - int64_t total, - int64_t current_network_bytes) override { - // Note that the current progress may be greater than the previous progress, - // in the case of retrying the request. - EXPECT_FALSE(did_complete_); - EXPECT_TRUE(fetcher_); - EXPECT_EQ(source, fetcher_.get()); - - EXPECT_LE(0, current); - // If file size is not known, |total| is -1. - if (total >= 0) - EXPECT_LE(current, total); - } - - void OnURLFetchUploadProgress(const URLFetcher* source, - int64_t current, - int64_t total) override { - // Note that the current progress may be greater than the previous progress, - // in the case of retrying the request. - EXPECT_FALSE(did_complete_); - EXPECT_TRUE(fetcher_); - EXPECT_EQ(source, fetcher_.get()); - - EXPECT_LE(0, current); - // If file size is not known, |total| is -1. - if (total >= 0) - EXPECT_LE(current, total); - } - - bool did_complete() const { return did_complete_; } - - void set_on_complete_or_cancel_closure(base::OnceClosure closure) { - on_complete_or_cancel_ = std::move(closure); - } - - private: - bool did_complete_ = false; - - std::unique_ptr<URLFetcherImpl> fetcher_; - const scoped_refptr<base::SequencedTaskRunner> task_runner_ = - base::SequencedTaskRunnerHandle::Get(); - std::unique_ptr<base::RunLoop> run_loop_; - base::OnceClosure on_complete_or_cancel_; -}; - -namespace { - -// TODO(akalin): Move all the test data to somewhere under net/. -const base::FilePath::CharType kDocRoot[] = - FILE_PATH_LITERAL("net/data/url_fetcher_impl_unittest"); -const char kTestServerFilePrefix[] = "/"; - -// Test server path and response body for the default URL used by many of the -// tests. -const char kDefaultResponsePath[] = "/defaultresponse"; -const char kDefaultResponseBody[] = - "Default response given for path: /defaultresponse"; - -// Request body for streams created by CreateUploadStream. -const char kCreateUploadStreamBody[] = "rosebud"; - -base::FilePath GetUploadFileTestPath() { - base::FilePath path; - base::PathService::Get(base::DIR_SOURCE_ROOT, &path); - return path.Append( - FILE_PATH_LITERAL("net/data/url_request_unittest/BullRunSpeech.txt")); -} - -class FetcherTestURLRequestContextGetter : public URLRequestContextGetter { - public: - FetcherTestURLRequestContextGetter( - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - const std::string& hanging_domain) - : network_task_runner_(network_task_runner), - hanging_domain_(hanging_domain) {} - - FetcherTestURLRequestContextGetter( - const FetcherTestURLRequestContextGetter&) = delete; - FetcherTestURLRequestContextGetter& operator=( - const FetcherTestURLRequestContextGetter&) = delete; - - // Sets callback to be invoked when the getter is destroyed. - void set_on_destruction_callback(base::OnceClosure on_destruction_callback) { - on_destruction_callback_ = std::move(on_destruction_callback); - } - - MockHostResolver* mock_resolver() { - DCHECK(context_); - // This cast is safe because we set a MockHostResolver in the constructor. - return static_cast<MockHostResolver*>(context_->host_resolver()); - } - - // URLRequestContextGetter: - URLRequestContext* GetURLRequestContext() override { - // Calling this on the wrong thread may be either a bug in the test or a bug - // in production code. - EXPECT_TRUE(network_task_runner_->BelongsToCurrentThread()); - - if (shutting_down_) - return nullptr; - - if (!context_) { - auto mock_resolver = std::make_unique<MockHostResolver>(); - mock_resolver->set_ondemand_mode(true); - mock_resolver->rules()->AddRule(hanging_domain_, "127.0.0.1"); - - auto builder = CreateTestURLRequestContextBuilder(); - builder->set_host_resolver(std::move(mock_resolver)); - builder->set_throttling_enabled(true); - if (proxy_resolution_service_) { - builder->set_proxy_resolution_service( - std::move(proxy_resolution_service_)); - } - - context_ = builder->Build(); - } - - return context_.get(); - } - - scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() - const override { - return network_task_runner_; - } - - // Adds a throttler entry with the specified parameters. Does this - // synchronously if the context lives on the current thread, or posts a task - // to the relevant thread otherwise. - // - // If |reserve_sending_time_for_next_request|, will start backoff early, as - // if there has already been a request for |url|. - void AddThrottlerEntry(const GURL& url, - const std::string& url_id, - int sliding_window_period_ms, - int max_send_threshold, - int initial_backoff_ms, - double multiply_factor, - double jitter_factor, - int maximum_backoff_ms, - bool reserve_sending_time_for_next_request) { - if (!network_task_runner_->RunsTasksInCurrentSequence()) { - network_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&FetcherTestURLRequestContextGetter::AddThrottlerEntry, - this, url, url_id, sliding_window_period_ms, - max_send_threshold, initial_backoff_ms, - multiply_factor, jitter_factor, maximum_backoff_ms, - reserve_sending_time_for_next_request)); - return; - } - scoped_refptr<URLRequestThrottlerEntry> entry(new URLRequestThrottlerEntry( - GetURLRequestContext()->throttler_manager(), url_id, - sliding_window_period_ms, max_send_threshold, initial_backoff_ms, - multiply_factor, jitter_factor, maximum_backoff_ms)); - - GetURLRequestContext()->throttler_manager()->OverrideEntryForTests( - url, entry.get()); - - if (reserve_sending_time_for_next_request) - entry->ReserveSendingTimeForNextRequest(base::TimeTicks()); - } - - // Tells the getter to act as if the URLRequestContext is about to be shut - // down. - void Shutdown() { - if (!network_task_runner_->RunsTasksInCurrentSequence()) { - network_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&FetcherTestURLRequestContextGetter::Shutdown, this)); - return; - } - - shutting_down_ = true; - NotifyContextShuttingDown(); - // Should now be safe to destroy the context. Context will check it has no - // pending requests. - context_.reset(); - } - - // Convenience method to access the context. - URLRequestContext* context() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - return context_.get(); - } - - void set_proxy_resolution_service( - std::unique_ptr<ProxyResolutionService> proxy_resolution_service) { - DCHECK(proxy_resolution_service); - proxy_resolution_service_ = std::move(proxy_resolution_service); - } - - protected: - ~FetcherTestURLRequestContextGetter() override { - // |context_| may only be deleted on the network thread. Fortunately, - // the parent class already ensures it's deleted on the network thread. - DCHECK(network_task_runner_->BelongsToCurrentThread()); - if (!on_destruction_callback_.is_null()) - std::move(on_destruction_callback_).Run(); - } - - private: - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - const std::string hanging_domain_; - - // May be null. - std::unique_ptr<ProxyResolutionService> proxy_resolution_service_; - - std::unique_ptr<URLRequestContext> context_; - bool shutting_down_ = false; - - base::OnceClosure on_destruction_callback_; -}; - -} // namespace - -class URLFetcherTest : public TestWithTaskEnvironment { - public: - URLFetcherTest() = default; - - static int GetNumFetcherCores() { - return URLFetcherImpl::GetNumFetcherCores(); - } - - // Creates a URLRequestContextGetter with a URLRequestContext that lives on - // the current thread. - scoped_refptr<FetcherTestURLRequestContextGetter> - CreateSameThreadContextGetter() { - return scoped_refptr<FetcherTestURLRequestContextGetter>( - new FetcherTestURLRequestContextGetter( - base::ThreadTaskRunnerHandle::Get(), hanging_url().host())); - } - - // Creates a URLRequestContextGetter with a URLRequestContext that lives on - // a separate network thread. - scoped_refptr<FetcherTestURLRequestContextGetter> - CreateCrossThreadContextGetter() { - if (!network_thread_) { - network_thread_ = std::make_unique<base::Thread>("network thread"); - base::Thread::Options network_thread_options; - network_thread_options.message_pump_type = base::MessagePumpType::IO; - bool result = - network_thread_->StartWithOptions(std::move(network_thread_options)); - CHECK(result); - } - - return scoped_refptr<FetcherTestURLRequestContextGetter>( - new FetcherTestURLRequestContextGetter(network_thread_->task_runner(), - hanging_url().host())); - } - - // Callback passed to URLFetcher to create upload stream by some tests. - std::unique_ptr<UploadDataStream> CreateUploadStream() { - ++num_upload_streams_created_; - std::vector<char> buffer( - kCreateUploadStreamBody, - kCreateUploadStreamBody + strlen(kCreateUploadStreamBody)); - return ElementsUploadDataStream::CreateWithReader( - std::unique_ptr<UploadElementReader>( - new UploadOwnedBytesElementReader(&buffer)), - 0); - } - - // Number of streams created by CreateUploadStream. - size_t num_upload_streams_created() const { - return num_upload_streams_created_; - } - - // Downloads |file_to_fetch| and checks the contents when done. If - // |save_to_temporary_file| is true, saves it to a temporary file, and - // |requested_out_path| is ignored. Otherwise, saves it to - // |requested_out_path|. Takes ownership of the file if |take_ownership| is - // true. Deletes file when done. - void SaveFileTest(const char* file_to_fetch, - bool save_to_temporary_file, - const base::FilePath& requested_out_path, - bool take_ownership) { - std::unique_ptr<WaitingURLFetcherDelegate> delegate( - new WaitingURLFetcherDelegate()); - delegate->CreateFetcher( - test_server_->GetURL(std::string(kTestServerFilePrefix) + - file_to_fetch), - URLFetcher::GET, CreateSameThreadContextGetter()); - if (save_to_temporary_file) { - delegate->fetcher()->SaveResponseToTemporaryFile( - scoped_refptr<base::SequencedTaskRunner>( - base::SequencedTaskRunnerHandle::Get())); - } else { - delegate->fetcher()->SaveResponseToFileAtPath( - requested_out_path, scoped_refptr<base::SequencedTaskRunner>( - base::SequencedTaskRunnerHandle::Get())); - } - delegate->StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate->fetcher()->GetError()); - EXPECT_EQ(200, delegate->fetcher()->GetResponseCode()); - - base::FilePath out_path; - EXPECT_TRUE( - delegate->fetcher()->GetResponseAsFilePath(take_ownership, &out_path)); - if (!save_to_temporary_file) { - EXPECT_EQ(requested_out_path, out_path); - } - - base::FilePath server_root; - base::PathService::Get(base::DIR_SOURCE_ROOT, &server_root); - - EXPECT_TRUE(base::ContentsEqual( - server_root.Append(kDocRoot).AppendASCII(file_to_fetch), out_path)); - - // Delete the delegate and run the message loop to give the fetcher's - // destructor a chance to delete the file. - delegate.reset(); - base::RunLoop().RunUntilIdle(); - - // File should only exist if |take_ownership| was true. - EXPECT_EQ(take_ownership, base::PathExists(out_path)); - - // Cleanup. - if (base::PathExists(out_path)) - base::DeleteFile(out_path); - } - - // Returns a URL that hangs on DNS resolution when using a context created by - // the test fixture. - const GURL& hanging_url() const { return hanging_url_; } - - // testing::Test: - void SetUp() override { - SetUpServer(); - ASSERT_TRUE(test_server_->Start()); - - // URL that will hang when lookups reach the host resolver. - hanging_url_ = GURL(base::StringPrintf( - "http://example.com:%d%s", test_server_->host_port_pair().port(), - kDefaultResponsePath)); - ASSERT_TRUE(hanging_url_.is_valid()); - } - - // Initializes |test_server_| without starting it. Allows subclasses to use - // their own server configuration. - virtual void SetUpServer() { - test_server_ = std::make_unique<EmbeddedTestServer>(); - test_server_->AddDefaultHandlers(base::FilePath(kDocRoot)); - } - - // Network thread for cross-thread tests. Most threads just use the main - // thread for network activity. - std::unique_ptr<base::Thread> network_thread_; - - std::unique_ptr<EmbeddedTestServer> test_server_; - GURL hanging_url_; - - size_t num_upload_streams_created_ = 0; -}; - -namespace { - -// Version of URLFetcherTest that tests bad HTTPS requests. -class URLFetcherBadHTTPSTest : public URLFetcherTest { - public: - URLFetcherBadHTTPSTest() = default; - - // URLFetcherTest: - void SetUpServer() override { - test_server_ = std::make_unique<EmbeddedTestServer>( - net::EmbeddedTestServer::TYPE_HTTPS); - test_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); - test_server_->ServeFilesFromSourceDirectory("net/data/ssl"); - } -}; - -// Verifies that the fetcher succesfully fetches resources over proxy, and -// correctly returns the value of the proxy server used. -TEST_F(URLFetcherTest, FetchedUsingProxy) { - WaitingURLFetcherDelegate delegate; - - scoped_refptr<net::FetcherTestURLRequestContextGetter> context_getter = - CreateSameThreadContextGetter(); - - const net::ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, - test_server_->host_port_pair()); - - std::unique_ptr<ProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( - ProxyServerToPacResultElement(proxy_server), - TRAFFIC_ANNOTATION_FOR_TESTS); - context_getter->set_proxy_resolution_service( - std::move(proxy_resolution_service)); - - delegate.CreateFetcher( - GURL(std::string("http://does.not.resolve.test") + kDefaultResponsePath), - URLFetcher::GET, context_getter); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kDefaultResponseBody, data); - - EXPECT_EQ(proxy_server, delegate.fetcher()->ProxyServerUsed()); -} - -// Create the fetcher on the main thread. Since network IO will happen on the -// main thread, this will test URLFetcher's ability to do everything on one -// thread. -TEST_F(URLFetcherTest, SameThreadTest) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL(kDefaultResponsePath), - URLFetcher::GET, CreateSameThreadContextGetter()); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kDefaultResponseBody, data); - - EXPECT_EQ(static_cast<int64_t>(strlen(kDefaultResponseBody)), - delegate.fetcher()->GetReceivedResponseContentLength()); - std::string parsed_headers; - base::ReplaceChars(delegate.fetcher()->GetResponseHeaders()->raw_headers(), - std::string("\0", 1), "\n\r", &parsed_headers); - EXPECT_EQ(static_cast<int64_t>(parsed_headers.size() + - strlen(kDefaultResponseBody)), - delegate.fetcher()->GetTotalReceivedBytes()); - EXPECT_EQ(ProxyServer::SCHEME_DIRECT, - delegate.fetcher()->ProxyServerUsed().scheme()); -} - -// Create a separate thread that will create the URLFetcher. A separate thread -// acts as the network thread. -TEST_F(URLFetcherTest, DifferentThreadsTest) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL(kDefaultResponsePath), - URLFetcher::GET, CreateCrossThreadContextGetter()); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kDefaultResponseBody, data); -} - -// Verifies that a URLFetcher works correctly on a ThreadPool Sequence. -TEST_F(URLFetcherTest, SequencedTaskTest) { - auto sequenced_task_runner = base::ThreadPool::CreateSequencedTaskRunner({}); - - // Since we cannot use StartFetchAndWait(), which runs a nested RunLoop owned - // by the Delegate, in the ThreadPool, this test is split into two Callbacks, - // both run on |sequenced_task_runner_|. The test main thread then runs its - // own RunLoop, which the second of the Callbacks will quit. - base::RunLoop run_loop; - - // Actually start the test fetch, on the Sequence. - sequenced_task_runner->PostTask( - FROM_HERE, - base::BindOnce( - [](scoped_refptr<FetcherTestURLRequestContextGetter> context_getter, - const GURL& response_path, base::OnceClosure quit_closure) { - std::unique_ptr<WaitingURLFetcherDelegate> delegate = - std::make_unique<WaitingURLFetcherDelegate>(); - WaitingURLFetcherDelegate* raw_delegate = delegate.get(); - - // Configure the delegate to run our |on_complete_closure_| rather - // than quitting its own |run_loop_|, on completion. - raw_delegate->set_on_complete_or_cancel_closure(base::BindOnce( - [](base::OnceClosure quit_closure, - std::unique_ptr<WaitingURLFetcherDelegate> delegate) { - EXPECT_EQ(OK, delegate->fetcher()->GetError()); - EXPECT_EQ(200, delegate->fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate->fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kDefaultResponseBody, data); - std::move(quit_closure).Run(); - }, - std::move(quit_closure), std::move(delegate))); - - raw_delegate->CreateFetcher(response_path, URLFetcher::GET, - context_getter); - raw_delegate->fetcher()->Start(); - }, - CreateCrossThreadContextGetter(), - test_server_->GetURL(kDefaultResponsePath), run_loop.QuitClosure())); - - run_loop.Run(); - RunUntilIdle(); -} - -// Tests to make sure CancelAll() will successfully cancel existing URLFetchers. -TEST_F(URLFetcherTest, CancelAll) { - EXPECT_EQ(0, GetNumFetcherCores()); - - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - // Force context creation. - context_getter->GetURLRequestContext(); - MockHostResolver* mock_resolver = context_getter->mock_resolver(); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - delegate.fetcher()->Start(); - // Wait for the request to reach the mock resolver and hang, to ensure the - // request has actually started. - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(mock_resolver->has_pending_requests()); - - EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores()); - URLFetcherImpl::CancelAll(); - EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores()); -} - -TEST_F(URLFetcherTest, DontRetryOnNetworkChangedByDefault) { - EXPECT_EQ(0, GetNumFetcherCores()); - - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - // Force context creation. - context_getter->GetURLRequestContext(); - MockHostResolver* mock_resolver = context_getter->mock_resolver(); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - EXPECT_FALSE(mock_resolver->has_pending_requests()); - - // This posts a task to start the fetcher. - delegate.fetcher()->Start(); - base::RunLoop().RunUntilIdle(); - - // The fetcher is now running, but is pending the host resolve. - EXPECT_EQ(1, GetNumFetcherCores()); - EXPECT_TRUE(mock_resolver->has_pending_requests()); - ASSERT_FALSE(delegate.did_complete()); - - // A network change notification aborts the connect job. - NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); - delegate.WaitForComplete(); - EXPECT_FALSE(mock_resolver->has_pending_requests()); - - // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error. - EXPECT_EQ(hanging_url(), delegate.fetcher()->GetOriginalURL()); - EXPECT_THAT(delegate.fetcher()->GetError(), IsError(ERR_NETWORK_CHANGED)); -} - -TEST_F(URLFetcherTest, RetryOnNetworkChangedAndFail) { - EXPECT_EQ(0, GetNumFetcherCores()); - - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - // Force context creation. - context_getter->GetURLRequestContext(); - MockHostResolver* mock_resolver = context_getter->mock_resolver(); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - delegate.fetcher()->SetAutomaticallyRetryOnNetworkChanges(3); - EXPECT_FALSE(mock_resolver->has_pending_requests()); - - // This posts a task to start the fetcher. - delegate.fetcher()->Start(); - base::RunLoop().RunUntilIdle(); - - // The fetcher is now running, but is pending the host resolve. - EXPECT_EQ(1, GetNumFetcherCores()); - EXPECT_TRUE(mock_resolver->has_pending_requests()); - ASSERT_FALSE(delegate.did_complete()); - - // Make it fail 3 times. - for (int i = 0; i < 3; ++i) { - // A network change notification aborts the connect job. - NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); - base::RunLoop().RunUntilIdle(); - - // But the fetcher retries automatically. - EXPECT_EQ(1, GetNumFetcherCores()); - EXPECT_TRUE(mock_resolver->has_pending_requests()); - ASSERT_FALSE(delegate.did_complete()); - } - - // A 4th failure doesn't trigger another retry, and propagates the error - // to the owner of the fetcher. - NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); - delegate.WaitForComplete(); - EXPECT_FALSE(mock_resolver->has_pending_requests()); - - // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error. - EXPECT_EQ(hanging_url(), delegate.fetcher()->GetOriginalURL()); - EXPECT_THAT(delegate.fetcher()->GetError(), IsError(ERR_NETWORK_CHANGED)); -} - -TEST_F(URLFetcherTest, RetryOnNetworkChangedAndSucceed) { - EXPECT_EQ(0, GetNumFetcherCores()); - - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - // Force context creation. - context_getter->GetURLRequestContext(); - MockHostResolver* mock_resolver = context_getter->mock_resolver(); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - delegate.fetcher()->SetAutomaticallyRetryOnNetworkChanges(3); - EXPECT_FALSE(mock_resolver->has_pending_requests()); - - // This posts a task to start the fetcher. - delegate.fetcher()->Start(); - base::RunLoop().RunUntilIdle(); - - // The fetcher is now running, but is pending the host resolve. - EXPECT_EQ(1, GetNumFetcherCores()); - EXPECT_TRUE(mock_resolver->has_pending_requests()); - ASSERT_FALSE(delegate.did_complete()); - - // Make it fail 3 times. - for (int i = 0; i < 3; ++i) { - // A network change notification aborts the connect job. - NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); - base::RunLoop().RunUntilIdle(); - - // But the fetcher retries automatically. - EXPECT_EQ(1, GetNumFetcherCores()); - EXPECT_TRUE(mock_resolver->has_pending_requests()); - ASSERT_FALSE(delegate.did_complete()); - } - - // Now let it succeed by resolving the pending request. - mock_resolver->ResolveAllPending(); - delegate.WaitForComplete(); - EXPECT_FALSE(mock_resolver->has_pending_requests()); - - // This time the request succeeded. - EXPECT_EQ(hanging_url(), delegate.fetcher()->GetOriginalURL()); - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kDefaultResponseBody, data); -} - -TEST_F(URLFetcherTest, PostString) { - const char kUploadData[] = "bobsyeruncle"; - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, - CreateSameThreadContextGetter()); - delegate.fetcher()->SetUploadData("application/x-www-form-urlencoded", - kUploadData); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kUploadData, data); -} - -TEST_F(URLFetcherTest, PostEmptyString) { - const char kUploadData[] = ""; - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, - CreateSameThreadContextGetter()); - delegate.fetcher()->SetUploadData("application/x-www-form-urlencoded", - kUploadData); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kUploadData, data); -} - -TEST_F(URLFetcherTest, PostEntireFile) { - base::FilePath upload_path = GetUploadFileTestPath(); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, - CreateSameThreadContextGetter()); - delegate.fetcher()->SetUploadFilePath("application/x-www-form-urlencoded", - upload_path, 0, - std::numeric_limits<uint64_t>::max(), - base::SequencedTaskRunnerHandle::Get()); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - - std::string expected; - ASSERT_TRUE(base::ReadFileToString(upload_path, &expected)); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(expected, data); -} - -TEST_F(URLFetcherTest, PostFileRange) { - const size_t kRangeStart = 30; - const size_t kRangeLength = 100; - base::FilePath upload_path = GetUploadFileTestPath(); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, - CreateSameThreadContextGetter()); - delegate.fetcher()->SetUploadFilePath("application/x-www-form-urlencoded", - upload_path, kRangeStart, kRangeLength, - base::SequencedTaskRunnerHandle::Get()); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - - std::string expected; - ASSERT_TRUE(base::ReadFileToString(upload_path, &expected)); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(expected.substr(kRangeStart, kRangeLength), data); -} - -TEST_F(URLFetcherTest, PostWithUploadStreamFactory) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, - CreateSameThreadContextGetter()); - delegate.fetcher()->SetUploadStreamFactory( - "text/plain", base::BindRepeating(&URLFetcherTest::CreateUploadStream, - base::Unretained(this))); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kCreateUploadStreamBody, data); - EXPECT_EQ(1u, num_upload_streams_created()); -} - -TEST_F(URLFetcherTest, PostWithUploadStreamFactoryAndRetries) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo?status=500"), - URLFetcher::POST, CreateSameThreadContextGetter()); - delegate.fetcher()->SetAutomaticallyRetryOn5xx(true); - delegate.fetcher()->SetMaxRetriesOn5xx(1); - delegate.fetcher()->SetUploadStreamFactory( - "text/plain", base::BindRepeating(&URLFetcherTest::CreateUploadStream, - base::Unretained(this))); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(500, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kCreateUploadStreamBody, data); - EXPECT_EQ(2u, num_upload_streams_created()); -} - -// Tests simple chunked POST case. -TEST_F(URLFetcherTest, PostChunked) { - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateCrossThreadContextGetter()); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, - CreateCrossThreadContextGetter()); - - delegate.fetcher()->SetChunkedUpload("text/plain"); - - // This posts a task to start the fetcher. - delegate.fetcher()->Start(); - - delegate.fetcher()->AppendChunkToUpload(kCreateUploadStreamBody, false); - delegate.fetcher()->AppendChunkToUpload(kCreateUploadStreamBody, true); - - delegate.WaitForComplete(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(std::string(kCreateUploadStreamBody) + - std::string(kCreateUploadStreamBody), - data); -} - -// Tests that data can be appended to a request after it fails. This is needed -// because the consumer may try to append data to a request after it failed, but -// before the consumer learns that it failed. -TEST_F(URLFetcherTest, PostAppendChunkAfterError) { - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateCrossThreadContextGetter()); - - WaitingURLFetcherDelegate delegate; - // Request that will fail almost immediately after being started, due to using - // a reserved port. - delegate.CreateFetcher(GURL("http://127.0.0.1:7"), URLFetcher::POST, - context_getter); - - delegate.fetcher()->SetChunkedUpload("text/plain"); - - // This posts a task to start the fetcher. - delegate.fetcher()->Start(); - - // Give the request a chance to fail, and inform the fetcher of the failure, - // while blocking the current thread so the error doesn't reach the delegate. - base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); - - // Try to append data. - delegate.fetcher()->AppendChunkToUpload("kCreateUploadStreamBody", false); - delegate.fetcher()->AppendChunkToUpload("kCreateUploadStreamBody", true); - - delegate.WaitForComplete(); - - // Make sure the request failed, as expected. - EXPECT_THAT(delegate.fetcher()->GetError(), IsError(ERR_UNSAFE_PORT)); -} - -// Checks that upload progress increases over time, never exceeds what's already -// been sent, and adds a chunk whenever all previously appended chunks have -// been uploaded. -class CheckUploadProgressDelegate : public WaitingURLFetcherDelegate { - public: - CheckUploadProgressDelegate() : chunk_(1 << 16, 'a') {} - - CheckUploadProgressDelegate(const CheckUploadProgressDelegate&) = delete; - CheckUploadProgressDelegate& operator=(const CheckUploadProgressDelegate&) = - delete; - - ~CheckUploadProgressDelegate() override = default; - - void OnURLFetchUploadProgress(const URLFetcher* source, - int64_t current, - int64_t total) override { - // Run default checks. - WaitingURLFetcherDelegate::OnURLFetchUploadProgress(source, current, total); - - EXPECT_LE(last_seen_progress_, current); - EXPECT_LE(current, bytes_appended()); - last_seen_progress_ = current; - MaybeAppendChunk(); - } - - // Append the next chunk if all previously appended chunks have been sent. - void MaybeAppendChunk() { - const int kNumChunks = 5; - if (last_seen_progress_ == bytes_appended() && - num_chunks_appended_ < kNumChunks) { - ++num_chunks_appended_; - fetcher()->AppendChunkToUpload(chunk_, - num_chunks_appended_ == kNumChunks); - } - } - - private: - int64_t bytes_appended() const { - return num_chunks_appended_ * chunk_.size(); - } - - const std::string chunk_; - - int64_t num_chunks_appended_ = 0; - int64_t last_seen_progress_ = 0; -}; - -TEST_F(URLFetcherTest, UploadProgress) { - CheckUploadProgressDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, - CreateSameThreadContextGetter()); - // Use a chunked upload so that the upload can be paused after uploading data. - // Since upload progress uses a timer, the delegate may not receive any - // notification otherwise. - delegate.fetcher()->SetChunkedUpload("application/x-www-form-urlencoded"); - - delegate.fetcher()->Start(); - // Append the first chunk. Others will be appended automatically in response - // to OnURLFetchUploadProgress events. - delegate.MaybeAppendChunk(); - delegate.WaitForComplete(); - - // Make sure there are no pending events that cause problems when run. - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - EXPECT_TRUE(delegate.did_complete()); -} - -// Checks that download progress never decreases, never exceeds file size, and -// that file size is correctly reported. -class CheckDownloadProgressDelegate : public WaitingURLFetcherDelegate { - public: - explicit CheckDownloadProgressDelegate(int64_t file_size) - : file_size_(file_size) {} - - CheckDownloadProgressDelegate(const CheckDownloadProgressDelegate&) = delete; - CheckDownloadProgressDelegate& operator=( - const CheckDownloadProgressDelegate&) = delete; - - ~CheckDownloadProgressDelegate() override = default; - - void OnURLFetchDownloadProgress(const URLFetcher* source, - int64_t current, - int64_t total, - int64_t current_network_bytes) override { - // Run default checks. - WaitingURLFetcherDelegate::OnURLFetchDownloadProgress( - source, current, total, current_network_bytes); - - EXPECT_LE(last_seen_progress_, current); - EXPECT_EQ(file_size_, total); - last_seen_progress_ = current; - } - - private: - int64_t file_size_; - int64_t last_seen_progress_ = 0; -}; - -TEST_F(URLFetcherTest, DownloadProgress) { - // Get a file large enough to require more than one read into - // URLFetcher::Core's IOBuffer. - const char kFileToFetch[] = "animate1.gif"; - - std::string file_contents; - - base::FilePath server_root; - base::PathService::Get(base::DIR_SOURCE_ROOT, &server_root); - - ASSERT_TRUE(base::ReadFileToString( - server_root.Append(kDocRoot).AppendASCII(kFileToFetch), &file_contents)); - - CheckDownloadProgressDelegate delegate(file_contents.size()); - delegate.CreateFetcher( - test_server_->GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), - URLFetcher::GET, CreateSameThreadContextGetter()); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(file_contents, data); -} - -class CancelOnUploadProgressDelegate : public WaitingURLFetcherDelegate { - public: - CancelOnUploadProgressDelegate() = default; - - CancelOnUploadProgressDelegate(const CancelOnUploadProgressDelegate&) = - delete; - CancelOnUploadProgressDelegate& operator=( - const CancelOnUploadProgressDelegate&) = delete; - - ~CancelOnUploadProgressDelegate() override = default; - - void OnURLFetchUploadProgress(const URLFetcher* source, - int64_t current, - int64_t total) override { - CancelFetch(); - } -}; - -// Check that a fetch can be safely cancelled/deleted during an upload progress -// callback. -TEST_F(URLFetcherTest, CancelInUploadProgressCallback) { - CancelOnUploadProgressDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, - CreateSameThreadContextGetter()); - delegate.fetcher()->SetChunkedUpload("application/x-www-form-urlencoded"); - delegate.fetcher()->Start(); - // Use a chunked upload so that the upload can be paused after uploading data. - // Since uploads progress uses a timer, may not receive any notification, - // otherwise. - std::string upload_data(1 << 16, 'a'); - delegate.fetcher()->AppendChunkToUpload(upload_data, false); - delegate.WaitForComplete(); - - // Make sure there are no pending events that cause problems when run. - base::RunLoop().RunUntilIdle(); - - EXPECT_FALSE(delegate.did_complete()); - EXPECT_FALSE(delegate.fetcher()); -} - -class CancelOnDownloadProgressDelegate : public WaitingURLFetcherDelegate { - public: - CancelOnDownloadProgressDelegate() = default; - - CancelOnDownloadProgressDelegate(const CancelOnDownloadProgressDelegate&) = - delete; - CancelOnDownloadProgressDelegate& operator=( - const CancelOnDownloadProgressDelegate&) = delete; - - ~CancelOnDownloadProgressDelegate() override = default; - - void OnURLFetchDownloadProgress(const URLFetcher* source, - int64_t current, - int64_t total, - int64_t current_network_bytes) override { - CancelFetch(); - } -}; - -// Check that a fetch can be safely cancelled/deleted during a download progress -// callback. -TEST_F(URLFetcherTest, CancelInDownloadProgressCallback) { - // Get a file large enough to require more than one read into - // URLFetcher::Core's IOBuffer. - static const char kFileToFetch[] = "animate1.gif"; - CancelOnDownloadProgressDelegate delegate; - delegate.CreateFetcher( - test_server_->GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), - URLFetcher::GET, CreateSameThreadContextGetter()); - delegate.StartFetcherAndWait(); - - // Make sure there are no pending events that cause problems when run. - base::RunLoop().RunUntilIdle(); - - EXPECT_FALSE(delegate.did_complete()); - EXPECT_FALSE(delegate.fetcher()); -} - -TEST_F(URLFetcherTest, Headers) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher( - test_server_->GetURL("/set-header?cache-control: private"), - URLFetcher::GET, CreateSameThreadContextGetter()); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string header; - ASSERT_TRUE(delegate.fetcher()->GetResponseHeaders()->GetNormalizedHeader( - "cache-control", &header)); - EXPECT_EQ("private", header); -} - -TEST_F(URLFetcherTest, SocketAddress) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL(kDefaultResponsePath), - URLFetcher::GET, CreateSameThreadContextGetter()); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - EXPECT_EQ(test_server_->host_port_pair().port(), - delegate.fetcher()->GetSocketAddress().port()); - EXPECT_EQ(test_server_->host_port_pair().host(), - delegate.fetcher()->GetSocketAddress().ToStringWithoutPort()); -} - -TEST_F(URLFetcherTest, StopOnRedirect) { - const char kRedirectTarget[] = "http://redirect.target.com"; - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher( - test_server_->GetURL(std::string("/server-redirect?") + kRedirectTarget), - URLFetcher::GET, CreateSameThreadContextGetter()); - delegate.fetcher()->SetStopOnRedirect(true); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(GURL(kRedirectTarget), delegate.fetcher()->GetURL()); - EXPECT_THAT(delegate.fetcher()->GetError(), IsError(ERR_ABORTED)); - EXPECT_EQ(301, delegate.fetcher()->GetResponseCode()); - ASSERT_TRUE(delegate.fetcher()->GetResponseHeaders()); - EXPECT_TRUE(delegate.fetcher()->GetResponseHeaders()->HasHeaderValue( - "Location", std::string(kRedirectTarget))); -} - -TEST_F(URLFetcherTest, ThrottleOnRepeatedFetches) { - base::Time start_time = Time::Now(); - GURL url(test_server_->GetURL(kDefaultResponsePath)); - - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - - // Registers an entry for test url. It only allows 3 requests to be sent - // in 200 milliseconds. - context_getter->AddThrottlerEntry( - url, std::string() /* url_id */, 200 /* sliding_window_period_ms */, - 3 /* max_send_threshold */, 1 /* initial_backoff_ms */, - 2.0 /* multiply_factor */, 0.0 /* jitter_factor */, - 256 /* maximum_backoff_ms */, - false /* reserve_sending_time_for_next_request*/); - - for (int i = 0; i < 20; ++i) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(url, URLFetcher::GET, context_getter); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - } - - // 20 requests were sent. Due to throttling, they should have collectively - // taken over 1 second. - EXPECT_GE(Time::Now() - start_time, base::Seconds(1)); -} - -// If throttling kicks in for a chunked upload, there should be no crash. -TEST_F(URLFetcherTest, ThrottleChunkedUpload) { - GURL url(test_server_->GetURL("/echo")); - - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - - // Registers an entry for test url. It only allows 3 requests to be sent - // in 200 milliseconds. - context_getter->AddThrottlerEntry( - url, std::string() /* url_id */, 200 /* sliding_window_period_ms */, - 3 /* max_send_threshold */, 1 /* initial_backoff_ms */, - 2.0 /* multiply_factor */, 0.0 /* jitter_factor */, - 256 /* maximum_backoff_ms */, - false /* reserve_sending_time_for_next_request*/); - - for (int i = 0; i < 20; ++i) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(url, URLFetcher::POST, context_getter); - delegate.fetcher()->SetChunkedUpload("text/plain"); - delegate.fetcher()->Start(); - delegate.fetcher()->AppendChunkToUpload(kCreateUploadStreamBody, true); - delegate.WaitForComplete(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ(kCreateUploadStreamBody, data); - } -} - -TEST_F(URLFetcherTest, ThrottleOn5xxRetries) { - base::Time start_time = Time::Now(); - GURL url(test_server_->GetURL("/server-unavailable.html")); - - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - - // Registers an entry for test url. The backoff time is calculated by: - // new_backoff = 2.0 * old_backoff + 0 - // and maximum backoff time is 256 milliseconds. - // Maximum retries allowed is set to 11. - context_getter->AddThrottlerEntry( - url, std::string() /* url_id */, 200 /* sliding_window_period_ms */, - 3 /* max_send_threshold */, 1 /* initial_backoff_ms */, - 2.0 /* multiply_factor */, 0.0 /* jitter_factor */, - 256 /* maximum_backoff_ms */, - false /* reserve_sending_time_for_next_request*/); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(url, URLFetcher::GET, context_getter); - delegate.fetcher()->SetAutomaticallyRetryOn5xx(true); - delegate.fetcher()->SetMaxRetriesOn5xx(11); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(503, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_FALSE(data.empty()); - - // The request should have been retried 11 times (12 times including the first - // attempt). Due to throttling, they should have collectively taken over 1 - // second. - EXPECT_GE(Time::Now() - start_time, base::Seconds(1)); -} - -// Tests overload protection, when responses passed through. -TEST_F(URLFetcherTest, ProtectTestPassedThrough) { - base::Time start_time = Time::Now(); - GURL url(test_server_->GetURL("/server-unavailable.html")); - - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - - // Registers an entry for test url. The backoff time is calculated by: - // new_backoff = 2.0 * old_backoff + 0 - // and maximum backoff time is 150000 milliseconds. - // Maximum retries allowed is set to 11. - // Total time if *not* for not doing automatic backoff would be 150s. - // In reality it should be "as soon as server responds". - context_getter->AddThrottlerEntry( - url, std::string() /* url_id */, 200 /* sliding_window_period_ms */, - 3 /* max_send_threshold */, 10000 /* initial_backoff_ms */, - 2.0 /* multiply_factor */, 0.0 /* jitter_factor */, - 150000 /* maximum_backoff_ms */, - false /* reserve_sending_time_for_next_request*/); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(url, URLFetcher::GET, context_getter); - delegate.fetcher()->SetAutomaticallyRetryOn5xx(false); - delegate.fetcher()->SetMaxRetriesOn5xx(11); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(503, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_FALSE(data.empty()); - EXPECT_GT(delegate.fetcher()->GetBackoffDelay().InMicroseconds(), 0); - - // The request should not have been retried at all. If it had attempted all - // 11 retries, that should have taken 2.5 minutes. - EXPECT_TRUE(Time::Now() - start_time < base::Minutes(1)); -} - -// Used to check if a callback has been invoked. -void SetBoolToTrue(bool* ptr) { - *ptr = true; -} - -// Make sure that the URLFetcher cancels the URLRequest and releases its context -// getter pointer synchronously when the fetcher and request context live on -// the same thread. -TEST_F(URLFetcherTest, CancelSameThread) { - WaitingURLFetcherDelegate delegate; - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - bool getter_was_destroyed = false; - context_getter->set_on_destruction_callback( - base::BindOnce(&SetBoolToTrue, &getter_was_destroyed)); - delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - - // The getter won't be destroyed if the test holds on to a reference to it. - context_getter = nullptr; - - delegate.fetcher()->Start(); - // Give the fetcher a chance to start the request. - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores()); - - // On same-thread cancel, the request should be canceled and getter destroyed - // synchronously, for safe shutdown. - delegate.CancelFetch(); - EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores()); - EXPECT_TRUE(getter_was_destroyed); -} - -// Make sure that the URLFetcher releases its context getter pointer on -// cancellation, cross-thread case. -TEST_F(URLFetcherTest, CancelDifferentThreads) { - base::RunLoop run_loop; - - WaitingURLFetcherDelegate delegate; - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateCrossThreadContextGetter()); - context_getter->set_on_destruction_callback( - base::BindOnce(base::IgnoreResult(&base::SequencedTaskRunner::PostTask), - base::SequencedTaskRunnerHandle::Get(), FROM_HERE, - run_loop.QuitClosure())); - delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - - // The getter won't be destroyed if the test holds on to a reference to it. - context_getter = nullptr; - - delegate.fetcher()->Start(); - delegate.CancelFetch(); - run_loop.Run(); - - EXPECT_FALSE(delegate.did_complete()); -} - -TEST_F(URLFetcherTest, CancelWhileDelayedByThrottleDifferentThreads) { - GURL url = test_server_->GetURL(kDefaultResponsePath); - base::RunLoop run_loop; - - WaitingURLFetcherDelegate delegate; - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateCrossThreadContextGetter()); - context_getter->set_on_destruction_callback( - base::BindOnce(base::IgnoreResult(&base::SequencedTaskRunner::PostTask), - base::SequencedTaskRunnerHandle::Get(), FROM_HERE, - run_loop.QuitClosure())); - delegate.CreateFetcher(url, URLFetcher::GET, context_getter); - - // Register an entry for test url using a sliding window of 400 seconds, and - // max of 1 request. Also simulate a request having just started, so the - // next request will be affected by backoff of ~400 seconds. - context_getter->AddThrottlerEntry( - url, std::string() /* url_id */, 400000 /* sliding_window_period_ms */, - 1 /* max_send_threshold */, 200000 /* initial_backoff_ms */, - 2.0 /* multiply_factor */, 0.0 /* jitter_factor */, - 400000 /* maximum_backoff_ms */, - true /* reserve_sending_time_for_next_request*/); - - // The getter won't be destroyed if the test holds on to a reference to it. - context_getter = nullptr; - - delegate.fetcher()->Start(); - delegate.CancelFetch(); - run_loop.Run(); - - EXPECT_FALSE(delegate.did_complete()); -} - -// A URLFetcherDelegate that expects to receive a response body of "request1" -// and then reuses the fetcher for the same URL, setting the "test" request -// header to "request2". -class ReuseFetcherDelegate : public WaitingURLFetcherDelegate { - public: - // |second_request_context_getter| is the context getter used for the second - // request. Can't reuse the old one because fetchers release it on completion. - ReuseFetcherDelegate( - scoped_refptr<URLRequestContextGetter> second_request_context_getter) - : second_request_context_getter_(second_request_context_getter) {} - - ReuseFetcherDelegate(const ReuseFetcherDelegate&) = delete; - ReuseFetcherDelegate& operator=(const ReuseFetcherDelegate&) = delete; - - ~ReuseFetcherDelegate() override = default; - - void OnURLFetchComplete(const URLFetcher* source) override { - EXPECT_EQ(fetcher(), source); - if (!first_request_complete_) { - first_request_complete_ = true; - EXPECT_EQ(OK, fetcher()->GetError()); - EXPECT_EQ(200, fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(fetcher()->GetResponseAsString(&data)); - EXPECT_EQ("request1", data); - - fetcher()->SetRequestContext(second_request_context_getter_.get()); - fetcher()->ClearExtraRequestHeaders(); - fetcher()->AddExtraRequestHeader("test", "request2"); - fetcher()->Start(); - return; - } - WaitingURLFetcherDelegate::OnURLFetchComplete(source); - } - - private: - bool first_request_complete_ = false; - scoped_refptr<URLRequestContextGetter> second_request_context_getter_; -}; - -TEST_F(URLFetcherTest, ReuseFetcherForSameURL) { - // TODO(mmenke): It's really weird that this is supported, particularly - // some fields can be modified between requests, but some (Like upload body) - // cannot be. Can we get rid of support for this? - scoped_refptr<URLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - ReuseFetcherDelegate delegate(context_getter); - delegate.CreateFetcher(test_server_->GetURL("/echoheader?test"), - URLFetcher::GET, context_getter); - delegate.fetcher()->ClearExtraRequestHeaders(); - delegate.fetcher()->AddExtraRequestHeader("test", "request1"); - delegate.StartFetcherAndWait(); - - EXPECT_EQ(OK, delegate.fetcher()->GetError()); - EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); - std::string data; - ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_EQ("request2", data); -} - -TEST_F(URLFetcherTest, ShutdownSameThread) { - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateSameThreadContextGetter()); - - // Create a fetcher and wait for it to create a request. - WaitingURLFetcherDelegate delegate1; - delegate1.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - delegate1.fetcher()->Start(); - // Need to spin the loop to ensure the URLRequest is created and started. - base::RunLoop().RunUntilIdle(); - - // Create and start another fetcher, but don't wait for it to start. The task - // to start the request should be in the message loop. - WaitingURLFetcherDelegate delegate2; - delegate2.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - delegate2.fetcher()->Start(); - - // Check that shutting down the getter cancels the request synchronously, - // allowing the context to be destroyed. - context_getter->Shutdown(); - - // Wait for the first fetcher, make sure it failed. - delegate1.WaitForComplete(); - EXPECT_THAT(delegate1.fetcher()->GetError(), IsError(ERR_CONTEXT_SHUT_DOWN)); - - // Wait for the second fetcher, make sure it failed. - delegate2.WaitForComplete(); - EXPECT_THAT(delegate2.fetcher()->GetError(), IsError(ERR_CONTEXT_SHUT_DOWN)); - - // New fetchers should automatically fail without making new requests. This - // should follow the same path as the second fetcher, but best to be safe. - WaitingURLFetcherDelegate delegate3; - delegate3.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - delegate3.fetcher()->Start(); - delegate3.WaitForComplete(); - EXPECT_THAT(delegate3.fetcher()->GetError(), IsError(ERR_CONTEXT_SHUT_DOWN)); -} - -TEST_F(URLFetcherTest, ShutdownCrossThread) { - scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( - CreateCrossThreadContextGetter()); - - WaitingURLFetcherDelegate delegate1; - delegate1.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - delegate1.fetcher()->Start(); - // Check that shutting the context getter lets the context be destroyed safely - // and cancels the request. - context_getter->Shutdown(); - delegate1.WaitForComplete(); - EXPECT_THAT(delegate1.fetcher()->GetError(), IsError(ERR_CONTEXT_SHUT_DOWN)); - - // New requests should automatically fail without making new requests. - WaitingURLFetcherDelegate delegate2; - delegate2.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter); - delegate2.StartFetcherAndWait(); - EXPECT_THAT(delegate2.fetcher()->GetError(), IsError(ERR_CONTEXT_SHUT_DOWN)); -} - -// Get a small file. -TEST_F(URLFetcherTest, FileTestSmallGet) { - const char kFileToFetch[] = "simple.html"; - - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - base::FilePath out_path = temp_dir.GetPath().AppendASCII(kFileToFetch); - SaveFileTest(kFileToFetch, false, out_path, false); -} - -// Get a file large enough to require more than one read into URLFetcher::Core's -// IOBuffer. -TEST_F(URLFetcherTest, FileTestLargeGet) { - const char kFileToFetch[] = "animate1.gif"; - - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - base::FilePath out_path = temp_dir.GetPath().AppendASCII(kFileToFetch); - SaveFileTest(kFileToFetch, false, out_path, false); -} - -// If the caller takes the ownership of the output file, the file should persist -// even after URLFetcher is gone. -TEST_F(URLFetcherTest, FileTestTakeOwnership) { - const char kFileToFetch[] = "simple.html"; - - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - base::FilePath out_path = temp_dir.GetPath().AppendASCII(kFileToFetch); - SaveFileTest(kFileToFetch, false, out_path, true); -} - -// Test that an existing file can be overwritten be a fetcher. -TEST_F(URLFetcherTest, FileTestOverwriteExisting) { - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - // Create a file before trying to fetch. - const char kFileToFetch[] = "simple.html"; - std::string data(10000, '?'); // Meant to be larger than simple.html. - base::FilePath out_path = temp_dir.GetPath().AppendASCII(kFileToFetch); - ASSERT_EQ(static_cast<int>(data.size()), - base::WriteFile(out_path, data.data(), data.size())); - ASSERT_TRUE(base::PathExists(out_path)); - - SaveFileTest(kFileToFetch, false, out_path, true); -} - -// Test trying to overwrite a directory with a file when using a fetcher fails. -TEST_F(URLFetcherTest, FileTestTryToOverwriteDirectory) { - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - // Create a directory before trying to fetch. - static const char kFileToFetch[] = "simple.html"; - base::FilePath out_path = temp_dir.GetPath().AppendASCII(kFileToFetch); - ASSERT_TRUE(base::CreateDirectory(out_path)); - ASSERT_TRUE(base::PathExists(out_path)); - - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher( - test_server_->GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), - URLFetcher::GET, CreateSameThreadContextGetter()); - delegate.fetcher()->SaveResponseToFileAtPath( - out_path, scoped_refptr<base::SequencedTaskRunner>( - base::SequencedTaskRunnerHandle::Get())); - delegate.StartFetcherAndWait(); - - EXPECT_THAT(delegate.fetcher()->GetError(), IsError(ERR_ACCESS_DENIED)); -} - -// Get a small file and save it to a temp file. -TEST_F(URLFetcherTest, TempFileTestSmallGet) { - SaveFileTest("simple.html", true, base::FilePath(), false); -} - -// Get a file large enough to require more than one read into URLFetcher::Core's -// IOBuffer and save it to a temp file. -TEST_F(URLFetcherTest, TempFileTestLargeGet) { - SaveFileTest("animate1.gif", true, base::FilePath(), false); -} - -// If the caller takes the ownership of the temp file, check that the file -// persists even after URLFetcher is gone. -TEST_F(URLFetcherTest, TempFileTestTakeOwnership) { - SaveFileTest("simple.html", true, base::FilePath(), true); -} - -TEST_F(URLFetcherBadHTTPSTest, BadHTTPS) { - WaitingURLFetcherDelegate delegate; - delegate.CreateFetcher(test_server_->GetURL(kDefaultResponsePath), - URLFetcher::GET, CreateSameThreadContextGetter()); - delegate.StartFetcherAndWait(); - - EXPECT_THAT(delegate.fetcher()->GetError(), IsError(ERR_ABORTED)); - EXPECT_EQ(-1, delegate.fetcher()->GetResponseCode()); - EXPECT_FALSE(delegate.fetcher()->GetResponseHeaders()); - std::string data; - EXPECT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); - EXPECT_TRUE(data.empty()); -} - -} // namespace - -} // namespace net diff --git a/chromium/net/url_request/url_fetcher_response_writer.cc b/chromium/net/url_request/url_fetcher_response_writer.cc deleted file mode 100644 index b3064d92038..00000000000 --- a/chromium/net/url_request/url_fetcher_response_writer.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2013 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 "net/url_request/url_fetcher_response_writer.h" - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/location.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/task_runner_util.h" -#include "net/base/file_stream.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" - -namespace net { - -URLFetcherStringWriter* URLFetcherResponseWriter::AsStringWriter() { - return nullptr; -} - -URLFetcherFileWriter* URLFetcherResponseWriter::AsFileWriter() { - return nullptr; -} - -URLFetcherStringWriter::URLFetcherStringWriter() = default; - -URLFetcherStringWriter::~URLFetcherStringWriter() = default; - -int URLFetcherStringWriter::Initialize(CompletionOnceCallback callback) { - data_.clear(); - return OK; -} - -int URLFetcherStringWriter::Write(IOBuffer* buffer, - int num_bytes, - CompletionOnceCallback callback) { - data_.append(buffer->data(), num_bytes); - return num_bytes; -} - -int URLFetcherStringWriter::Finish(int net_error, - CompletionOnceCallback callback) { - // Do nothing. - return OK; -} - -URLFetcherStringWriter* URLFetcherStringWriter::AsStringWriter() { - return this; -} - -URLFetcherFileWriter::URLFetcherFileWriter( - scoped_refptr<base::SequencedTaskRunner> file_task_runner, - const base::FilePath& file_path) - : file_task_runner_(file_task_runner), file_path_(file_path) { - DCHECK(file_task_runner_.get()); -} - -URLFetcherFileWriter::~URLFetcherFileWriter() { - CloseAndDeleteFile(); -} - -int URLFetcherFileWriter::Initialize(CompletionOnceCallback callback) { - DCHECK(!callback_); - - file_stream_ = std::make_unique<FileStream>(file_task_runner_); - - int result = ERR_IO_PENDING; - owns_file_ = true; - if (file_path_.empty()) { - base::FilePath* temp_file_path = new base::FilePath; - base::PostTaskAndReplyWithResult( - file_task_runner_.get(), FROM_HERE, - base::BindOnce(&base::CreateTemporaryFile, temp_file_path), - base::BindOnce(&URLFetcherFileWriter::DidCreateTempFile, - weak_factory_.GetWeakPtr(), - base::Owned(temp_file_path))); - } else { - result = - file_stream_->Open(file_path_, - base::File::FLAG_WRITE | base::File::FLAG_ASYNC | - base::File::FLAG_CREATE_ALWAYS, - base::BindOnce(&URLFetcherFileWriter::OnIOCompleted, - weak_factory_.GetWeakPtr())); - DCHECK_NE(OK, result); - } - - if (result == ERR_IO_PENDING) { - callback_ = std::move(callback); - return result; - } - if (result < 0) - CloseAndDeleteFile(); - return result; -} - -int URLFetcherFileWriter::Write(IOBuffer* buffer, - int num_bytes, - CompletionOnceCallback callback) { - DCHECK(file_stream_) << "Call Initialize() first."; - DCHECK(owns_file_); - DCHECK(!callback_); - - int result = - file_stream_->Write(buffer, num_bytes, - base::BindOnce(&URLFetcherFileWriter::OnIOCompleted, - weak_factory_.GetWeakPtr())); - if (result == ERR_IO_PENDING) { - callback_ = std::move(callback); - return result; - } - if (result < 0) - CloseAndDeleteFile(); - return result; -} - -int URLFetcherFileWriter::Finish(int net_error, - CompletionOnceCallback callback) { - DCHECK_NE(ERR_IO_PENDING, net_error); - - // If an error occurred, simply delete the file after any pending operation - // is done. Do not call file_stream_->Close() because there might be an - // operation pending. See crbug.com/487732. - if (net_error < 0) { - // Cancel callback and invalid weak ptrs so as to cancel any posted task. - callback_.Reset(); - weak_factory_.InvalidateWeakPtrs(); - CloseAndDeleteFile(); - return OK; - } - DCHECK(!callback_); - // If the file_stream_ still exists at this point, close it. - if (file_stream_) { - int result = file_stream_->Close(base::BindOnce( - &URLFetcherFileWriter::CloseComplete, weak_factory_.GetWeakPtr())); - if (result == ERR_IO_PENDING) { - callback_ = std::move(callback); - return result; - } - file_stream_.reset(); - return result; - } - return OK; -} - -URLFetcherFileWriter* URLFetcherFileWriter::AsFileWriter() { - return this; -} - -void URLFetcherFileWriter::DisownFile() { - // Disowning is done by the delegate's OnURLFetchComplete method. - // The file should be closed by the time that method is called. - DCHECK(!file_stream_); - - owns_file_ = false; -} - -void URLFetcherFileWriter::CloseAndDeleteFile() { - if (!owns_file_) - return; - - file_stream_.reset(); - DisownFile(); - file_task_runner_->PostTask(FROM_HERE, - base::GetDeleteFileCallback(file_path_)); -} - -void URLFetcherFileWriter::DidCreateTempFile(base::FilePath* temp_file_path, - bool success) { - if (!success) { - OnIOCompleted(ERR_FILE_NOT_FOUND); - return; - } - file_path_ = *temp_file_path; - const int result = file_stream_->Open( - file_path_, - base::File::FLAG_WRITE | base::File::FLAG_ASYNC | base::File::FLAG_OPEN, - base::BindOnce(&URLFetcherFileWriter::OnIOCompleted, - weak_factory_.GetWeakPtr())); - if (result != ERR_IO_PENDING) - OnIOCompleted(result); -} - -void URLFetcherFileWriter::OnIOCompleted(int result) { - if (result < OK) - CloseAndDeleteFile(); - - if (!callback_.is_null()) - std::move(callback_).Run(result); -} - -void URLFetcherFileWriter::CloseComplete(int result) { - // Destroy |file_stream_| whether or not the close succeeded. - file_stream_.reset(); - if (!callback_.is_null()) - std::move(callback_).Run(result); -} - -} // namespace net diff --git a/chromium/net/url_request/url_fetcher_response_writer.h b/chromium/net/url_request/url_fetcher_response_writer.h deleted file mode 100644 index 474087c35fa..00000000000 --- a/chromium/net/url_request/url_fetcher_response_writer.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2013 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 NET_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_ -#define NET_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_ - -#include <memory> -#include <string> - -#include "base/files/file_path.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "net/base/completion_once_callback.h" -#include "net/base/net_export.h" - -namespace base { -class SequencedTaskRunner; -} // namespace base - -namespace net { - -class FileStream; -class IOBuffer; -class URLFetcherFileWriter; -class URLFetcherStringWriter; - -// This class encapsulates all state involved in writing URLFetcher response -// bytes to the destination. -class NET_EXPORT URLFetcherResponseWriter { - public: - virtual ~URLFetcherResponseWriter() {} - - // Initializes this instance. Returns an error code defined in - // //net/base/net_errors.h. If ERR_IO_PENDING is returned, |callback| will be - // run later with the result. If anything else is returned, |callback| will - // *not* be called. Calling this method again after a Initialize() success - // results in discarding already written data. - virtual int Initialize(CompletionOnceCallback callback) = 0; - - // Writes |num_bytes| bytes in |buffer|, and returns the number of bytes - // written or an error code defined in //net/base/net_errors.h. If - // ERR_IO_PENDING is returned, |callback| will be run later with the result. - // If anything else is returned, |callback| will *not* be called. - virtual int Write(IOBuffer* buffer, - int num_bytes, - CompletionOnceCallback callback) = 0; - - // Finishes writing. If |net_error| is not OK, this method can be called - // in the middle of another operation (eg. Initialize() and Write()). On - // errors (|net_error| not OK), this method may be called before the previous - // operation completed. In this case, URLFetcherResponseWriter may skip - // graceful shutdown and completion of the pending operation. After such a - // failure, the URLFetcherResponseWriter may be reused. Returns an error code - // defined in //net/base/net_errors.h. If ERR_IO_PENDING is returned, - // |callback| will be run later with the result. If anything else is returned, - // |callback| will *not* be called. - virtual int Finish(int net_error, CompletionOnceCallback callback) = 0; - - // Returns this instance's pointer as URLFetcherStringWriter when possible. - virtual URLFetcherStringWriter* AsStringWriter(); - - // Returns this instance's pointer as URLFetcherFileWriter when possible. - virtual URLFetcherFileWriter* AsFileWriter(); -}; - -// URLFetcherResponseWriter implementation for std::string. -class NET_EXPORT URLFetcherStringWriter : public URLFetcherResponseWriter { - public: - URLFetcherStringWriter(); - - URLFetcherStringWriter(const URLFetcherStringWriter&) = delete; - URLFetcherStringWriter& operator=(const URLFetcherStringWriter&) = delete; - - ~URLFetcherStringWriter() override; - - const std::string& data() const { return data_; } - - // URLFetcherResponseWriter overrides: - int Initialize(CompletionOnceCallback callback) override; - int Write(IOBuffer* buffer, - int num_bytes, - CompletionOnceCallback callback) override; - int Finish(int net_error, CompletionOnceCallback callback) override; - URLFetcherStringWriter* AsStringWriter() override; - - private: - std::string data_; -}; - -// URLFetcherResponseWriter implementation for files. -class NET_EXPORT URLFetcherFileWriter : public URLFetcherResponseWriter { - public: - // |file_path| is used as the destination path. If |file_path| is empty, - // Initialize() will create a temporary file. The destination file is deleted - // when a URLFetcherFileWriter instance is destructed unless DisownFile() is - // called. - URLFetcherFileWriter( - scoped_refptr<base::SequencedTaskRunner> file_task_runner, - const base::FilePath& file_path); - - URLFetcherFileWriter(const URLFetcherFileWriter&) = delete; - URLFetcherFileWriter& operator=(const URLFetcherFileWriter&) = delete; - - ~URLFetcherFileWriter() override; - - const base::FilePath& file_path() const { return file_path_; } - - // URLFetcherResponseWriter overrides: - int Initialize(CompletionOnceCallback callback) override; - int Write(IOBuffer* buffer, - int num_bytes, - CompletionOnceCallback callback) override; - int Finish(int net_error, CompletionOnceCallback callback) override; - URLFetcherFileWriter* AsFileWriter() override; - - // Drops ownership of the file at |file_path_|. - // This class will not delete it or write to it again. - void DisownFile(); - - private: - // Closes the file if it is open and then delete it. - void CloseAndDeleteFile(); - - // Callback which gets the result of a temporary file creation. - void DidCreateTempFile(base::FilePath* temp_file_path, bool success); - - // Run |callback_| if it is non-null when FileStream::Open or - // FileStream::Write is completed. - void OnIOCompleted(int result); - - // Callback which gets the result of closing a file. - void CloseComplete(int result); - - // Task runner on which file operations should happen. - scoped_refptr<base::SequencedTaskRunner> file_task_runner_; - - // Destination file path. - // Initialize() creates a temporary file if this variable is empty. - base::FilePath file_path_; - - // True when this instance is responsible to delete the file at |file_path_|. - bool owns_file_ = false; - - std::unique_ptr<FileStream> file_stream_; - - CompletionOnceCallback callback_; - - base::WeakPtrFactory<URLFetcherFileWriter> weak_factory_{this}; -}; - -} // namespace net - -#endif // NET_URL_REQUEST_URL_FETCHER_RESPONSE_WRITER_H_ diff --git a/chromium/net/url_request/url_fetcher_response_writer_unittest.cc b/chromium/net/url_request/url_fetcher_response_writer_unittest.cc deleted file mode 100644 index 89faf9786fa..00000000000 --- a/chromium/net/url_request/url_fetcher_response_writer_unittest.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2014 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 "net/url_request/url_fetcher_response_writer.h" - -#include <memory> - -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/base/test_completion_callback.h" -#include "net/test/gtest_util.h" -#include "net/test/test_with_task_environment.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/platform_test.h" - -using net::test::IsOk; - -namespace net { - -namespace { - -const char kData[] = "Hello!"; - -} // namespace - -class URLFetcherStringWriterTest : public PlatformTest { - protected: - void SetUp() override { - writer_ = std::make_unique<URLFetcherStringWriter>(); - buf_ = base::MakeRefCounted<StringIOBuffer>(kData); - } - - std::unique_ptr<URLFetcherStringWriter> writer_; - scoped_refptr<StringIOBuffer> buf_; -}; - -TEST_F(URLFetcherStringWriterTest, Basic) { - int rv = 0; - // Initialize(), Write() and Finish(). - TestCompletionCallback callback; - rv = writer_->Initialize(callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - rv = writer_->Write(buf_.get(), buf_->size(), callback.callback()); - EXPECT_EQ(buf_->size(), callback.GetResult(rv)); - rv = writer_->Finish(OK, callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - - // Verify the result. - EXPECT_EQ(kData, writer_->data()); - - // Initialize() again to reset. - rv = writer_->Initialize(callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - EXPECT_TRUE(writer_->data().empty()); -} - -class URLFetcherFileWriterTest : public PlatformTest, - public WithTaskEnvironment { - protected: - void SetUp() override { - PlatformTest::SetUp(); - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - file_path_ = temp_dir_.GetPath().AppendASCII("test.txt"); - writer_ = std::make_unique<URLFetcherFileWriter>( - base::ThreadTaskRunnerHandle::Get(), file_path_); - buf_ = base::MakeRefCounted<StringIOBuffer>(kData); - } - - void TearDown() override { - ASSERT_TRUE(temp_dir_.Delete()); - PlatformTest::TearDown(); - } - - base::ScopedTempDir temp_dir_; - base::FilePath file_path_; - std::unique_ptr<URLFetcherFileWriter> writer_; - scoped_refptr<StringIOBuffer> buf_; -}; - -TEST_F(URLFetcherFileWriterTest, WriteToFile) { - int rv = 0; - // Initialize(), Write() and Finish(). - TestCompletionCallback callback; - rv = writer_->Initialize(callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - rv = writer_->Write(buf_.get(), buf_->size(), callback.callback()); - EXPECT_EQ(buf_->size(), callback.GetResult(rv)); - rv = writer_->Finish(OK, callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - - // Verify the result. - EXPECT_EQ(file_path_.value(), writer_->file_path().value()); - std::string file_contents; - EXPECT_TRUE(base::ReadFileToString(writer_->file_path(), &file_contents)); - EXPECT_EQ(kData, file_contents); - - // Destroy the writer. File should be deleted. - writer_.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(base::PathExists(file_path_)); -} - -TEST_F(URLFetcherFileWriterTest, InitializeAgain) { - int rv = 0; - // Initialize(), Write() and Finish(). - TestCompletionCallback callback; - rv = writer_->Initialize(callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - rv = writer_->Write(buf_.get(), buf_->size(), callback.callback()); - EXPECT_EQ(buf_->size(), callback.GetResult(rv)); - rv = writer_->Finish(OK, callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - - // Verify the result. - std::string file_contents; - EXPECT_TRUE(base::ReadFileToString(writer_->file_path(), &file_contents)); - EXPECT_EQ(kData, file_contents); - - // Initialize() again to reset. Write different data. - const std::string data2 = "Bye!"; - scoped_refptr<StringIOBuffer> buf2 = - base::MakeRefCounted<StringIOBuffer>(data2); - - rv = writer_->Initialize(callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - rv = writer_->Write(buf2.get(), buf2->size(), callback.callback()); - EXPECT_EQ(buf2->size(), callback.GetResult(rv)); - rv = writer_->Finish(OK, callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - - // Verify the result. - file_contents.clear(); - EXPECT_TRUE(base::ReadFileToString(writer_->file_path(), &file_contents)); - EXPECT_EQ(data2, file_contents); -} - -TEST_F(URLFetcherFileWriterTest, FinishWhileWritePending) { - int rv = 0; - // Initialize(), Write() and Finish(). - TestCompletionCallback callback; - rv = writer_->Initialize(callback.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - EXPECT_THAT(callback.WaitForResult(), IsOk()); - TestCompletionCallback callback2; - rv = writer_->Write(buf_.get(), buf_->size(), callback2.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - TestCompletionCallback callback3; - rv = writer_->Finish(ERR_FAILED, callback3.callback()); - EXPECT_EQ(OK, rv); - - base::RunLoop().RunUntilIdle(); - // Verify the result. - EXPECT_FALSE(base::PathExists(file_path_)); -} - -TEST_F(URLFetcherFileWriterTest, FinishWhileOpenPending) { - int rv = 0; - // Initialize() and Finish(). - TestCompletionCallback callback; - rv = writer_->Initialize(callback.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - TestCompletionCallback callback2; - rv = writer_->Finish(ERR_FAILED, callback2.callback()); - EXPECT_EQ(OK, rv); - - base::RunLoop().RunUntilIdle(); - // Verify the result. - EXPECT_FALSE(base::PathExists(file_path_)); -} - -TEST_F(URLFetcherFileWriterTest, InitializeAgainAfterFinishWithError) { - int rv = 0; - // Initialize(), Write() and Finish(). - TestCompletionCallback callback; - rv = writer_->Initialize(callback.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - EXPECT_THAT(callback.WaitForResult(), IsOk()); - TestCompletionCallback callback2; - rv = writer_->Write(buf_.get(), buf_->size(), callback2.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - TestCompletionCallback callback3; - rv = writer_->Finish(ERR_FAILED, callback3.callback()); - EXPECT_EQ(OK, rv); - - base::RunLoop().RunUntilIdle(); - // Initialize() again and wait for it to complete. - TestCompletionCallback callback4; - rv = writer_->Initialize(callback4.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - EXPECT_THAT(callback4.WaitForResult(), IsOk()); - // Verify the result. - EXPECT_TRUE(base::PathExists(file_path_)); - - // Destroy the writer and allow all files to be closed. - writer_.reset(); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(URLFetcherFileWriterTest, DisownFile) { - int rv = 0; - // Initialize() and Finish() to create a file. - TestCompletionCallback callback; - rv = writer_->Initialize(callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - rv = writer_->Finish(OK, callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - - // Disown file. - writer_->DisownFile(); - - // File is not deleted even after the writer gets destroyed. - writer_.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(base::PathExists(file_path_)); -} - -class URLFetcherFileWriterTemporaryFileTest : public PlatformTest, - public WithTaskEnvironment { - protected: - void SetUp() override { - writer_ = std::make_unique<URLFetcherFileWriter>( - base::ThreadTaskRunnerHandle::Get(), base::FilePath()); - buf_ = base::MakeRefCounted<StringIOBuffer>(kData); - } - - std::unique_ptr<URLFetcherFileWriter> writer_; - scoped_refptr<StringIOBuffer> buf_; -}; - -TEST_F(URLFetcherFileWriterTemporaryFileTest, WriteToTemporaryFile) { - int rv = 0; - // Initialize(), Write() and Finish(). - TestCompletionCallback callback; - rv = writer_->Initialize(callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - rv = writer_->Write(buf_.get(), buf_->size(), callback.callback()); - EXPECT_EQ(buf_->size(), callback.GetResult(rv)); - rv = writer_->Finish(OK, callback.callback()); - EXPECT_THAT(callback.GetResult(rv), IsOk()); - - // Verify the result. - std::string file_contents; - EXPECT_TRUE(base::ReadFileToString(writer_->file_path(), &file_contents)); - EXPECT_EQ(kData, file_contents); - - // Destroy the writer. File should be deleted. - const base::FilePath file_path = writer_->file_path(); - writer_.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(base::PathExists(file_path)); -} - -} // namespace net diff --git a/chromium/net/url_request/url_request.cc b/chromium/net/url_request/url_request.cc index 59c2435ac0c..ccb85ec9ff8 100644 --- a/chromium/net/url_request/url_request.cc +++ b/chromium/net/url_request/url_request.cc @@ -283,37 +283,37 @@ LoadStateWithParam URLRequest::GetLoadState() const { } base::Value URLRequest::GetStateAsValue() const { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("url", original_url().possibly_invalid_spec()); + base::Value::Dict dict; + dict.Set("url", original_url().possibly_invalid_spec()); if (url_chain_.size() > 1) { base::Value list(base::Value::Type::LIST); for (const GURL& url : url_chain_) { list.Append(url.possibly_invalid_spec()); } - dict.SetKey("url_chain", std::move(list)); + dict.Set("url_chain", std::move(list)); } - dict.SetIntKey("load_flags", load_flags_); + dict.Set("load_flags", load_flags_); LoadStateWithParam load_state = GetLoadState(); - dict.SetIntKey("load_state", load_state.state); + dict.Set("load_state", load_state.state); if (!load_state.param.empty()) - dict.SetStringKey("load_state_param", load_state.param); + dict.Set("load_state_param", load_state.param); if (!blocked_by_.empty()) - dict.SetStringKey("delegate_blocked_by", blocked_by_); + dict.Set("delegate_blocked_by", blocked_by_); - dict.SetStringKey("method", method_); - dict.SetStringKey("network_isolation_key", - isolation_info_.network_isolation_key().ToDebugString()); - dict.SetBoolKey("has_upload", has_upload()); - dict.SetBoolKey("is_pending", is_pending_); + dict.Set("method", method_); + dict.Set("network_isolation_key", + isolation_info_.network_isolation_key().ToDebugString()); + dict.Set("has_upload", has_upload()); + dict.Set("is_pending", is_pending_); - dict.SetIntKey("traffic_annotation", traffic_annotation_.unique_id_hash_code); + dict.Set("traffic_annotation", traffic_annotation_.unique_id_hash_code); if (status_ != OK) - dict.SetIntKey("net_error", status_); - return dict; + dict.Set("net_error", status_); + return base::Value(std::move(dict)); } void URLRequest::LogBlockedBy(const char* blocked_by) { @@ -808,6 +808,7 @@ int URLRequest::NotifyConnected(const TransportInfo& info, void URLRequest::NotifyReceivedRedirect(const RedirectInfo& redirect_info, bool* defer_redirect) { + DCHECK_EQ(OK, status_); is_redirecting_ = true; OnCallToDelegate(NetLogEventType::URL_REQUEST_DELEGATE_RECEIVED_REDIRECT); delegate_->OnReceivedRedirect(this, redirect_info, defer_redirect); @@ -1019,6 +1020,7 @@ void URLRequest::SetPriority(RequestPriority priority) { void URLRequest::NotifyAuthRequired( std::unique_ptr<AuthChallengeInfo> auth_info) { + DCHECK_EQ(OK, status_); DCHECK(auth_info); // Check that there are no callbacks to already failed or cancelled requests. DCHECK(!failed()); @@ -1047,9 +1049,7 @@ bool URLRequest::CanSetCookie(const net::CanonicalCookie& cookie, DCHECK(!(load_flags_ & LOAD_DO_NOT_SAVE_COOKIES)); bool can_set_cookies = g_default_can_use_cookies; if (network_delegate()) { - can_set_cookies = - network_delegate()->CanSetCookie(*this, cookie, options, - /*allowed_from_caller=*/true); + can_set_cookies = network_delegate()->CanSetCookie(*this, cookie, options); } if (!can_set_cookies) net_log_.AddEvent(NetLogEventType::COOKIE_SET_BLOCKED_BY_NETWORK_DELEGATE); @@ -1080,6 +1080,10 @@ void URLRequest::NotifyReadCompleted(int bytes_read) { } void URLRequest::OnHeadersComplete() { + // The URLRequest status should still be IO_PENDING, which it was set to + // before the URLRequestJob was started. On error or cancellation, this + // method should not be called. + DCHECK_EQ(ERR_IO_PENDING, status_); set_status(OK); // Cache load timing information now, as information will be lost once the // socket is closed and the ClientSocketHandle is Reset, which will happen diff --git a/chromium/net/url_request/url_request.h b/chromium/net/url_request/url_request.h index 10840b06182..532ce5207e6 100644 --- a/chromium/net/url_request/url_request.h +++ b/chromium/net/url_request/url_request.h @@ -85,13 +85,6 @@ class X509Certificate; // class NET_EXPORT URLRequest : public base::SupportsUserData { public: - // Callback function implemented by protocol handlers to create new jobs. - // The factory may return NULL to indicate an error, which will cause other - // factories to be queried. If no factory handles the request, then the - // default job will be used. - typedef URLRequestJob*(ProtocolFactory)(URLRequest* request, - const std::string& scheme); - // Max number of http redirects to follow. The Fetch spec says: "If // request's redirect count is twenty, return a network error." // https://fetch.spec.whatwg.org/#http-redirect-fetch @@ -208,7 +201,7 @@ class NET_EXPORT URLRequest : public base::SupportsUserData { virtual void OnReadCompleted(URLRequest* request, int bytes_read) = 0; protected: - virtual ~Delegate() {} + virtual ~Delegate() = default; }; URLRequest(const URLRequest&) = delete; @@ -715,12 +708,6 @@ class NET_EXPORT URLRequest : public base::SupportsUserData { return traffic_annotation_; } - bool Supports(const net::SourceStream::SourceType& type) const { - if (!accepted_stream_types_) - return true; - return accepted_stream_types_->contains(type); - } - const absl::optional<base::flat_set<net::SourceStream::SourceType>>& accepted_stream_types() const { return accepted_stream_types_; @@ -1061,8 +1048,8 @@ class NET_EXPORT URLRequest : public base::SupportsUserData { int pervasive_payloads_index_for_logging_ = -1; // A SHA-256 checksum of the response and selected headers, stored as - // upper-case hexadecimal. This is only used if the - // LOAD_USE_SINGLE_KEYED_CACHE flag is set. On failure to match the cache + // upper-case hexadecimal. If this is set to a non-empty value the transaction + // will attempt to use the single-keyed cache. On failure to match the cache // entry will be marked as unusable and will not be re-used. std::string expected_response_checksum_; diff --git a/chromium/net/url_request/url_request_context.cc b/chromium/net/url_request/url_request_context.cc index f14a84efeae..a2fd9ff84a0 100644 --- a/chromium/net/url_request/url_request_context.cc +++ b/chromium/net/url_request/url_request_context.cc @@ -32,7 +32,7 @@ namespace net { URLRequestContext::URLRequestContext( base::PassKey<URLRequestContextBuilder> pass_key) : url_requests_(std::make_unique<std::set<const URLRequest*>>()), - bound_network_(NetworkChangeNotifier::kInvalidNetworkHandle) {} + bound_network_(handles::kInvalidNetworkHandle) {} URLRequestContext::~URLRequestContext() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); diff --git a/chromium/net/url_request/url_request_context.h b/chromium/net/url_request/url_request_context.h index 7795b87134b..68a212dac89 100644 --- a/chromium/net/url_request/url_request_context.h +++ b/chromium/net/url_request/url_request_context.h @@ -21,7 +21,7 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "net/base/net_export.h" -#include "net/base/network_change_notifier.h" +#include "net/base/network_handle.h" #include "net/base/request_priority.h" #include "net/log/net_log_source.h" #include "net/net_buildflags.h" @@ -227,11 +227,9 @@ class NET_EXPORT URLRequestContext { return require_network_isolation_key_; } - // If != NetworkChangeNotifier::kInvalidNetworkHandle, the network which this + // If != handles::kInvalidNetworkHandle, the network which this // context has been bound to. - NetworkChangeNotifier::NetworkHandle bound_network() const { - return bound_network_; - } + handles::NetworkHandle bound_network() const { return bound_network_; } void AssertCalledOnValidThread() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -319,34 +317,42 @@ class NET_EXPORT URLRequestContext { void set_require_network_isolation_key(bool require_network_isolation_key) { require_network_isolation_key_ = require_network_isolation_key; } - void set_bound_network(NetworkChangeNotifier::NetworkHandle network) { + void set_bound_network(handles::NetworkHandle network) { bound_network_ = network; } // Ownership for these members are not defined here. Clients should either // provide storage elsewhere or have a subclass take ownership. raw_ptr<NetLog> net_log_ = nullptr; - raw_ptr<HostResolver> host_resolver_ = nullptr; - raw_ptr<CertVerifier> cert_verifier_ = nullptr; - raw_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_ = nullptr; - raw_ptr<ProxyResolutionService> proxy_resolution_service_ = nullptr; + raw_ptr<HostResolver, DanglingUntriaged> host_resolver_ = nullptr; + raw_ptr<CertVerifier, DanglingUntriaged> cert_verifier_ = nullptr; + raw_ptr<HttpAuthHandlerFactory, DanglingUntriaged> + http_auth_handler_factory_ = nullptr; + raw_ptr<ProxyResolutionService, DanglingUntriaged> proxy_resolution_service_ = + nullptr; raw_ptr<ProxyDelegate> proxy_delegate_ = nullptr; - raw_ptr<SSLConfigService> ssl_config_service_ = nullptr; - raw_ptr<NetworkDelegate> network_delegate_ = nullptr; - raw_ptr<HttpServerProperties> http_server_properties_ = nullptr; - raw_ptr<const HttpUserAgentSettings> http_user_agent_settings_ = nullptr; - raw_ptr<CookieStore> cookie_store_ = nullptr; - raw_ptr<TransportSecurityState> transport_security_state_ = nullptr; - raw_ptr<CTPolicyEnforcer> ct_policy_enforcer_ = nullptr; - raw_ptr<SCTAuditingDelegate> sct_auditing_delegate_ = nullptr; - raw_ptr<HttpTransactionFactory> http_transaction_factory_ = nullptr; - raw_ptr<const URLRequestJobFactory> job_factory_ = nullptr; + raw_ptr<SSLConfigService, DanglingUntriaged> ssl_config_service_ = nullptr; + raw_ptr<NetworkDelegate, DanglingUntriaged> network_delegate_ = nullptr; + raw_ptr<HttpServerProperties, DanglingUntriaged> http_server_properties_ = + nullptr; + raw_ptr<const HttpUserAgentSettings, DanglingUntriaged> + http_user_agent_settings_ = nullptr; + raw_ptr<CookieStore, DanglingUntriaged> cookie_store_ = nullptr; + raw_ptr<TransportSecurityState, DanglingUntriaged> transport_security_state_ = + nullptr; + raw_ptr<CTPolicyEnforcer, DanglingUntriaged> ct_policy_enforcer_ = nullptr; + raw_ptr<SCTAuditingDelegate, DanglingUntriaged> sct_auditing_delegate_ = + nullptr; + raw_ptr<HttpTransactionFactory, DanglingUntriaged> http_transaction_factory_ = + nullptr; + raw_ptr<const URLRequestJobFactory, DanglingUntriaged> job_factory_ = nullptr; raw_ptr<URLRequestThrottlerManager> throttler_manager_ = nullptr; - raw_ptr<QuicContext> quic_context_ = nullptr; + raw_ptr<QuicContext, DanglingUntriaged> quic_context_ = nullptr; raw_ptr<NetworkQualityEstimator> network_quality_estimator_ = nullptr; #if BUILDFLAG(ENABLE_REPORTING) - raw_ptr<ReportingService> reporting_service_ = nullptr; - raw_ptr<NetworkErrorLoggingService> network_error_logging_service_ = nullptr; + raw_ptr<ReportingService, DanglingUntriaged> reporting_service_ = nullptr; + raw_ptr<NetworkErrorLoggingService, DanglingUntriaged> + network_error_logging_service_ = nullptr; #endif // BUILDFLAG(ENABLE_REPORTING) std::unique_ptr<std::set<const URLRequest*>> url_requests_; @@ -361,7 +367,7 @@ class NET_EXPORT URLRequestContext { // a request when true. bool require_network_isolation_key_ = false; - NetworkChangeNotifier::NetworkHandle bound_network_; + handles::NetworkHandle bound_network_; THREAD_CHECKER(thread_checker_); }; diff --git a/chromium/net/url_request/url_request_context_builder.cc b/chromium/net/url_request/url_request_context_builder.cc index d8a383a69dd..50c1b5a964d 100644 --- a/chromium/net/url_request/url_request_context_builder.cc +++ b/chromium/net/url_request/url_request_context_builder.cc @@ -310,7 +310,8 @@ void URLRequestContextBuilder::SetCreateHttpTransactionFactoryCallback( } void URLRequestContextBuilder::BindToNetwork( - NetworkChangeNotifier::NetworkHandle network) { + handles::NetworkHandle network, + absl::optional<HostResolver::ManagerOptions> options) { #if BUILDFLAG(IS_ANDROID) DCHECK(NetworkChangeNotifier::AreNetworkHandlesSupported()); // DNS lookups for this context will need to target `network`. NDK to do that @@ -321,6 +322,7 @@ void URLRequestContextBuilder::BindToNetwork( CHECK(base::android::BuildInfo::GetInstance()->sdk_int() >= base::android::SDK_VERSION_MARSHMALLOW); bound_network_ = network; + manager_options_ = options.value_or(manager_options_); #else NOTIMPLEMENTED(); #endif // BUILDFLAG(IS_ANDROID) @@ -356,8 +358,8 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() { context->set_net_log(NetLog::Get()); } - if (bound_network_ != NetworkChangeNotifier::kInvalidNetworkHandle) { - DCHECK(!client_socket_factory_); + if (bound_network_ != handles::kInvalidNetworkHandle) { + DCHECK(!client_socket_factory_raw_); DCHECK(!host_resolver_); DCHECK(!host_resolver_manager_); DCHECK(!host_resolver_factory_); @@ -371,11 +373,8 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() { set_client_socket_factory(client_socket_factory.get()); storage->set_client_socket_factory(std::move(client_socket_factory)); - HostResolver::ManagerOptions manager_options; - manager_options.insecure_dns_client_enabled = false; - manager_options.additional_types_via_insecure_dns_enabled = false; host_resolver_ = HostResolver::CreateStandaloneNetworkBoundResolver( - context->net_log(), bound_network_, manager_options); + context->net_log(), bound_network_, manager_options_); if (!quic_context_) set_quic_context(std::make_unique<QuicContext>()); @@ -394,6 +393,10 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() { http_network_session_params_.ignore_ip_address_changes = true; } + if (client_socket_factory_) { + storage->set_client_socket_factory(std::move(client_socket_factory_)); + } + if (host_resolver_) { DCHECK(host_mapping_rules_.empty()); DCHECK(!host_resolver_manager_); @@ -440,8 +443,8 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() { if (cookie_store_set_by_client_) { storage->set_cookie_store(std::move(cookie_store_)); } else { - std::unique_ptr<CookieStore> cookie_store(new CookieMonster( - nullptr /* store */, context->net_log(), first_party_sets_enabled_)); + auto cookie_store = std::make_unique<CookieMonster>( + nullptr /* store */, context->net_log(), first_party_sets_enabled_); storage->set_cookie_store(std::move(cookie_store)); } @@ -502,11 +505,11 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() { if (!proxy_resolution_service_) { #if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID) // TODO(willchan): Switch to using this code when - // ConfiguredProxyResolutionService::CreateSystemProxyConfigService()'s + // ProxyConfigService::CreateSystemProxyConfigService()'s // signature doesn't suck. if (!proxy_config_service_) { proxy_config_service_ = - ConfiguredProxyResolutionService::CreateSystemProxyConfigService( + ProxyConfigService::CreateSystemProxyConfigService( base::ThreadTaskRunnerHandle::Get().get()); } #endif // !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) && @@ -567,7 +570,7 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() { SetHttpNetworkSessionComponents( context.get(), &network_session_context, suppress_setting_socket_performance_watcher_factory_for_testing_, - client_socket_factory_); + client_socket_factory_raw_); storage->set_http_network_session(std::make_unique<HttpNetworkSession>( http_network_session_params_, network_session_context)); diff --git a/chromium/net/url_request/url_request_context_builder.h b/chromium/net/url_request/url_request_context_builder.h index 572a7642eab..cec74606d04 100644 --- a/chromium/net/url_request/url_request_context_builder.h +++ b/chromium/net/url_request/url_request_context_builder.h @@ -30,8 +30,8 @@ #include "build/build_config.h" #include "build/buildflag.h" #include "net/base/net_export.h" -#include "net/base/network_change_notifier.h" #include "net/base/network_delegate.h" +#include "net/base/network_handle.h" #include "net/base/proxy_delegate.h" #include "net/disk_cache/disk_cache.h" #include "net/dns/host_resolver.h" @@ -40,15 +40,14 @@ #include "net/network_error_logging/network_error_logging_service.h" #include "net/proxy_resolution/proxy_config_service.h" #include "net/proxy_resolution/proxy_resolution_service.h" +#include "net/socket/client_socket_factory.h" #include "net/ssl/ssl_config_service.h" #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h" #include "net/url_request/url_request_job_factory.h" -namespace base { -namespace android { +namespace base::android { class ApplicationStatusListener; -} -} // namespace base +} // namespace base::android namespace net { @@ -345,14 +344,24 @@ class NET_EXPORT URLRequestContextBuilder { set_client_socket_factory(client_socket_factory_for_testing); } + // Sets a ClientSocketFactory when the network service sandbox is enabled. The + // unique_ptr is moved to a URLRequestContextStorage once Build() is called. + void set_client_socket_factory( + std::unique_ptr<ClientSocketFactory> client_socket_factory) { + set_client_socket_factory(client_socket_factory.get()); + client_socket_factory_ = std::move(client_socket_factory); + } + // Binds the context to `network`. All requests scheduled through the context // built by this builder will be sent using `network`. Requests will fail if - // `network` disconnects. + // `network` disconnects. `options` allows to specify the ManagerOptions that + // will be passed to the special purpose HostResolver created internally. // This also imposes some limitations on the context capabilities: - // * Currently, URLs will only be resolved using the System DNS. // * By design, QUIC connection migration will be turned off. // Only implemented for Android (API level > 23). - void BindToNetwork(NetworkChangeNotifier::NetworkHandle network); + void BindToNetwork( + handles::NetworkHandle network, + absl::optional<HostResolver::ManagerOptions> options = absl::nullopt); // Creates a mostly self-contained URLRequestContext. May only be called once // per URLRequestContextBuilder. After this is called, the Builder can be @@ -391,7 +400,7 @@ class NET_EXPORT URLRequestContextBuilder { // URLRequestContext that will be built. // `client_socket_factory` must outlive the context. void set_client_socket_factory(ClientSocketFactory* client_socket_factory) { - client_socket_factory_ = client_socket_factory; + client_socket_factory_raw_ = client_socket_factory; } bool enable_brotli_ = false; @@ -409,8 +418,10 @@ class NET_EXPORT URLRequestContextBuilder { bool suppress_setting_socket_performance_watcher_factory_for_testing_ = false; bool first_party_sets_enabled_ = false; - NetworkChangeNotifier::NetworkHandle bound_network_ = - NetworkChangeNotifier::kInvalidNetworkHandle; + handles::NetworkHandle bound_network_ = handles::kInvalidNetworkHandle; + // Used only if the context is bound to a network to customize the + // HostResolver created internally. + HostResolver::ManagerOptions manager_options_; HttpCacheParams http_cache_params_; HttpNetworkSessionParams http_network_session_params_; @@ -435,6 +446,7 @@ class NET_EXPORT URLRequestContextBuilder { std::unique_ptr<CTPolicyEnforcer> ct_policy_enforcer_; std::unique_ptr<SCTAuditingDelegate> sct_auditing_delegate_; std::unique_ptr<QuicContext> quic_context_; + std::unique_ptr<ClientSocketFactory> client_socket_factory_ = nullptr; #if BUILDFLAG(ENABLE_REPORTING) std::unique_ptr<ReportingService> reporting_service_; std::unique_ptr<ReportingPolicy> reporting_policy_; @@ -447,7 +459,7 @@ class NET_EXPORT URLRequestContextBuilder { std::map<std::string, std::unique_ptr<URLRequestJobFactory::ProtocolHandler>> protocol_handlers_; - raw_ptr<ClientSocketFactory> client_socket_factory_ = nullptr; + raw_ptr<ClientSocketFactory> client_socket_factory_raw_ = nullptr; }; } // namespace net diff --git a/chromium/net/url_request/url_request_context_builder_unittest.cc b/chromium/net/url_request/url_request_context_builder_unittest.cc index 4180b9eebce..effeb506bb1 100644 --- a/chromium/net/url_request/url_request_context_builder_unittest.cc +++ b/chromium/net/url_request/url_request_context_builder_unittest.cc @@ -290,7 +290,7 @@ TEST_F(URLRequestContextBuilderTest, BindToNetworkFinalConfiguration) { // The actual network handle doesn't really matter, this test just wants to // check that all the pieces are in place and configured correctly. - constexpr NetworkChangeNotifier::NetworkHandle network = 2; + constexpr handles::NetworkHandle network = 2; auto scoped_mock_network_change_notifier = std::make_unique<test::ScopedMockNetworkChangeNotifier>(); test::MockNetworkChangeNotifier* mock_ncn = @@ -325,6 +325,38 @@ TEST_F(URLRequestContextBuilderTest, BindToNetworkFinalConfiguration) { #endif // BUILDFLAG(IS_ANDROID) } +TEST_F(URLRequestContextBuilderTest, BindToNetworkCustomManagerOptions) { +#if BUILDFLAG(IS_ANDROID) + if (base::android::BuildInfo::GetInstance()->sdk_int() < + base::android::SDK_VERSION_MARSHMALLOW) { + GTEST_SKIP() + << "BindToNetwork is supported starting from Android Marshmallow"; + } + + // The actual network handle doesn't really matter, this test just wants to + // check that all the pieces are in place and configured correctly. + constexpr handles::NetworkHandle network = 2; + auto scoped_mock_network_change_notifier = + std::make_unique<test::ScopedMockNetworkChangeNotifier>(); + test::MockNetworkChangeNotifier* mock_ncn = + scoped_mock_network_change_notifier->mock_network_change_notifier(); + mock_ncn->ForceNetworkHandlesSupported(); + + // Set non-default value for check_ipv6_on_wifi and check that this is what + // HostResolverManager receives. + HostResolver::ManagerOptions options; + options.check_ipv6_on_wifi = !options.check_ipv6_on_wifi; + builder_.BindToNetwork(network, options); + std::unique_ptr<URLRequestContext> context = builder_.Build(); + EXPECT_EQ(context->host_resolver() + ->GetManagerForTesting() + ->check_ipv6_on_wifi_for_testing(), + options.check_ipv6_on_wifi); +#else // !BUILDFLAG(IS_ANDROID) + GTEST_SKIP() << "BindToNetwork is supported only on Android"; +#endif // BUILDFLAG(IS_ANDROID) +} + } // namespace } // namespace net diff --git a/chromium/net/url_request/url_request_context_getter_observer.h b/chromium/net/url_request/url_request_context_getter_observer.h index a59d0e6a34c..1ebbbb31636 100644 --- a/chromium/net/url_request/url_request_context_getter_observer.h +++ b/chromium/net/url_request/url_request_context_getter_observer.h @@ -14,7 +14,7 @@ class URLRequestContextGetter; // URLRequestContextGetter is shutting down. class NET_EXPORT URLRequestContextGetterObserver { public: - URLRequestContextGetterObserver() {} + URLRequestContextGetterObserver() = default; URLRequestContextGetterObserver(const URLRequestContextGetterObserver&) = delete; @@ -28,7 +28,7 @@ class NET_EXPORT URLRequestContextGetterObserver { virtual void OnContextShuttingDown() = 0; protected: - virtual ~URLRequestContextGetterObserver() {} + virtual ~URLRequestContextGetterObserver() = default; }; } // namespace net diff --git a/chromium/net/url_request/url_request_filter.cc b/chromium/net/url_request/url_request_filter.cc index 9a19dde37df..a07bf8301a6 100644 --- a/chromium/net/url_request/url_request_filter.cc +++ b/chromium/net/url_request/url_request_filter.cc @@ -70,10 +70,6 @@ void URLRequestFilter::RemoveHostnameHandler(const std::string& scheme, DCHECK(OnMessageLoopForInterceptorRemoval()); int removed = hostname_interceptor_map_.erase(make_pair(scheme, hostname)); DCHECK(removed); - - // Note that we don't unregister from the URLRequest ProtocolFactory as - // this would leave no protocol factory for the remaining hostname and URL - // handlers. } bool URLRequestFilter::AddUrlInterceptor( @@ -96,9 +92,6 @@ void URLRequestFilter::RemoveUrlHandler(const GURL& url) { DCHECK(OnMessageLoopForInterceptorRemoval()); size_t removed = url_interceptor_map_.erase(url.spec()); DCHECK(removed); - // Note that we don't unregister from the URLRequest ProtocolFactory as - // this would leave no protocol factory for the remaining hostname and URL - // handlers. } void URLRequestFilter::ClearHandlers() { diff --git a/chromium/net/url_request/url_request_filter.h b/chromium/net/url_request/url_request_filter.h index 134f029fc5f..48d7a7e9ad3 100644 --- a/chromium/net/url_request/url_request_filter.h +++ b/chromium/net/url_request/url_request_filter.h @@ -59,8 +59,7 @@ class NET_EXPORT URLRequestFilter : public URLRequestInterceptor { void RemoveUrlHandler(const GURL& url); - // Clear all the existing URL handlers and unregister with the - // ProtocolFactory. Resets the hit count. + // Clear all the existing URL and hostname handlers. Resets the hit count. void ClearHandlers(); // Returns the number of times a handler was used to service a request. diff --git a/chromium/net/url_request/url_request_filter_unittest.cc b/chromium/net/url_request/url_request_filter_unittest.cc index c330f6144a2..0da85940f27 100644 --- a/chromium/net/url_request/url_request_filter_unittest.cc +++ b/chromium/net/url_request/url_request_filter_unittest.cc @@ -37,8 +37,9 @@ class TestURLRequestInterceptor : public URLRequestInterceptor { // URLRequestInterceptor implementation: std::unique_ptr<URLRequestJob> MaybeInterceptRequest( URLRequest* request) const override { - job_ = new URLRequestTestJob(request); - return base::WrapUnique<URLRequestJob>(job_.get()); + auto job = std::make_unique<URLRequestTestJob>(request); + job_ = job.get(); + return job; } // Is |job| the URLRequestJob generated during interception? @@ -67,18 +68,17 @@ TEST(URLRequestFilter, BasicMatching) { // Check AddUrlInterceptor checks for invalid URLs. EXPECT_FALSE(filter->AddUrlInterceptor( - GURL(), - std::unique_ptr<URLRequestInterceptor>(new TestURLRequestInterceptor()))); + GURL(), std::make_unique<TestURLRequestInterceptor>())); // Check URLRequestInterceptor URL matching. filter->ClearHandlers(); - TestURLRequestInterceptor* interceptor = new TestURLRequestInterceptor(); - EXPECT_TRUE(filter->AddUrlInterceptor( - kUrl1, std::unique_ptr<URLRequestInterceptor>(interceptor))); + auto interceptor1 = std::make_unique<TestURLRequestInterceptor>(); + auto* interceptor1_ptr = interceptor1.get(); + EXPECT_TRUE(filter->AddUrlInterceptor(kUrl1, std::move(interceptor1))); { std::unique_ptr<URLRequestJob> found = filter->MaybeInterceptRequest(request1.get()); - EXPECT_TRUE(interceptor->WasLastJobCreated(found.get())); + EXPECT_TRUE(interceptor1_ptr->WasLastJobCreated(found.get())); } EXPECT_EQ(filter->hit_count(), 1); @@ -94,14 +94,14 @@ TEST(URLRequestFilter, BasicMatching) { // Check hostname matching. filter->ClearHandlers(); EXPECT_EQ(0, filter->hit_count()); - interceptor = new TestURLRequestInterceptor(); - filter->AddHostnameInterceptor( - kUrl1.scheme(), kUrl1.host(), - std::unique_ptr<URLRequestInterceptor>(interceptor)); + auto interceptor2 = std::make_unique<TestURLRequestInterceptor>(); + auto* interceptor2_ptr = interceptor2.get(); + filter->AddHostnameInterceptor(kUrl1.scheme(), kUrl1.host(), + std::move(interceptor2)); { std::unique_ptr<URLRequestJob> found = filter->MaybeInterceptRequest(request1.get()); - EXPECT_TRUE(interceptor->WasLastJobCreated(found.get())); + EXPECT_TRUE(interceptor2_ptr->WasLastJobCreated(found.get())); } EXPECT_EQ(1, filter->hit_count()); diff --git a/chromium/net/url_request/url_request_http_job.cc b/chromium/net/url_request/url_request_http_job.cc index 1975492c29a..bd336369896 100644 --- a/chromium/net/url_request/url_request_http_job.cc +++ b/chromium/net/url_request/url_request_http_job.cc @@ -108,18 +108,18 @@ base::Value CookieInclusionStatusNetLogParams( const std::string& cookie_path, const net::CookieInclusionStatus& status, net::NetLogCaptureMode capture_mode) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("operation", operation); - dict.SetStringKey("status", status.GetDebugString()); + base::Value::Dict dict; + dict.Set("operation", operation); + dict.Set("status", status.GetDebugString()); if (net::NetLogCaptureIncludesSensitive(capture_mode)) { if (!cookie_name.empty()) - dict.SetStringKey("name", cookie_name); + dict.Set("name", cookie_name); if (!cookie_domain.empty()) - dict.SetStringKey("domain", cookie_domain); + dict.Set("domain", cookie_domain); if (!cookie_path.empty()) - dict.SetStringKey("path", cookie_path); + dict.Set("path", cookie_path); } - return dict; + return base::Value(std::move(dict)); } // Records details about the most-specific trust anchor in |spki_hashes|, @@ -335,7 +335,11 @@ void URLRequestHttpJob::OnGotFirstPartySetMetadata( cookie_partition_key_ = CookiePartitionKey::FromNetworkIsolationKey( request_->isolation_info().network_isolation_key(), - base::OptionalOrNullptr(first_party_set_metadata_.top_frame_owner())); + base::OptionalOrNullptr( + first_party_set_metadata_.top_frame_entry().has_value() + ? absl::make_optional( + first_party_set_metadata_.top_frame_entry()->primary()) + : absl::nullopt)); AddCookieHeaderAndStart(); } else { StartTransaction(); @@ -451,8 +455,8 @@ void URLRequestHttpJob::DestroyTransaction() { transaction_->GetTotalReceivedBytes(); total_sent_bytes_from_previous_transactions_ += transaction_->GetTotalSentBytes(); - transaction_.reset(); response_info_ = nullptr; + transaction_.reset(); override_response_headers_ = nullptr; receive_headers_end_ = base::TimeTicks(); } @@ -575,50 +579,16 @@ void URLRequestHttpJob::StartTransactionInternal() { } void URLRequestHttpJob::AddExtraHeaders() { - if (!request_info_.extra_headers.HasHeader( - HttpRequestHeaders::kAcceptEncoding)) { - // If a range is specifically requested, set the "Accepted Encoding" header - // to "identity" - if (request_info_.extra_headers.HasHeader(HttpRequestHeaders::kRange)) { - request_info_.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding, - "identity"); - } else { - // Supply Accept-Encoding headers first so that it is more likely that - // they will be in the first transmitted packet. This can sometimes make - // it easier to filter and analyze the streams to assure that a proxy has - // not damaged these headers. Some proxies deliberately corrupt - // Accept-Encoding headers. - std::vector<std::string> advertised_encoding_names; - if (request_->Supports(SourceStream::SourceType::TYPE_GZIP)) { - advertised_encoding_names.push_back("gzip"); - } - if (request_->Supports(SourceStream::SourceType::TYPE_DEFLATE)) { - advertised_encoding_names.push_back("deflate"); - } - // Advertise "br" encoding only if transferred data is opaque to proxy. - if (request()->context()->enable_brotli() && - request_->Supports(SourceStream::SourceType::TYPE_BROTLI)) { - if (request()->url().SchemeIsCryptographic() || - IsLocalhost(request()->url())) { - advertised_encoding_names.push_back("br"); - } - } - if (!advertised_encoding_names.empty()) { - // Tell the server what compression formats are supported. - request_info_.extra_headers.SetHeader( - HttpRequestHeaders::kAcceptEncoding, - base::JoinString(base::make_span(advertised_encoding_names), ", ")); - } - } - } + request_info_.extra_headers.SetAcceptEncodingIfMissing( + request()->url(), request()->accepted_stream_types(), + request()->context()->enable_brotli()); if (http_user_agent_settings_) { // Only add default Accept-Language if the request didn't have it // specified. std::string accept_language = http_user_agent_settings_->GetAcceptLanguage(); - if (base::FeatureList::IsEnabled(features::kAcceptLanguageHeader) && - !accept_language.empty()) { + if (!accept_language.empty()) { request_info_.extra_headers.SetHeaderIfMissing( HttpRequestHeaders::kAcceptLanguage, accept_language); @@ -648,15 +618,11 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() { is_main_frame_navigation, force_ignore_site_for_cookies); bool is_in_nontrivial_first_party_set = - first_party_set_metadata_.frame_owner().has_value(); + first_party_set_metadata_.frame_entry().has_value(); CookieOptions options = CreateCookieOptions( same_site_context, first_party_set_metadata_.context(), request_->isolation_info(), is_in_nontrivial_first_party_set); - UMA_HISTOGRAM_ENUMERATION( - "Cookie.FirstPartySetsContextType.HTTP.Read", - first_party_set_metadata_.first_party_sets_context_type()); - cookie_store->GetCookieListWithOptionsAsync( request_->url(), options, CookiePartitionKeyCollection::FromOptional(cookie_partition_key_.value()), @@ -833,8 +799,7 @@ void URLRequestHttpJob::AnnotateAndMoveUserBlockedCookies( if (request()->network_delegate()) { can_get_cookies = request()->network_delegate()->AnnotateAndMoveUserBlockedCookies( - *request(), maybe_included_cookies, excluded_cookies, - /*allowed_from_caller=*/true); + *request(), maybe_included_cookies, excluded_cookies); } if (!can_get_cookies) { @@ -889,15 +854,11 @@ void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) { force_ignore_site_for_cookies); bool is_in_nontrivial_first_party_set = - first_party_set_metadata_.frame_owner().has_value(); + first_party_set_metadata_.frame_entry().has_value(); CookieOptions options = CreateCookieOptions( same_site_context, first_party_set_metadata_.context(), request_->isolation_info(), is_in_nontrivial_first_party_set); - UMA_HISTOGRAM_ENUMERATION( - "Cookie.FirstPartySetsContextType.HTTP.Write", - first_party_set_metadata_.first_party_sets_context_type()); - // Set all cookies, without waiting for them to be set. Any subsequent // read will see the combined result of all cookie operation. const base::StringPiece name("Set-Cookie"); diff --git a/chromium/net/url_request/url_request_http_job.h b/chromium/net/url_request/url_request_http_job.h index 10516a902b0..9d9e968d01a 100644 --- a/chromium/net/url_request/url_request_http_job.h +++ b/chromium/net/url_request/url_request_http_job.h @@ -232,7 +232,6 @@ class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob { RequestPriority priority_ = DEFAULT_PRIORITY; HttpRequestInfo request_info_; - raw_ptr<const HttpResponseInfo> response_info_ = nullptr; // Used for any logic, e.g. DNS-based scheme upgrade, that needs to synthesize // response info to override the real response info. Transaction should be @@ -248,6 +247,12 @@ class NET_EXPORT_PRIVATE URLRequestHttpJob : public URLRequestJob { std::unique_ptr<HttpTransaction> transaction_; + // This needs to be declared after `transaction_` and + // `override_response_info_` because `response_info_` holds a pointer that's + // itself owned by one of those, so `response_info_` needs to be destroyed + // first. + raw_ptr<const HttpResponseInfo> response_info_ = nullptr; + // This is used to supervise traffic and enforce exponential // back-off. May be NULL. scoped_refptr<URLRequestThrottlerEntryInterface> throttling_entry_; diff --git a/chromium/net/url_request/url_request_http_job_unittest.cc b/chromium/net/url_request/url_request_http_job_unittest.cc index 6cfcbd5fa44..22f7ad48487 100644 --- a/chromium/net/url_request/url_request_http_job_unittest.cc +++ b/chromium/net/url_request/url_request_http_job_unittest.cc @@ -260,7 +260,7 @@ TEST_F(URLRequestHttpJobWithProxyTest, TestSuccessfulWithOneProxy) { ProxyUriToProxyServer("http://origin.net:80", ProxyServer::SCHEME_HTTP); std::unique_ptr<ProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( ProxyServerToPacResultElement(proxy_server), TRAFFIC_ANNOTATION_FOR_TESTS); @@ -302,7 +302,7 @@ TEST_F(URLRequestHttpJobWithProxyTest, // Connection to |proxy_server| would fail. Request should be fetched over // DIRECT. std::unique_ptr<ProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( ProxyServerToPacResultElement(proxy_server) + "; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); @@ -1843,21 +1843,24 @@ TEST_P(PartitionedCookiesURLRequestHttpJobTest, SetPartitionedCookie) { /*first_party_sets_enabled=*/false)); auto context = context_builder->Build(); - TestDelegate delegate; - std::unique_ptr<URLRequest> req(context->CreateRequest( - https_test.GetURL("/set-cookie?__Host-foo=bar;SameSite=None;Secure;Path=/" - ";Partitioned;"), - DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); - const url::Origin kTopFrameOrigin = url::Origin::Create(GURL("https://www.toplevelsite.com")); const IsolationInfo kTestIsolationInfo = IsolationInfo::CreateForInternalRequest(kTopFrameOrigin); - req->set_isolation_info(kTestIsolationInfo); - req->Start(); - ASSERT_TRUE(req->is_pending()); - delegate.RunUntilComplete(); + { + TestDelegate delegate; + std::unique_ptr<URLRequest> req(context->CreateRequest( + https_test.GetURL( + "/set-cookie?__Host-foo=bar;SameSite=None;Secure;Path=/" + ";Partitioned;"), + DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); + + req->set_isolation_info(kTestIsolationInfo); + req->Start(); + ASSERT_TRUE(req->is_pending()); + delegate.RunUntilComplete(); + } { // Test request from the same top-level site. TestDelegate delegate; @@ -1917,31 +1920,34 @@ TEST_P(PartitionedCookiesURLRequestHttpJobTest, const IsolationInfo kNonMemberIsolationInfo = IsolationInfo::CreateForInternalRequest(kNonMemberOrigin); - base::flat_map<SchemefulSite, std::set<SchemefulSite>> first_party_sets; - first_party_sets.insert(std::make_pair( - kOwnerSite, std::set<SchemefulSite>({kOwnerSite, kMemberSite}))); - auto context_builder = CreateTestURLRequestContextBuilder(); auto cookie_monster = std::make_unique<CookieMonster>( /*store=*/nullptr, /*net_log=*/nullptr, /*first_party_sets_enabled=*/false); auto cookie_access_delegate = std::make_unique<TestCookieAccessDelegate>(); - cookie_access_delegate->SetFirstPartySets(first_party_sets); + cookie_access_delegate->SetFirstPartySets({ + {kOwnerSite, net::FirstPartySetEntry(kOwnerSite, net::SiteType::kPrimary, + absl::nullopt)}, + {kMemberSite, + net::FirstPartySetEntry(kOwnerSite, net::SiteType::kAssociated, 0)}, + }); cookie_monster->SetCookieAccessDelegate(std::move(cookie_access_delegate)); context_builder->SetCookieStore(std::move(cookie_monster)); auto context = context_builder->Build(); - TestDelegate delegate; - std::unique_ptr<URLRequest> req(context->CreateRequest( - https_test.GetURL("/set-cookie?__Host-foo=0;SameSite=None;Secure;Path=/" - ";Partitioned;"), - DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); + { + TestDelegate delegate; + std::unique_ptr<URLRequest> req(context->CreateRequest( + https_test.GetURL("/set-cookie?__Host-foo=0;SameSite=None;Secure;Path=/" + ";Partitioned;"), + DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); - // Start with the set's owner as the top-level site. - req->set_isolation_info(kOwnerIsolationInfo); - req->Start(); - ASSERT_TRUE(req->is_pending()); - delegate.RunUntilComplete(); + // Start with the set's owner as the top-level site. + req->set_isolation_info(kOwnerIsolationInfo); + req->Start(); + ASSERT_TRUE(req->is_pending()); + delegate.RunUntilComplete(); + } { // Test the cookie is present in a request with the same top-frame site as @@ -1969,15 +1975,18 @@ TEST_P(PartitionedCookiesURLRequestHttpJobTest, EXPECT_EQ("__Host-foo=0", delegate.data_received()); } - // Set a cookie from the member site. - req = context->CreateRequest( - https_test.GetURL("/set-cookie?__Host-bar=1;SameSite=None;Secure;Path=/" - ";Partitioned;"), - DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); - req->set_isolation_info(kMemberIsolationInfo); - req->Start(); - ASSERT_TRUE(req->is_pending()); - delegate.RunUntilComplete(); + { + // Set a cookie from the member site. + TestDelegate delegate; + std::unique_ptr<URLRequest> req(context->CreateRequest( + https_test.GetURL("/set-cookie?__Host-bar=1;SameSite=None;Secure;Path=/" + ";Partitioned;"), + DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); + req->set_isolation_info(kMemberIsolationInfo); + req->Start(); + ASSERT_TRUE(req->is_pending()); + delegate.RunUntilComplete(); + } { // Check request whose top-frame site is the owner site has the cookie set @@ -2029,17 +2038,19 @@ TEST_P(PartitionedCookiesURLRequestHttpJobTest, PrivacyMode) { const IsolationInfo kTestIsolationInfo = IsolationInfo::CreateForInternalRequest(kTopFrameOrigin); - // Set an unpartitioned and partitioned cookie. - TestDelegate delegate; - std::unique_ptr<URLRequest> req(context->CreateRequest( - https_test.GetURL( - "/set-cookie?__Host-partitioned=0;SameSite=None;Secure;Path=/" - ";Partitioned;&__Host-unpartitioned=1;SameSite=None;Secure;Path=/"), - DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); - req->set_isolation_info(kTestIsolationInfo); - req->Start(); - ASSERT_TRUE(req->is_pending()); - delegate.RunUntilComplete(); + { + // Set an unpartitioned and partitioned cookie. + TestDelegate delegate; + std::unique_ptr<URLRequest> req(context->CreateRequest( + https_test.GetURL( + "/set-cookie?__Host-partitioned=0;SameSite=None;Secure;Path=/" + ";Partitioned;&__Host-unpartitioned=1;SameSite=None;Secure;Path=/"), + DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); + req->set_isolation_info(kTestIsolationInfo); + req->Start(); + ASSERT_TRUE(req->is_pending()); + delegate.RunUntilComplete(); + } { // Get both cookies when privacy mode is disabled. TestDelegate delegate; @@ -2133,23 +2144,26 @@ TEST_P(PartitionedCookiesURLRequestHttpJobTest, /*first_party_sets_enabled=*/false)); auto context = context_builder->Build(); - TestDelegate delegate; - std::unique_ptr<URLRequest> req(context->CreateRequest( - https_test.GetURL("/set-cookie?__Host-foo=bar;SameSite=None;Secure;Path=/" - ";Partitioned;"), - DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); - const url::Origin kTopFrameOrigin = url::Origin::Create(GURL("https://www.toplevelsite.com")); const IsolationInfo kTestIsolationInfo = IsolationInfo::CreateForInternalRequest(kTopFrameOrigin); - req->set_isolation_info(kTestIsolationInfo); - req->Start(); - ASSERT_TRUE(req->is_pending()); - delegate.RunUntilComplete(); + { + TestDelegate delegate; + std::unique_ptr<URLRequest> req(context->CreateRequest( + https_test.GetURL( + "/set-cookie?__Host-foo=bar;SameSite=None;Secure;Path=/" + ";Partitioned;"), + DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS)); - ASSERT_TRUE(req->HasPartitionedCookie()); + req->set_isolation_info(kTestIsolationInfo); + req->Start(); + ASSERT_TRUE(req->is_pending()); + delegate.RunUntilComplete(); + + ASSERT_TRUE(req->HasPartitionedCookie()); + } { // Test request from the same top-level site. TestDelegate delegate; diff --git a/chromium/net/url_request/url_request_job.cc b/chromium/net/url_request/url_request_job.cc index 9262d5b3aa6..b788b8a3c89 100644 --- a/chromium/net/url_request/url_request_job.cc +++ b/chromium/net/url_request/url_request_job.cc @@ -40,9 +40,9 @@ namespace { // Callback for TYPE_URL_REQUEST_FILTERS_SET net-internals event. base::Value SourceStreamSetParams(SourceStream* source_stream) { - base::Value event_params(base::Value::Type::DICTIONARY); - event_params.SetStringKey("filters", source_stream->Description()); - return event_params; + base::Value::Dict event_params; + event_params.Set("filters", source_stream->Description()); + return base::Value(std::move(event_params)); } } // namespace @@ -86,8 +86,7 @@ class URLRequestJob::URLRequestJobSourceStream : public SourceStream { URLRequestJob::URLRequestJob(URLRequest* request) : request_(request) {} -URLRequestJob::~URLRequestJob() { -} +URLRequestJob::~URLRequestJob() = default; void URLRequestJob::SetUpload(UploadDataStream* upload) { } @@ -408,11 +407,6 @@ void URLRequestJob::NotifyHeadersComplete() { if (has_handled_response_) return; - // The URLRequest status should still be IO_PENDING, which it was set to - // before the URLRequestJob was started. On error or cancellation, this - // method should not be called. - DCHECK_EQ(ERR_IO_PENDING, request_->status()); - // Initialize to the current time, and let the subclass optionally override // the time stamps if it has that information. The default request_time is // set by URLRequest before it calls our Start method. diff --git a/chromium/net/url_request/url_request_netlog_params.cc b/chromium/net/url_request/url_request_netlog_params.cc index 178663fb822..cec31242801 100644 --- a/chromium/net/url_request/url_request_netlog_params.cc +++ b/chromium/net/url_request/url_request_netlog_params.cc @@ -20,11 +20,11 @@ base::Value NetLogURLRequestConstructorParams( const GURL& url, RequestPriority priority, NetworkTrafficAnnotationTag traffic_annotation) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("url", url.possibly_invalid_spec()); - dict.SetStringKey("priority", RequestPriorityToString(priority)); - dict.SetIntKey("traffic_annotation", traffic_annotation.unique_id_hash_code); - return dict; + base::Value::Dict dict; + dict.Set("url", url.possibly_invalid_spec()); + dict.Set("priority", RequestPriorityToString(priority)); + dict.Set("traffic_annotation", traffic_annotation.unique_id_hash_code); + return base::Value(std::move(dict)); } base::Value NetLogURLRequestStartParams( @@ -35,12 +35,12 @@ base::Value NetLogURLRequestStartParams( const SiteForCookies& site_for_cookies, const absl::optional<url::Origin>& initiator, int64_t upload_id) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("url", url.possibly_invalid_spec()); - dict.SetStringKey("method", method); - dict.SetIntKey("load_flags", load_flags); - dict.SetStringKey("network_isolation_key", - isolation_info.network_isolation_key().ToDebugString()); + base::Value::Dict dict; + dict.Set("url", url.possibly_invalid_spec()); + dict.Set("method", method); + dict.Set("load_flags", load_flags); + dict.Set("network_isolation_key", + isolation_info.network_isolation_key().ToDebugString()); std::string request_type; switch (isolation_info.request_type()) { case IsolationInfo::RequestType::kMainFrame: @@ -53,13 +53,13 @@ base::Value NetLogURLRequestStartParams( request_type = "other"; break; } - dict.SetStringKey("request_type", request_type); - dict.SetStringKey("site_for_cookies", site_for_cookies.ToDebugString()); - dict.SetStringKey("initiator", initiator.has_value() ? initiator->Serialize() - : "not an origin"); + dict.Set("request_type", request_type); + dict.Set("site_for_cookies", site_for_cookies.ToDebugString()); + dict.Set("initiator", + initiator.has_value() ? initiator->Serialize() : "not an origin"); if (upload_id > -1) - dict.SetStringKey("upload_id", base::NumberToString(upload_id)); - return dict; + dict.Set("upload_id", base::NumberToString(upload_id)); + return base::Value(std::move(dict)); } } // namespace net diff --git a/chromium/net/url_request/url_request_quic_perftest.cc b/chromium/net/url_request/url_request_quic_perftest.cc index 0ac808142c2..56f9a4c29b5 100644 --- a/chromium/net/url_request/url_request_quic_perftest.cc +++ b/chromium/net/url_request/url_request_quic_perftest.cc @@ -83,8 +83,7 @@ perf_test::PerfResultReporter SetUpURLRequestQuicReporter( std::unique_ptr<test_server::HttpResponse> HandleRequest( const test_server::HttpRequest& request) { - std::unique_ptr<test_server::BasicHttpResponse> http_response( - new test_server::BasicHttpResponse()); + auto http_response = std::make_unique<test_server::BasicHttpResponse>(); std::string alpn = quic::AlpnForVersion(DefaultSupportedQuicVersions().front()); http_response->AddCustomHeader( @@ -105,14 +104,14 @@ class URLRequestQuicPerfTest : public ::testing::Test { memory_dump_manager_ = base::trace_event::MemoryDumpManager::CreateInstanceForTesting(); base::trace_event::InitializeMemoryDumpManagerForInProcessTesting( - /*is_coordinator_process=*/false); + /*is_coordinator=*/false); memory_dump_manager_->set_dumper_registrations_ignored_for_testing(false); memory_dump_manager_->set_dumper_registrations_ignored_for_testing(true); StartTcpServer(); StartQuicServer(); // Host mapping. - std::unique_ptr<MockHostResolver> resolver(new MockHostResolver()); + auto resolver = std::make_unique<MockHostResolver>(); resolver->rules()->AddRule(kAltSvcHost, "127.0.0.1"); auto host_resolver = std::make_unique<MappedHostResolver>(std::move(resolver)); diff --git a/chromium/net/url_request/url_request_quic_unittest.cc b/chromium/net/url_request/url_request_quic_unittest.cc index 8e792a7719b..b6736ea9a6b 100644 --- a/chromium/net/url_request/url_request_quic_unittest.cc +++ b/chromium/net/url_request/url_request_quic_unittest.cc @@ -12,6 +12,7 @@ #include "base/strings/string_number_conversions.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" +#include "base/time/time.h" #include "build/build_config.h" #include "net/base/features.h" #include "net/base/isolation_info.h" @@ -23,6 +24,7 @@ #include "net/cert/mock_cert_verifier.h" #include "net/dns/mapped_host_resolver.h" #include "net/dns/mock_host_resolver.h" +#include "net/http/http_response_headers.h" #include "net/http/transport_security_state.h" #include "net/log/net_log_event_type.h" #include "net/log/test_net_log_util.h" @@ -33,6 +35,7 @@ #include "net/test/test_data_directory.h" #include "net/test/test_with_task_environment.h" #include "net/third_party/quiche/src/quiche/quic/core/quic_dispatcher.h" +#include "net/third_party/quiche/src/quiche/quic/core/quic_time.h" #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend.h" #include "net/third_party/quiche/src/quiche/quic/tools/quic_simple_dispatcher.h" @@ -219,6 +222,14 @@ class URLRequestQuicTest std::string(path); } + void SetDelay(absl::string_view host, + absl::string_view path, + base::TimeDelta delay) { + memory_cache_backend_.SetResponseDelay( + host, path, + quic::QuicTime::Delta::FromMilliseconds(delay.InMilliseconds())); + } + private: void StartQuicServer(quic::ParsedQuicVersion version) { // Set up in-memory cache. @@ -247,7 +258,7 @@ class URLRequestQuicTest server_->Listen(net::IPEndPoint(net::IPAddress::IPv4AllZeros(), 0)); EXPECT_GE(rv, 0) << "Quic server fails to start"; - std::unique_ptr<MockHostResolver> resolver(new MockHostResolver()); + auto resolver = std::make_unique<MockHostResolver>(); resolver->rules()->AddRule("test.example.com", "127.0.0.1"); host_resolver_ = std::make_unique<MappedHostResolver>(std::move(resolver)); // Use a mapped host resolver so that request for test.example.com @@ -280,7 +291,7 @@ class URLRequestQuicTest // received. class CheckLoadTimingDelegate : public TestDelegate { public: - CheckLoadTimingDelegate(bool session_reused) + explicit CheckLoadTimingDelegate(bool session_reused) : session_reused_(session_reused) {} CheckLoadTimingDelegate(const CheckLoadTimingDelegate&) = delete; @@ -449,6 +460,25 @@ TEST_P(URLRequestQuicTest, RequestHeadersCallback) { EXPECT_EQ(OK, delegate.request_status()); } +TEST_P(URLRequestQuicTest, DelayedResponseStart) { + auto context = BuildContext(); + TestDelegate delegate; + std::unique_ptr<URLRequest> request = + CreateRequest(context.get(), GURL(UrlFromPath(kHelloPath)), &delegate); + + constexpr auto delay = base::Milliseconds(300); + + this->SetDelay(kTestServerHost, kHelloPath, delay); + request->Start(); + ASSERT_TRUE(request->is_pending()); + delegate.RunUntilComplete(); + LoadTimingInfo timing_info; + request->GetLoadTimingInfo(&timing_info); + EXPECT_EQ(OK, delegate.request_status()); + EXPECT_GE((timing_info.receive_headers_start - timing_info.request_start), + delay); +} + // Tests that if there's an Expect-CT failure at the QUIC layer, a report is // generated. TEST_P(URLRequestQuicTest, ExpectCT) { diff --git a/chromium/net/url_request/url_request_test_util.cc b/chromium/net/url_request/url_request_test_util.cc index e186610df1e..2c0b36aab42 100644 --- a/chromium/net/url_request/url_request_test_util.cc +++ b/chromium/net/url_request/url_request_test_util.cc @@ -58,7 +58,7 @@ const char kTestNetworkDelegateRequestIdKey[] = class TestRequestId : public base::SupportsUserData::Data { public: - TestRequestId(int id) : id_(id) {} + explicit TestRequestId(int id) : id_(id) {} ~TestRequestId() override = default; int id() const { return id_; } @@ -390,8 +390,8 @@ int TestNetworkDelegate::OnHeadersReceived( next_states_[req_id] |= kStageBeforeStartTransaction; if (!redirect_on_headers_received_url_.is_empty()) { - *override_response_headers = - new HttpResponseHeaders(original_response_headers->raw_headers()); + *override_response_headers = base::MakeRefCounted<HttpResponseHeaders>( + original_response_headers->raw_headers()); (*override_response_headers)->ReplaceStatusLine("HTTP/1.1 302 Found"); (*override_response_headers)->RemoveHeader("Location"); (*override_response_headers) @@ -402,8 +402,8 @@ int TestNetworkDelegate::OnHeadersReceived( // Since both values are absl::optionals, can just copy this over. *preserve_fragment_on_redirect_url = preserve_fragment_on_redirect_url_; } else if (add_header_to_first_response_ && is_first_response) { - *override_response_headers = - new HttpResponseHeaders(original_response_headers->raw_headers()); + *override_response_headers = base::MakeRefCounted<HttpResponseHeaders>( + original_response_headers->raw_headers()); (*override_response_headers) ->AddHeader("X-Network-Delegate", "Greetings, planet"); } @@ -502,9 +502,8 @@ void TestNetworkDelegate::OnURLRequestDestroyed(URLRequest* request) { bool TestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, net::CookieAccessResultList& maybe_included_cookies, - net::CookieAccessResultList& excluded_cookies, - bool allowed_from_caller) { - bool allow = allowed_from_caller; + net::CookieAccessResultList& excluded_cookies) { + bool allow = true; if (cookie_options_bit_mask_ & NO_GET_COOKIES) allow = false; @@ -527,9 +526,8 @@ NetworkDelegate::PrivacySetting TestNetworkDelegate::OnForcePrivacyMode( bool TestNetworkDelegate::OnCanSetCookie(const URLRequest& request, const net::CanonicalCookie& cookie, - CookieOptions* options, - bool allowed_from_caller) { - bool allow = allowed_from_caller; + CookieOptions* options) { + bool allow = true; if (cookie_options_bit_mask_ & NO_SET_COOKIE) allow = false; @@ -566,18 +564,19 @@ FilteringTestNetworkDelegate::~FilteringTestNetworkDelegate() = default; bool FilteringTestNetworkDelegate::OnCanSetCookie( const URLRequest& request, const net::CanonicalCookie& cookie, - CookieOptions* options, - bool allowed_from_caller) { + CookieOptions* options) { // Filter out cookies with the same name as |cookie_name_filter_| and // combine with |allowed_from_caller|. - bool allowed = allowed_from_caller && !(cookie.Name() == cookie_name_filter_); + bool allowed = cookie.Name() != cookie_name_filter_; ++set_cookie_called_count_; if (!allowed) ++blocked_set_cookie_count_; - return TestNetworkDelegate::OnCanSetCookie(request, cookie, options, allowed); + // Call the nested delegate's method first to avoid a short circuit. + return TestNetworkDelegate::OnCanSetCookie(request, cookie, options) && + allowed; } NetworkDelegate::PrivacySetting @@ -599,11 +598,10 @@ FilteringTestNetworkDelegate::OnForcePrivacyMode( bool FilteringTestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, net::CookieAccessResultList& maybe_included_cookies, - net::CookieAccessResultList& excluded_cookies, - bool allowed_from_caller) { + net::CookieAccessResultList& excluded_cookies) { // Filter out cookies if |block_annotate_cookies_| is set and // combine with |allowed_from_caller|. - bool allowed = allowed_from_caller && !block_annotate_cookies_; + bool allowed = !block_annotate_cookies_; ++annotate_cookies_called_count_; @@ -630,8 +628,10 @@ bool FilteringTestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( MoveExcludedCookies(maybe_included_cookies, excluded_cookies); } + // Call the nested delegate's method first to avoid a short circuit. return TestNetworkDelegate::OnAnnotateAndMoveUserBlockedCookies( - request, maybe_included_cookies, excluded_cookies, allowed); + request, maybe_included_cookies, excluded_cookies) && + allowed; } // URLRequestInterceptor that intercepts only the first request it sees, diff --git a/chromium/net/url_request/url_request_test_util.h b/chromium/net/url_request/url_request_test_util.h index 05e5399fb81..e8fa60fb4c2 100644 --- a/chromium/net/url_request/url_request_test_util.h +++ b/chromium/net/url_request/url_request_test_util.h @@ -311,8 +311,7 @@ class TestNetworkDelegate : public NetworkDelegateImpl { bool OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, net::CookieAccessResultList& maybe_included_cookies, - net::CookieAccessResultList& excluded_cookies, - bool allowed_from_caller) override; + net::CookieAccessResultList& excluded_cookies) override; NetworkDelegate::PrivacySetting OnForcePrivacyMode( const GURL& url, const SiteForCookies& site_for_cookies, @@ -320,8 +319,7 @@ class TestNetworkDelegate : public NetworkDelegateImpl { SamePartyContext::Type same_party_context_type) const override; bool OnCanSetCookie(const URLRequest& request, const net::CanonicalCookie& cookie, - CookieOptions* options, - bool allowed_from_caller) override; + CookieOptions* options) override; bool OnCancelURLRequestWithPolicyViolatingReferrerHeader( const URLRequest& request, const GURL& target_url, @@ -380,8 +378,7 @@ class FilteringTestNetworkDelegate : public TestNetworkDelegate { bool OnCanSetCookie(const URLRequest& request, const net::CanonicalCookie& cookie, - CookieOptions* options, - bool allowed_from_caller) override; + CookieOptions* options) override; void SetCookieFilter(std::string filter) { cookie_name_filter_ = std::move(filter); @@ -398,8 +395,7 @@ class FilteringTestNetworkDelegate : public TestNetworkDelegate { bool OnAnnotateAndMoveUserBlockedCookies( const URLRequest& request, net::CookieAccessResultList& maybe_included_cookies, - net::CookieAccessResultList& excluded_cookies, - bool allowed_from_caller) override; + net::CookieAccessResultList& excluded_cookies) override; NetworkDelegate::PrivacySetting OnForcePrivacyMode( const GURL& url, diff --git a/chromium/net/url_request/url_request_throttler_entry.cc b/chromium/net/url_request/url_request_throttler_entry.cc index c7f44694b45..ddfbf2f4387 100644 --- a/chromium/net/url_request/url_request_throttler_entry.cc +++ b/chromium/net/url_request/url_request_throttler_entry.cc @@ -54,12 +54,12 @@ const int URLRequestThrottlerEntry::kDefaultEntryLifetimeMs = 2 * 60 * 1000; base::Value NetLogRejectedRequestParams(const std::string* url_id, int num_failures, const base::TimeDelta& release_after) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("url", *url_id); - dict.SetIntKey("num_failures", num_failures); - dict.SetIntKey("release_after_ms", - static_cast<int>(release_after.InMilliseconds())); - return dict; + base::Value::Dict dict; + dict.Set("url", *url_id); + dict.Set("num_failures", num_failures); + dict.Set("release_after_ms", + static_cast<int>(release_after.InMilliseconds())); + return base::Value(std::move(dict)); } URLRequestThrottlerEntry::URLRequestThrottlerEntry( diff --git a/chromium/net/url_request/url_request_throttler_entry_interface.h b/chromium/net/url_request/url_request_throttler_entry_interface.h index e7c5a1ab039..0e15419ba54 100644 --- a/chromium/net/url_request/url_request_throttler_entry_interface.h +++ b/chromium/net/url_request/url_request_throttler_entry_interface.h @@ -19,7 +19,7 @@ class URLRequest; class NET_EXPORT URLRequestThrottlerEntryInterface : public base::RefCountedThreadSafe<URLRequestThrottlerEntryInterface> { public: - URLRequestThrottlerEntryInterface() {} + URLRequestThrottlerEntryInterface() = default; URLRequestThrottlerEntryInterface(const URLRequestThrottlerEntryInterface&) = delete; @@ -61,7 +61,7 @@ class NET_EXPORT URLRequestThrottlerEntryInterface protected: friend class base::RefCountedThreadSafe<URLRequestThrottlerEntryInterface>; - virtual ~URLRequestThrottlerEntryInterface() {} + virtual ~URLRequestThrottlerEntryInterface() = default; private: friend class base::RefCounted<URLRequestThrottlerEntryInterface>; diff --git a/chromium/net/url_request/url_request_throttler_manager.cc b/chromium/net/url_request/url_request_throttler_manager.cc index 5927ee91e3e..fc91eceff29 100644 --- a/chromium/net/url_request/url_request_throttler_manager.cc +++ b/chromium/net/url_request/url_request_throttler_manager.cc @@ -68,7 +68,7 @@ scoped_refptr<URLRequestThrottlerEntryInterface> // Create the entry if needed. if (entry.get() == nullptr) { - entry = new URLRequestThrottlerEntry(this, url_id); + entry = base::MakeRefCounted<URLRequestThrottlerEntry>(this, url_id); // We only disable back-off throttling on an entry that we have // just constructed. This is to allow unit tests to explicitly override @@ -92,14 +92,14 @@ scoped_refptr<URLRequestThrottlerEntryInterface> void URLRequestThrottlerManager::OverrideEntryForTests( const GURL& url, - URLRequestThrottlerEntry* entry) { + scoped_refptr<URLRequestThrottlerEntry> entry) { // Normalize the url. std::string url_id = GetIdFromUrl(url); // Periodically garbage collect old entries. GarbageCollectEntriesIfNecessary(); - url_entries_[url_id] = entry; + url_entries_[url_id] = std::move(entry); } void URLRequestThrottlerManager::EraseEntryForTests(const GURL& url) { diff --git a/chromium/net/url_request/url_request_throttler_manager.h b/chromium/net/url_request/url_request_throttler_manager.h index 8bc39d19942..e32ecbdca92 100644 --- a/chromium/net/url_request/url_request_throttler_manager.h +++ b/chromium/net/url_request/url_request_throttler_manager.h @@ -53,7 +53,8 @@ class NET_EXPORT_PRIVATE URLRequestThrottlerManager // Registers a new entry in this service and overrides the existing entry (if // any) for the URL. The service will hold a reference to the entry. // It is only used by unit tests. - void OverrideEntryForTests(const GURL& url, URLRequestThrottlerEntry* entry); + void OverrideEntryForTests(const GURL& url, + scoped_refptr<URLRequestThrottlerEntry> entry); // Explicitly erases an entry. // This is useful to remove those entries which have got infinite lifetime and diff --git a/chromium/net/url_request/url_request_throttler_simulation_unittest.cc b/chromium/net/url_request/url_request_throttler_simulation_unittest.cc index f7c2bac1243..9d79f695a3b 100644 --- a/chromium/net/url_request/url_request_throttler_simulation_unittest.cc +++ b/chromium/net/url_request/url_request_throttler_simulation_unittest.cc @@ -98,12 +98,12 @@ class DiscreteTimeSimulation { TimeTicks start_time = TimeTicks(); TimeTicks now = start_time; while ((now - start_time) <= maximum_simulated_duration) { - for (auto it = actors_.begin(); it != actors_.end(); ++it) { - (*it)->AdvanceTime(now); + for (auto* actor : actors_) { + actor->AdvanceTime(now); } - for (auto it = actors_.begin(); it != actors_.end(); ++it) { - (*it)->PerformAction(); + for (auto* actor : actors_) { + actor->PerformAction(); } now += time_between_ticks; @@ -225,7 +225,7 @@ class Server : public DiscreteTimeSimulation::Actor { if (num_ticks % ticks_per_column) ++num_columns; DCHECK_LE(num_columns, terminal_width); - std::unique_ptr<int[]> columns(new int[num_columns]); + auto columns = std::make_unique<int[]>(num_columns); for (int tx = 0; tx < num_ticks; ++tx) { int cx = tx / ticks_per_column; if (tx % ticks_per_column == 0) @@ -488,27 +488,26 @@ void SimulateAttack(Server* server, for (size_t i = 0; i < kNumAttackers; ++i) { // Use a tiny time_between_requests so the attackers will ping the // server at every tick of the simulation. - scoped_refptr<MockURLRequestThrottlerEntry> throttler_entry( - new MockURLRequestThrottlerEntry(&manager)); + auto throttler_entry = + base::MakeRefCounted<MockURLRequestThrottlerEntry>(&manager); if (!enable_throttling) throttler_entry->DisableBackoffThrottling(); - std::unique_ptr<Requester> attacker( - new Requester(throttler_entry.get(), base::Milliseconds(1), server, - attacker_results)); + auto attacker = std::make_unique<Requester>( + throttler_entry.get(), base::Milliseconds(1), server, attacker_results); attacker->SetStartupJitter(base::Seconds(120)); simulation.AddActor(attacker.get()); requesters.push_back(std::move(attacker)); } for (size_t i = 0; i < kNumClients; ++i) { // Normal clients only make requests every 2 minutes, plus/minus 1 minute. - scoped_refptr<MockURLRequestThrottlerEntry> throttler_entry( - new MockURLRequestThrottlerEntry(&manager)); + auto throttler_entry = + base::MakeRefCounted<MockURLRequestThrottlerEntry>(&manager); if (!enable_throttling) throttler_entry->DisableBackoffThrottling(); - std::unique_ptr<Requester> client(new Requester( - throttler_entry.get(), base::Minutes(2), server, client_results)); + auto client = std::make_unique<Requester>( + throttler_entry.get(), base::Minutes(2), server, client_results); client->SetStartupJitter(base::Seconds(120)); client->SetRequestJitter(base::Minutes(1)); simulation.AddActor(client.get()); @@ -585,8 +584,8 @@ double SimulateDowntime(const base::TimeDelta& duration, server.SetDowntime(start_downtime, duration); URLRequestThrottlerManager manager; - scoped_refptr<MockURLRequestThrottlerEntry> throttler_entry( - new MockURLRequestThrottlerEntry(&manager)); + auto throttler_entry = + base::MakeRefCounted<MockURLRequestThrottlerEntry>(&manager); if (!enable_throttling) throttler_entry->DisableBackoffThrottling(); @@ -699,17 +698,17 @@ TEST(URLRequestThrottlerSimulation, PerceivedDowntimeRatio) { // If things don't converge by the time we've done 100K trials, then // clearly one or more of the expected intervals are wrong. while (global_stats.num_runs < 100000) { - for (size_t i = 0; i < std::size(trials); ++i) { + for (auto& trial : trials) { ++global_stats.num_runs; - ++trials[i].stats.num_runs; + ++trial.stats.num_runs; double ratio_unprotected = SimulateDowntime( - trials[i].duration, trials[i].average_client_interval, false); - double ratio_protected = SimulateDowntime( - trials[i].duration, trials[i].average_client_interval, true); + trial.duration, trial.average_client_interval, false); + double ratio_protected = + SimulateDowntime(trial.duration, trial.average_client_interval, true); global_stats.total_ratio_unprotected += ratio_unprotected; global_stats.total_ratio_protected += ratio_protected; - trials[i].stats.total_ratio_unprotected += ratio_unprotected; - trials[i].stats.total_ratio_protected += ratio_protected; + trial.stats.total_ratio_unprotected += ratio_unprotected; + trial.stats.total_ratio_protected += ratio_protected; } double increase_ratio; @@ -727,12 +726,12 @@ TEST(URLRequestThrottlerSimulation, PerceivedDowntimeRatio) { // Print individual trial results for optional manual evaluation. double max_increase_ratio = 0.0; - for (size_t i = 0; i < std::size(trials); ++i) { + for (auto& trial : trials) { double increase_ratio; - trials[i].stats.DidConverge(&increase_ratio); + trial.stats.DidConverge(&increase_ratio); max_increase_ratio = std::max(max_increase_ratio, increase_ratio); - trials[i].PrintTrialDescription(); - trials[i].stats.ReportTrialResult(increase_ratio); + trial.PrintTrialDescription(); + trial.stats.ReportTrialResult(increase_ratio); } VerboseOut("Average increase ratio was %.4f\n", average_increase_ratio); diff --git a/chromium/net/url_request/url_request_throttler_unittest.cc b/chromium/net/url_request/url_request_throttler_unittest.cc index 98c2aeac76f..0297899726f 100644 --- a/chromium/net/url_request/url_request_throttler_unittest.cc +++ b/chromium/net/url_request/url_request_throttler_unittest.cc @@ -122,10 +122,9 @@ class MockURLRequestThrottlerManager : public URLRequestThrottlerManager { std::string fake_url_string("http://www.fakeurl.com/"); fake_url_string.append(base::NumberToString(create_entry_index_++)); GURL fake_url(fake_url_string); - OverrideEntryForTests( - fake_url, - new MockURLRequestThrottlerEntry(this, time, TimeTicks::Now(), - TimeTicks::Now())); + OverrideEntryForTests(fake_url, + base::MakeRefCounted<MockURLRequestThrottlerEntry>( + this, time, TimeTicks::Now(), TimeTicks::Now())); } private: @@ -181,7 +180,7 @@ void URLRequestThrottlerEntryTest::SetUp() { request_->SetLoadFlags(0); now_ = TimeTicks::Now(); - entry_ = new MockURLRequestThrottlerEntry(&manager_); + entry_ = base::MakeRefCounted<MockURLRequestThrottlerEntry>(&manager_); entry_->ResetToBlank(now_); } diff --git a/chromium/net/url_request/url_request_unittest.cc b/chromium/net/url_request/url_request_unittest.cc index 66b18c53108..9c45ace4a25 100644 --- a/chromium/net/url_request/url_request_unittest.cc +++ b/chromium/net/url_request/url_request_unittest.cc @@ -335,8 +335,7 @@ bool ContainsString(const std::string& haystack, const char* needle) { } std::unique_ptr<UploadDataStream> CreateSimpleUploadData(const char* data) { - std::unique_ptr<UploadElementReader> reader( - new UploadBytesElementReader(data, strlen(data))); + auto reader = std::make_unique<UploadBytesElementReader>(data, strlen(data)); return ElementsUploadDataStream::CreateWithReader(std::move(reader), 0); } @@ -727,7 +726,7 @@ class URLRequestTest : public PlatformTest, public WithTaskEnvironment { static std::unique_ptr<ConfiguredProxyResolutionService> CreateFixedProxyResolutionService(const std::string& proxy) { - return ConfiguredProxyResolutionService::CreateFixed( + return ConfiguredProxyResolutionService::CreateFixedForTest( proxy, TRAFFIC_ANNOTATION_FOR_TESTS); } @@ -3732,12 +3731,11 @@ int FixedDateNetworkDelegate::OnHeadersReceived( scoped_refptr<HttpResponseHeaders>* override_response_headers, const IPEndPoint& endpoint, absl::optional<GURL>* preserve_fragment_on_redirect_url) { - HttpResponseHeaders* new_response_headers = - new HttpResponseHeaders(original_response_headers->raw_headers()); + *override_response_headers = base::MakeRefCounted<HttpResponseHeaders>( + original_response_headers->raw_headers()); - new_response_headers->SetHeader("Date", fixed_date_); + (*override_response_headers)->SetHeader("Date", fixed_date_); - *override_response_headers = new_response_headers; return TestNetworkDelegate::OnHeadersReceived( request, std::move(callback), original_response_headers, override_response_headers, endpoint, preserve_fragment_on_redirect_url); @@ -3988,8 +3986,8 @@ class URLRequestTestHTTP : public URLRequestTest { void HTTPUploadDataOperationTest(const std::string& method) { const int kMsgSize = 20000; // multiple of 10 const int kIterations = 50; - char* uploadBytes = new char[kMsgSize + 1]; - char* ptr = uploadBytes; + auto uploadBytes = std::make_unique<char[]>(kMsgSize + 1); + char* ptr = uploadBytes.get(); char marker = 'a'; for (int idx = 0; idx < kMsgSize / 10; idx++) { memcpy(ptr, "----------", 10); @@ -4010,7 +4008,7 @@ class URLRequestTestHTTP : public URLRequestTest { TRAFFIC_ANNOTATION_FOR_TESTS)); r->set_method(method.c_str()); - r->set_upload(CreateSimpleUploadData(uploadBytes)); + r->set_upload(CreateSimpleUploadData(uploadBytes.get())); r->Start(); EXPECT_TRUE(r->is_pending()); @@ -4021,9 +4019,9 @@ class URLRequestTestHTTP : public URLRequestTest { << "request failed. Error: " << d.request_status(); EXPECT_FALSE(d.received_data_before_response()); - EXPECT_EQ(uploadBytes, d.data_received()); + EXPECT_EQ(base::StringPiece(uploadBytes.get(), kMsgSize), + d.data_received()); } - delete[] uploadBytes; } HttpTestServer* http_test_server() { return &test_server_; } @@ -4044,8 +4042,7 @@ std::unique_ptr<test_server::HttpResponse> HandleRedirectConnect( return nullptr; } - std::unique_ptr<test_server::BasicHttpResponse> http_response( - new test_server::BasicHttpResponse); + auto http_response = std::make_unique<test_server::BasicHttpResponse>(); http_response->set_code(HTTP_FOUND); http_response->AddCustomHeader("Location", "http://www.destination.com/foo.js"); @@ -4134,7 +4131,6 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) { BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, BlockingNetworkDelegate::ON_HEADERS_RECEIVED}; - static const size_t blocking_stages_length = std::size(blocking_stages); ASSERT_TRUE(http_test_server()->Start()); @@ -4155,10 +4151,9 @@ TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) { TRAFFIC_ANNOTATION_FOR_TESTS)); r->Start(); - for (size_t i = 0; i < blocking_stages_length; ++i) { + for (auto stage : blocking_stages) { network_delegate.RunUntilBlocked(); - EXPECT_EQ(blocking_stages[i], - network_delegate.stage_blocked_for_callback()); + EXPECT_EQ(stage, network_delegate.stage_blocked_for_callback()); network_delegate.DoCallback(OK); } d.RunUntilComplete(); @@ -4678,12 +4673,11 @@ std::unique_ptr<test_server::HttpResponse> HandleServerAuthConnect( return nullptr; } - std::unique_ptr<test_server::BasicHttpResponse> http_response( - new test_server::BasicHttpResponse); + auto http_response = std::make_unique<test_server::BasicHttpResponse>(); http_response->set_code(HTTP_UNAUTHORIZED); http_response->AddCustomHeader("WWW-Authenticate", "Basic realm=\"WallyWorld\""); - return std::move(http_response); + return http_response; } } // namespace @@ -5921,7 +5915,7 @@ TEST_F(URLRequestTestHTTP, PostFileTest) { ASSERT_EQ(true, base::GetFileSize(path, &size64)); ASSERT_LE(size64, std::numeric_limits<int>::max()); int size = static_cast<int>(size64); - std::unique_ptr<char[]> buf(new char[size]); + auto buf = std::make_unique<char[]>(size); ASSERT_EQ(size, base::ReadFile(path, buf.get(), size)); @@ -6006,8 +6000,7 @@ TEST_F(URLRequestTestHTTP, TestPostChunkedDataBeforeStart) { std::unique_ptr<URLRequest> r(default_context().CreateRequest( http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); - std::unique_ptr<ChunkedUploadDataStream> upload_data_stream( - new ChunkedUploadDataStream(0)); + auto upload_data_stream = std::make_unique<ChunkedUploadDataStream>(0); std::unique_ptr<ChunkedUploadDataStream::Writer> writer = upload_data_stream->CreateWriter(); r->set_upload(std::move(upload_data_stream)); @@ -6030,8 +6023,7 @@ TEST_F(URLRequestTestHTTP, TestPostChunkedDataJustAfterStart) { std::unique_ptr<URLRequest> r(default_context().CreateRequest( http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); - std::unique_ptr<ChunkedUploadDataStream> upload_data_stream( - new ChunkedUploadDataStream(0)); + auto upload_data_stream = std::make_unique<ChunkedUploadDataStream>(0); std::unique_ptr<ChunkedUploadDataStream::Writer> writer = upload_data_stream->CreateWriter(); r->set_upload(std::move(upload_data_stream)); @@ -6053,8 +6045,7 @@ TEST_F(URLRequestTestHTTP, TestPostChunkedDataAfterStart) { std::unique_ptr<URLRequest> r(default_context().CreateRequest( http_test_server()->GetURL("/echo"), DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); - std::unique_ptr<ChunkedUploadDataStream> upload_data_stream( - new ChunkedUploadDataStream(0)); + auto upload_data_stream = std::make_unique<ChunkedUploadDataStream>(0); std::unique_ptr<ChunkedUploadDataStream::Writer> writer = upload_data_stream->CreateWriter(); r->set_upload(std::move(upload_data_stream)); @@ -9006,15 +8997,15 @@ TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) { {"/echoheader?Accept-Charset", "None"}, {"/echoheader?User-Agent", ""}}; - for (size_t i = 0; i < std::size(tests); i++) { + for (const auto& test : tests) { TestDelegate d; std::unique_ptr<URLRequest> req(context->CreateRequest( - http_test_server()->GetURL(tests[i].request), DEFAULT_PRIORITY, &d, + http_test_server()->GetURL(test.request), DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); req->Start(); d.RunUntilComplete(); - EXPECT_EQ(tests[i].expected_response, d.data_received()) - << " Request = \"" << tests[i].request << "\""; + EXPECT_EQ(test.expected_response, d.data_received()) + << " Request = \"" << test.request << "\""; } } @@ -9121,7 +9112,16 @@ class FailingHttpTransactionFactory : public HttpTransactionFactory { // This currently only happens when in suspend mode and there's no cache, but // just use a special HttpTransactionFactory, to avoid depending on those // behaviors. -TEST_F(URLRequestTestHTTP, NetworkCancelAfterCreateTransactionFailsTest) { +// +// Flaky crash: https://crbug.com/1348418 +#if BUILDFLAG(IS_CHROMEOS) +#define MAYBE_NetworkCancelAfterCreateTransactionFailsTest \ + DISABLED_NetworkCancelAfterCreateTransactionFailsTest +#else +#define MAYBE_NetworkCancelAfterCreateTransactionFailsTest \ + NetworkCancelAfterCreateTransactionFailsTest +#endif +TEST_F(URLRequestTestHTTP, MAYBE_NetworkCancelAfterCreateTransactionFailsTest) { auto context_builder = CreateTestURLRequestContextBuilder(); context_builder->SetCreateHttpTransactionFactoryCallback( base::BindOnce([](HttpNetworkSession* session) { @@ -10729,9 +10729,9 @@ class HTTPSCertNetFetchingTest : public HTTPSRequestTest { }; // The test EV policy OID used for generated certs. -static const char kOCSPTestCertPolicy[] = "1.3.6.1.4.1.11129.2.4.1"; +static const char kEVTestCertPolicy[] = "1.3.6.1.4.1.11129.2.4.1"; -class HTTPSOCSPTest : public HTTPSCertNetFetchingTest { +class HTTPSEVTest : public HTTPSCertNetFetchingTest { public: void SetUp() override { HTTPSCertNetFetchingTest::SetUp(); @@ -10743,19 +10743,22 @@ class HTTPSOCSPTest : public HTTPSCertNetFetchingTest { ev_test_policy_ = std::make_unique<ScopedTestEVPolicy>( EVRootCAMetadata::GetInstance(), X509Certificate::CalculateFingerprint256(root_cert->cert_buffer()), - kOCSPTestCertPolicy); + kEVTestCertPolicy); } void TearDown() override { HTTPSCertNetFetchingTest::TearDown(); } + private: + std::unique_ptr<ScopedTestEVPolicy> ev_test_policy_; +}; + +class HTTPSOCSPTest : public HTTPSCertNetFetchingTest { + public: CertVerifier::Config GetCertVerifierConfig() override { CertVerifier::Config config; config.enable_rev_checking = true; return config; } - - private: - std::unique_ptr<ScopedTestEVPolicy> ev_test_policy_; }; static bool UsingBuiltinCertVerifier() { @@ -10766,6 +10769,10 @@ static bool UsingBuiltinCertVerifier() { if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature)) return true; #endif +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + if (base::FeatureList::IsEnabled(features::kChromeRootStoreUsed)) + return true; +#endif return false; #endif } @@ -10803,7 +10810,7 @@ static bool SystemUsesChromiumEVMetadata() { static bool SystemSupportsOCSP() { #if BUILDFLAG(IS_ANDROID) - // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported. + // Unsupported, see http://crbug.com/117478. return false; #else return true; @@ -10830,6 +10837,25 @@ static bool SystemSupportsCRLSets() { #endif } +TEST_F(HTTPSEVTest, EVCheckNoOCSP) { + if (!SystemUsesChromiumEVMetadata()) { + LOG(WARNING) << "Skipping test because system doesn't support EV"; + return; + } + EmbeddedTestServer::ServerCertificateConfig cert_config; + cert_config.policy_oids = {kEVTestCertPolicy}; + + CertStatus cert_status; + DoConnection(cert_config, &cert_status); + + EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); + + EXPECT_EQ(SystemUsesChromiumEVMetadata(), + static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); + + EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); +} + TEST_F(HTTPSOCSPTest, Valid) { if (!SystemSupportsOCSP()) { LOG(WARNING) << "Skipping test because system doesn't support OCSP"; @@ -10837,7 +10863,6 @@ TEST_F(HTTPSOCSPTest, Valid) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( {{OCSPRevocationStatus::GOOD, EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); @@ -10847,9 +10872,6 @@ TEST_F(HTTPSOCSPTest, Valid) { EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); - EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -10860,7 +10882,6 @@ TEST_F(HTTPSOCSPTest, Revoked) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( {{OCSPRevocationStatus::REVOKED, EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); @@ -10880,7 +10901,6 @@ TEST_F(HTTPSOCSPTest, Invalid) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( EmbeddedTestServer::OCSPConfig::ResponseType::kInvalidResponse); @@ -10901,7 +10921,6 @@ TEST_F(HTTPSOCSPTest, IntermediateValid) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.intermediate = EmbeddedTestServer::IntermediateType::kInHandshake; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( {{OCSPRevocationStatus::GOOD, @@ -10915,9 +10934,6 @@ TEST_F(HTTPSOCSPTest, IntermediateValid) { EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); - EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -10928,7 +10944,6 @@ TEST_F(HTTPSOCSPTest, IntermediateResponseOldButStillValid) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.intermediate = EmbeddedTestServer::IntermediateType::kInHandshake; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( {{OCSPRevocationStatus::GOOD, @@ -10936,17 +10951,25 @@ TEST_F(HTTPSOCSPTest, IntermediateResponseOldButStillValid) { // Use an OCSP response for the intermediate that would be too old for a leaf // cert, but is still valid for an intermediate. cert_config.intermediate_ocsp_config = EmbeddedTestServer::OCSPConfig( - {{OCSPRevocationStatus::GOOD, + {{OCSPRevocationStatus::REVOKED, EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kLong}}); CertStatus cert_status; DoConnection(cert_config, &cert_status); - EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); - + if (UsingBuiltinCertVerifier()) { + EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); + } else { +#if BUILDFLAG(IS_WIN) + // TODO(mattm): Seems to be flaky on Windows. Either returns + // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION (which gets masked off due to + // soft-fail), or CERT_STATUS_REVOKED. + EXPECT_THAT(cert_status & CERT_STATUS_ALL_ERRORS, + AnyOf(0u, CERT_STATUS_REVOKED)); +#else + EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); +#endif + } EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -10957,28 +10980,29 @@ TEST_F(HTTPSOCSPTest, IntermediateResponseTooOld) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.intermediate = EmbeddedTestServer::IntermediateType::kInHandshake; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( {{OCSPRevocationStatus::GOOD, EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); cert_config.intermediate_ocsp_config = EmbeddedTestServer::OCSPConfig( - {{OCSPRevocationStatus::GOOD, + {{OCSPRevocationStatus::REVOKED, EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kLonger}}); CertStatus cert_status; DoConnection(cert_config, &cert_status); if (UsingBuiltinCertVerifier()) { - // The builtin verifier enforces the baseline requirements for max age of an - // intermediate's OCSP response, so the connection is considered non-EV. EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(0u, cert_status & CERT_STATUS_IS_EV); } else { - // The platform verifiers are more lenient. - EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); +#if BUILDFLAG(IS_WIN) + // TODO(mattm): Seems to be flaky on Windows. Either returns + // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION (which gets masked off due to + // soft-fail), or CERT_STATUS_REVOKED. + EXPECT_THAT(cert_status & CERT_STATUS_ALL_ERRORS, + AnyOf(0u, CERT_STATUS_REVOKED)); +#else + EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); +#endif } EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -10990,7 +11014,6 @@ TEST_F(HTTPSOCSPTest, IntermediateRevoked) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.intermediate = EmbeddedTestServer::IntermediateType::kInHandshake; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( {{OCSPRevocationStatus::GOOD, @@ -11002,6 +11025,9 @@ TEST_F(HTTPSOCSPTest, IntermediateRevoked) { CertStatus cert_status; DoConnection(cert_config, &cert_status); + if (UsingBuiltinCertVerifier()) { + EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); + } else { #if BUILDFLAG(IS_WIN) // TODO(mattm): Seems to be flaky on Windows. Either returns // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION (which gets masked off due to @@ -11011,7 +11037,7 @@ TEST_F(HTTPSOCSPTest, IntermediateRevoked) { #else EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); #endif - EXPECT_EQ(0u, cert_status & CERT_STATUS_IS_EV); + } EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -11023,7 +11049,6 @@ TEST_F(HTTPSOCSPTest, ValidStapled) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; // AIA OCSP url is included, but does not return a successful ocsp response. cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( @@ -11037,10 +11062,6 @@ TEST_F(HTTPSOCSPTest, ValidStapled) { DoConnection(cert_config, &cert_status); EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); - EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -11052,7 +11073,6 @@ TEST_F(HTTPSOCSPTest, RevokedStapled) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; // AIA OCSP url is included, but does not return a successful ocsp response. cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( @@ -11066,7 +11086,6 @@ TEST_F(HTTPSOCSPTest, RevokedStapled) { DoConnection(cert_config, &cert_status); EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -11078,7 +11097,6 @@ TEST_F(HTTPSOCSPTest, OldStapledAndInvalidAIA) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; // Stapled response indicates good, but is too old. cert_config.stapled_ocsp_config = EmbeddedTestServer::OCSPConfig( @@ -11093,7 +11111,6 @@ TEST_F(HTTPSOCSPTest, OldStapledAndInvalidAIA) { DoConnection(cert_config, &cert_status); EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -11105,7 +11122,6 @@ TEST_F(HTTPSOCSPTest, OldStapledButValidAIA) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; // Stapled response indicates good, but response is too old. cert_config.stapled_ocsp_config = EmbeddedTestServer::OCSPConfig( @@ -11121,8 +11137,6 @@ TEST_F(HTTPSOCSPTest, OldStapledButValidAIA) { DoConnection(cert_config, &cert_status); EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } @@ -11334,7 +11348,6 @@ TEST_P(HTTPSOCSPVerifyTest, VerifyResult) { OCSPVerifyTestData test = GetParam(); EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.stapled_ocsp_config = test.ocsp_config; SSLInfo ssl_info; @@ -11403,7 +11416,7 @@ class HTTPSHardFailTest : public HTTPSOCSPTest { } }; -TEST_F(HTTPSHardFailTest, FailsOnOCSPInvalid) { +TEST_F(HTTPSHardFailTest, Valid) { if (!SystemSupportsOCSP()) { LOG(WARNING) << "Skipping test because system doesn't support OCSP"; return; @@ -11416,96 +11429,152 @@ TEST_F(HTTPSHardFailTest, FailsOnOCSPInvalid) { } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( - EmbeddedTestServer::OCSPConfig::ResponseType::kInvalidResponse); + {{OCSPRevocationStatus::GOOD, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); CertStatus cert_status; DoConnection(cert_config, &cert_status); - EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, - cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); +} + +TEST_F(HTTPSHardFailTest, Revoked) { + if (!SystemSupportsOCSP()) { + LOG(WARNING) << "Skipping test because system doesn't support OCSP"; + return; + } + + if (!SystemSupportsHardFailRevocationChecking()) { + LOG(WARNING) << "Skipping test because system doesn't support hard fail " + << "revocation checking"; + return; + } - // Without a positive OCSP response, we shouldn't show the EV status. + EmbeddedTestServer::ServerCertificateConfig cert_config; + cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( + {{OCSPRevocationStatus::REVOKED, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); + + CertStatus cert_status; + DoConnection(cert_config, &cert_status); + + EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } -class HTTPSEVCRLSetTest : public HTTPSOCSPTest { - protected: - CertVerifier::Config GetCertVerifierConfig() override { - CertVerifier::Config config; - return config; +TEST_F(HTTPSHardFailTest, FailsOnOCSPInvalid) { + if (!SystemSupportsOCSP()) { + LOG(WARNING) << "Skipping test because system doesn't support OCSP"; + return; } -}; -TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndInvalidOCSP) { + if (!SystemSupportsHardFailRevocationChecking()) { + LOG(WARNING) << "Skipping test because system doesn't support hard fail " + << "revocation checking"; + return; + } + + EmbeddedTestServer::ServerCertificateConfig cert_config; + cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( + EmbeddedTestServer::OCSPConfig::ResponseType::kInvalidResponse); + + CertStatus cert_status; + DoConnection(cert_config, &cert_status); + + EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, + cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); +} + +TEST_F(HTTPSHardFailTest, IntermediateResponseOldButStillValid) { if (!SystemSupportsOCSP()) { LOG(WARNING) << "Skipping test because system doesn't support OCSP"; return; } + if (!SystemSupportsHardFailRevocationChecking()) { + LOG(WARNING) << "Skipping test because system doesn't support hard fail " + << "revocation checking"; + return; + } + EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; + cert_config.intermediate = EmbeddedTestServer::IntermediateType::kInHandshake; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( - EmbeddedTestServer::OCSPConfig::ResponseType::kInvalidResponse); + {{OCSPRevocationStatus::GOOD, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); + // Use an OCSP response for the intermediate that would be too old for a leaf + // cert, but is still valid for an intermediate. + cert_config.intermediate_ocsp_config = EmbeddedTestServer::OCSPConfig( + {{OCSPRevocationStatus::GOOD, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kLong}}); CertStatus cert_status; DoConnection(cert_config, &cert_status); EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); + EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } -TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndRevokedOCSP) { +TEST_F(HTTPSHardFailTest, IntermediateResponseTooOld) { if (!SystemSupportsOCSP()) { LOG(WARNING) << "Skipping test because system doesn't support OCSP"; return; } + if (!SystemSupportsHardFailRevocationChecking()) { + LOG(WARNING) << "Skipping test because system doesn't support hard fail " + << "revocation checking"; + return; + } + EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; + cert_config.intermediate = EmbeddedTestServer::IntermediateType::kInHandshake; cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( - {{OCSPRevocationStatus::REVOKED, + {{OCSPRevocationStatus::GOOD, EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); + // Use an OCSP response for the intermediate that is too old. + cert_config.intermediate_ocsp_config = EmbeddedTestServer::OCSPConfig( + {{OCSPRevocationStatus::GOOD, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kLonger}}); CertStatus cert_status; DoConnection(cert_config, &cert_status); - // The CertVerifyProc implementations handle revocation on the EV - // verification differently. Some will return a revoked error, others will - // return the non-EV verification result. For example on NSS it's not - // possible to determine whether the EV verification attempt failed because - // of actual revocation or because there was an OCSP failure. if (UsingBuiltinCertVerifier()) { - // TODO(https://crbug.com/410574): Handle this in builtin verifier too? - EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, + cert_status & CERT_STATUS_ALL_ERRORS); } else { -#if BUILDFLAG(IS_APPLE) - EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); -#elif BUILDFLAG(IS_WIN) - EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); -#else + // Platform verifier are more lenient. EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); -#endif } - EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); + EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } -TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndGoodOCSP) { - if (!SystemSupportsOCSP()) { - LOG(WARNING) << "Skipping test because system doesn't support OCSP"; +TEST_F(HTTPSHardFailTest, ValidStapled) { + if (!SystemSupportsOCSPStapling()) { + LOG(WARNING) + << "Skipping test because system doesn't support OCSP stapling"; + return; + } + + if (!SystemSupportsHardFailRevocationChecking()) { + LOG(WARNING) << "Skipping test because system doesn't support hard fail " + << "revocation checking"; return; } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; + + // AIA OCSP url is included, but does not return a successful ocsp response. cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( + EmbeddedTestServer::OCSPConfig::ResponseType::kTryLater); + + cert_config.stapled_ocsp_config = EmbeddedTestServer::OCSPConfig( {{OCSPRevocationStatus::GOOD, EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); @@ -11513,94 +11582,101 @@ TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndGoodOCSP) { DoConnection(cert_config, &cert_status); EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); + EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } -TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSet) { - if (!SystemSupportsOCSP()) { - LOG(WARNING) << "Skipping test because system doesn't support OCSP"; +TEST_F(HTTPSHardFailTest, RevokedStapled) { + if (!SystemSupportsOCSPStapling()) { + LOG(WARNING) + << "Skipping test because system doesn't support OCSP stapling"; + return; + } + + if (!SystemSupportsHardFailRevocationChecking()) { + LOG(WARNING) << "Skipping test because system doesn't support hard fail " + << "revocation checking"; return; } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; + + // AIA OCSP url is included, but does not return a successful ocsp response. cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( - EmbeddedTestServer::OCSPConfig::ResponseType::kInvalidResponse); + EmbeddedTestServer::OCSPConfig::ResponseType::kTryLater); - CertVerifier::Config cert_verifier_config = GetCertVerifierConfig(); - cert_verifier_config.crl_set = CRLSet::ExpiredCRLSetForTesting(); - context_->cert_verifier()->SetConfig(cert_verifier_config); + cert_config.stapled_ocsp_config = EmbeddedTestServer::OCSPConfig( + {{OCSPRevocationStatus::REVOKED, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); CertStatus cert_status; DoConnection(cert_config, &cert_status); - EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); + EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } -TEST_F(HTTPSEVCRLSetTest, FreshCRLSetCovered) { - if (!SystemSupportsOCSP()) { - LOG(WARNING) << "Skipping test because system doesn't support OCSP"; +TEST_F(HTTPSHardFailTest, OldStapledAndInvalidAIA) { + if (!SystemSupportsOCSPStapling()) { + LOG(WARNING) + << "Skipping test because system doesn't support OCSP stapling"; + return; + } + + if (!SystemSupportsHardFailRevocationChecking()) { + LOG(WARNING) << "Skipping test because system doesn't support hard fail " + << "revocation checking"; return; } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; - cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( - EmbeddedTestServer::OCSPConfig::ResponseType::kInvalidResponse); - CertVerifier::Config cert_verifier_config = GetCertVerifierConfig(); - SHA256HashValue root_cert_spki_hash; - ASSERT_TRUE(GetTestRootCertSPKIHash(&root_cert_spki_hash)); - cert_verifier_config.crl_set = - CRLSet::ForTesting(false, &root_cert_spki_hash, "", "", {}); - context_->cert_verifier()->SetConfig(cert_verifier_config); + // Stapled response indicates good, but is too old. + cert_config.stapled_ocsp_config = EmbeddedTestServer::OCSPConfig( + {{OCSPRevocationStatus::GOOD, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kOld}}); + + // AIA OCSP url is included, but does not return a successful ocsp response. + cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( + EmbeddedTestServer::OCSPConfig::ResponseType::kTryLater); CertStatus cert_status; DoConnection(cert_config, &cert_status); - // With a fresh CRLSet that covers the issuing certificate, we shouldn't do a - // revocation check for EV. - EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); - EXPECT_FALSE( - static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); + EXPECT_EQ(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, + cert_status & CERT_STATUS_ALL_ERRORS); + EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } -TEST_F(HTTPSEVCRLSetTest, FreshCRLSetNotCovered) { - if (!SystemSupportsOCSP()) { - LOG(WARNING) << "Skipping test because system doesn't support OCSP"; +TEST_F(HTTPSHardFailTest, OldStapledButValidAIA) { + if (!SystemSupportsOCSPStapling()) { + LOG(WARNING) + << "Skipping test because system doesn't support OCSP stapling"; + return; + } + + if (!SystemSupportsHardFailRevocationChecking()) { + LOG(WARNING) << "Skipping test because system doesn't support hard fail " + << "revocation checking"; return; } EmbeddedTestServer::ServerCertificateConfig cert_config; - cert_config.policy_oids = {kOCSPTestCertPolicy}; - cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( - EmbeddedTestServer::OCSPConfig::ResponseType::kInvalidResponse); - CertVerifier::Config cert_verifier_config = GetCertVerifierConfig(); - cert_verifier_config.crl_set = CRLSet::EmptyCRLSetForTesting(); - context_->cert_verifier()->SetConfig(cert_verifier_config); + // Stapled response indicates good, but response is too old. + cert_config.stapled_ocsp_config = EmbeddedTestServer::OCSPConfig( + {{OCSPRevocationStatus::GOOD, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kOld}}); - CertStatus cert_status = 0; + // AIA OCSP url is included, and returns a successful ocsp response. + cert_config.ocsp_config = EmbeddedTestServer::OCSPConfig( + {{OCSPRevocationStatus::GOOD, + EmbeddedTestServer::OCSPConfig::SingleResponse::Date::kValid}}); + + CertStatus cert_status; DoConnection(cert_config, &cert_status); - // Even with a fresh CRLSet, we should still do online revocation checks when - // the certificate chain isn't covered by the CRLSet, which it isn't in this - // test. Since the online revocation check returns an invalid OCSP response, - // the result should be non-EV but with REV_CHECKING_ENABLED status set to - // indicate online revocation checking was attempted. EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); - EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); - EXPECT_EQ(SystemUsesChromiumEVMetadata(), - static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); + EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } class HTTPSCRLSetTest : public HTTPSCertNetFetchingTest {}; @@ -12150,7 +12226,8 @@ TEST_F(URLRequestTestHTTP, HeadersCallbacksAuthRetry) { auto req_headers_callback = base::BindRepeating( [](ReqHeadersVector* vec, HttpRawRequestHeaders headers) { - vec->emplace_back(new HttpRawRequestHeaders(std::move(headers))); + vec->emplace_back( + std::make_unique<HttpRawRequestHeaders>(std::move(headers))); }, &raw_req_headers); auto resp_headers_callback = base::BindRepeating( @@ -12379,7 +12456,7 @@ class ZeroRTTResponse : public test_server::BasicHttpResponse { ZeroRTTResponse(const ZeroRTTResponse&) = delete; ZeroRTTResponse& operator=(const ZeroRTTResponse&) = delete; - ~ZeroRTTResponse() override {} + ~ZeroRTTResponse() override = default; void SendResponse( base::WeakPtr<test_server::HttpResponseDelegate> delegate) override { |