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/http | |
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/http')
118 files changed, 4335 insertions, 2207 deletions
diff --git a/chromium/net/http/OWNERS b/chromium/net/http/OWNERS index 49c38c96624..dd32c76bb0f 100644 --- a/chromium/net/http/OWNERS +++ b/chromium/net/http/OWNERS @@ -3,5 +3,8 @@ per-file transport_security_state_static.*=estark@chromium.org per-file transport_security_state_static.*=cthomp@chromium.org per-file transport_security_state_static.*=jdeblasio@chromium.org # For automated updates +# TODO(crbug.com/1342998): Remove mdb.chrome-pki-metadata@google.com once the +# pod batch migration is complete. per-file transport_security_state_static.*=mdb.chrome-pki-metadata@google.com +per-file transport_security_state_static.*=mdb.chrome-pki-metadata-release-jobs@google.com per-file *test*=file://net/quic/OWNERS # for QUIC refactors diff --git a/chromium/net/http/alternative_service.h b/chromium/net/http/alternative_service.h index 91dbc76a7b1..90656bf0939 100644 --- a/chromium/net/http/alternative_service.h +++ b/chromium/net/http/alternative_service.h @@ -27,13 +27,19 @@ enum AlternateProtocolUsage { // Alternate Protocol was used by winning a race with a normal connection. ALTERNATE_PROTOCOL_USAGE_WON_RACE = 1, // Alternate Protocol was not used by losing a race with a normal connection. - ALTERNATE_PROTOCOL_USAGE_LOST_RACE = 2, + ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE = 2, // Alternate Protocol was not used because no Alternate-Protocol information // was available when the request was issued, but an Alternate-Protocol header // was present in the response. ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING = 3, // Alternate Protocol was not used because it was marked broken. ALTERNATE_PROTOCOL_USAGE_BROKEN = 4, + // HTTPS DNS protocol upgrade job was used without racing with a normal + // connection and an Alternate Protocol job. + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_WITOUT_RACE = 5, + // HTTPS DNS protocol upgrade job won a race with a normal connection and + // an Alternate Protocol job. + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE = 6, // Maximum value for the enum. ALTERNATE_PROTOCOL_USAGE_MAX, }; diff --git a/chromium/net/http/bidirectional_stream.cc b/chromium/net/http/bidirectional_stream.cc index 13faebf3845..28bd9a89f8c 100644 --- a/chromium/net/http/bidirectional_stream.cc +++ b/chromium/net/http/bidirectional_stream.cc @@ -29,7 +29,7 @@ #include "net/spdy/spdy_log_util.h" #include "net/ssl/ssl_cert_request_info.h" #include "net/ssl/ssl_config.h" -#include "net/third_party/quiche/src/quiche/spdy/core/spdy_header_block.h" +#include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "url/gurl.h" diff --git a/chromium/net/http/bidirectional_stream.h b/chromium/net/http/bidirectional_stream.h index debf81b1ed0..cae471b0f05 100644 --- a/chromium/net/http/bidirectional_stream.h +++ b/chromium/net/http/bidirectional_stream.h @@ -21,7 +21,7 @@ #include "net/http/http_stream_factory.h" #include "net/http/http_stream_request.h" #include "net/log/net_log_with_source.h" -#include "net/third_party/quiche/src/quiche/spdy/core/spdy_header_block.h" +#include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h" namespace base { class OneShotTimer; diff --git a/chromium/net/http/bidirectional_stream_impl.h b/chromium/net/http/bidirectional_stream_impl.h index 51a068741db..2c151347984 100644 --- a/chromium/net/http/bidirectional_stream_impl.h +++ b/chromium/net/http/bidirectional_stream_impl.h @@ -14,7 +14,7 @@ #include "net/base/load_timing_info.h" #include "net/base/net_export.h" #include "net/socket/next_proto.h" -#include "net/third_party/quiche/src/quiche/spdy/core/spdy_header_block.h" +#include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h" #include "net/traffic_annotation/network_traffic_annotation.h" namespace base { diff --git a/chromium/net/http/bidirectional_stream_unittest.cc b/chromium/net/http/bidirectional_stream_unittest.cc index d39ee35be51..e6ac53f5fc1 100644 --- a/chromium/net/http/bidirectional_stream_unittest.cc +++ b/chromium/net/http/bidirectional_stream_unittest.cc @@ -377,7 +377,7 @@ class DeleteStreamDelegate : public TestDelegateBase { // A Timer that does not start a delayed task unless the timer is fired. class MockTimer : public base::MockOneShotTimer { public: - MockTimer() {} + MockTimer() = default; MockTimer(const MockTimer&) = delete; MockTimer& operator=(const MockTimer&) = delete; @@ -406,8 +406,9 @@ class BidirectionalStreamTest : public TestWithTaskEnvironment { ssl_data_.ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); net_log_observer_.SetObserverCaptureMode(NetLogCaptureMode::kEverything); - socket_factory_ = new MockTaggingClientSocketFactory(); - session_deps_.socket_factory.reset(socket_factory_); + auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>(); + socket_factory_ = socket_factory.get(); + session_deps_.socket_factory = std::move(socket_factory); } protected: @@ -452,15 +453,14 @@ class BidirectionalStreamTest : public TestWithTaskEnvironment { }; TEST_F(BidirectionalStreamTest, CreateInsecureStream) { - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = GURL("http://www.example.org/"); TestDelegateBase delegate(nullptr, 0); - std::unique_ptr<HttpNetworkSession> session(new HttpNetworkSession( + auto session = std::make_unique<HttpNetworkSession>( SpdySessionDependencies::CreateSessionParams(&session_deps_), - SpdySessionDependencies::CreateSessionContext(&session_deps_))); + SpdySessionDependencies::CreateSessionContext(&session_deps_)); delegate.SetRunUntilCompletion(true); delegate.Start(std::move(request_info), session.get()); @@ -485,16 +485,15 @@ TEST_F(BidirectionalStreamTest, SimplePostRequest) { }; InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "POST"; request_info->url = default_url_; request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength, base::NumberToString(kBodyDataSize)); scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<TestDelegateBase> delegate( - new TestDelegateBase(read_buffer.get(), kReadBufferSize)); + auto delegate = + std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize); delegate->Start(std::move(request_info), http_session_.get()); sequenced_data_->RunUntilPaused(); @@ -535,13 +534,11 @@ TEST_F(BidirectionalStreamTest, LoadTimingTwoRequests) { MockRead(ASYNC, 0, 6)}; InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->end_stream_on_headers = true; - std::unique_ptr<BidirectionalStreamRequestInfo> request_info2( - new BidirectionalStreamRequestInfo); + auto request_info2 = std::make_unique<BidirectionalStreamRequestInfo>(); request_info2->method = "GET"; request_info2->url = default_url_; request_info2->end_stream_on_headers = true; @@ -550,10 +547,10 @@ TEST_F(BidirectionalStreamTest, LoadTimingTwoRequests) { base::MakeRefCounted<IOBuffer>(kReadBufferSize); scoped_refptr<IOBuffer> read_buffer2 = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<TestDelegateBase> delegate( - new TestDelegateBase(read_buffer.get(), kReadBufferSize)); - std::unique_ptr<TestDelegateBase> delegate2( - new TestDelegateBase(read_buffer2.get(), kReadBufferSize)); + auto delegate = + std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize); + auto delegate2 = + std::make_unique<TestDelegateBase>(read_buffer2.get(), kReadBufferSize); delegate->Start(std::move(request_info), http_session_.get()); delegate2->Start(std::move(request_info2), http_session_.get()); delegate->SetRunUntilCompletion(true); @@ -574,15 +571,14 @@ TEST_F(BidirectionalStreamTest, LoadTimingTwoRequests) { // without waiting for the OnFailed task to be executed. TEST_F(BidirectionalStreamTest, CreateInsecureStreamAndDestroyStreamRightAfter) { - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = GURL("http://www.example.org/"); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase(nullptr, 0)); - std::unique_ptr<HttpNetworkSession> session(new HttpNetworkSession( + auto delegate = std::make_unique<TestDelegateBase>(nullptr, 0); + auto session = std::make_unique<HttpNetworkSession>( SpdySessionDependencies::CreateSessionParams(&session_deps_), - SpdySessionDependencies::CreateSessionContext(&session_deps_))); + SpdySessionDependencies::CreateSessionContext(&session_deps_)); delegate->Start(std::move(request_info), session.get()); // Reset stream right before the OnFailed task is executed. delegate.reset(); @@ -629,8 +625,7 @@ TEST_F(BidirectionalStreamTest, ClientAuthRequestIgnored) { PRIVACY_MODE_DISABLED, SpdySessionKey::IsProxySession::kFalse, SocketTag(), NetworkIsolationKey(), SecureDnsPolicy::kAllow); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->end_stream_on_headers = true; @@ -638,8 +633,8 @@ TEST_F(BidirectionalStreamTest, ClientAuthRequestIgnored) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<TestDelegateBase> delegate( - new TestDelegateBase(read_buffer.get(), kReadBufferSize)); + auto delegate = + std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize); delegate->SetRunUntilCompletion(true); delegate->Start(std::move(request_info), http_session_.get()); @@ -690,8 +685,7 @@ TEST_F(BidirectionalStreamTest, TestReadDataAfterClose) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->end_stream_on_headers = true; @@ -701,23 +695,24 @@ TEST_F(BidirectionalStreamTest, TestReadDataAfterClose) { base::MakeRefCounted<IOBuffer>(kReadBufferSize); // Create a MockTimer. Retain a raw pointer since the underlying // BidirectionalStreamImpl owns it. - MockTimer* timer = new MockTimer(); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( - read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); + auto timer = std::make_unique<MockTimer>(); + MockTimer* timer_ptr = timer.get(); + auto delegate = std::make_unique<TestDelegateBase>( + read_buffer.get(), kReadBufferSize, std::move(timer)); delegate->set_do_not_start_read(true); delegate->Start(std::move(request_info), http_session_.get()); // Write request, and deliver response headers. sequenced_data_->RunUntilPaused(); - EXPECT_FALSE(timer->IsRunning()); + EXPECT_FALSE(timer_ptr->IsRunning()); // ReadData returns asynchronously because no data is buffered. int rv = delegate->ReadData(); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Deliver a DATA frame. sequenced_data_->Resume(); base::RunLoop().RunUntilIdle(); - timer->Fire(); + timer_ptr->Fire(); // Asynchronous completion callback is invoke. EXPECT_EQ(1, delegate->on_data_read_count()); EXPECT_EQ(kUploadDataSize * 1, @@ -776,8 +771,7 @@ TEST_F(BidirectionalStreamTest, TestNetLogContainEntries) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "POST"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -787,14 +781,15 @@ TEST_F(BidirectionalStreamTest, TestNetLogContainEntries) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - MockTimer* timer = new MockTimer(); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( - read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); + auto timer = std::make_unique<MockTimer>(); + MockTimer* timer_ptr = timer.get(); + auto delegate = std::make_unique<TestDelegateBase>( + read_buffer.get(), kReadBufferSize, std::move(timer)); delegate->set_do_not_start_read(true); delegate->Start(std::move(request_info), http_session_.get()); // Send the request and receive response headers. sequenced_data_->RunUntilPaused(); - EXPECT_FALSE(timer->IsRunning()); + EXPECT_FALSE(timer_ptr->IsRunning()); scoped_refptr<StringIOBuffer> buf = base::MakeRefCounted<StringIOBuffer>(kBodyDataString); @@ -809,7 +804,7 @@ TEST_F(BidirectionalStreamTest, TestNetLogContainEntries) { // |sequenced_data_| is now stopped after delivering first DATA frame but // before the second DATA frame. // Fire the timer to allow the first ReadData to complete asynchronously. - timer->Fire(); + timer_ptr->Fire(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, delegate->on_data_read_count()); @@ -913,8 +908,7 @@ TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "POST"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -924,14 +918,15 @@ TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - MockTimer* timer = new MockTimer(); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( - read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); + auto timer = std::make_unique<MockTimer>(); + MockTimer* timer_ptr = timer.get(); + auto delegate = std::make_unique<TestDelegateBase>( + read_buffer.get(), kReadBufferSize, std::move(timer)); delegate->set_do_not_start_read(true); delegate->Start(std::move(request_info), http_session_.get()); // Send the request and receive response headers. sequenced_data_->RunUntilPaused(); - EXPECT_FALSE(timer->IsRunning()); + EXPECT_FALSE(timer_ptr->IsRunning()); // Send a DATA frame. scoped_refptr<StringIOBuffer> buf = @@ -945,7 +940,7 @@ TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) { // Deliver a DATA frame, and fire the timer. sequenced_data_->Resume(); sequenced_data_->RunUntilPaused(); - timer->Fire(); + timer_ptr->Fire(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, delegate->on_data_sent_count()); EXPECT_EQ(1, delegate->on_data_read_count()); @@ -958,7 +953,7 @@ TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) { // Deliver a DATA frame, and fire the timer. sequenced_data_->Resume(); sequenced_data_->RunUntilPaused(); - timer->Fire(); + timer_ptr->Fire(); base::RunLoop().RunUntilIdle(); // Last DATA frame is read. Server half closes. EXPECT_EQ(2, delegate->on_data_read_count()); @@ -1004,8 +999,7 @@ TEST_F(BidirectionalStreamTest, TestCoalesceSmallDataBuffers) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "POST"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1015,9 +1009,9 @@ TEST_F(BidirectionalStreamTest, TestCoalesceSmallDataBuffers) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - MockTimer* timer = new MockTimer(); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( - read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); + auto timer = std::make_unique<MockTimer>(); + auto delegate = std::make_unique<TestDelegateBase>( + read_buffer.get(), kReadBufferSize, std::move(timer)); delegate->set_do_not_start_read(true); TestCompletionCallback callback; delegate->Start(std::move(request_info), http_session_.get(), @@ -1097,8 +1091,7 @@ TEST_F(BidirectionalStreamTest, TestCompleteAsyncRead) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1106,14 +1099,15 @@ TEST_F(BidirectionalStreamTest, TestCompleteAsyncRead) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - MockTimer* timer = new MockTimer(); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( - read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); + auto timer = std::make_unique<MockTimer>(); + MockTimer* timer_ptr = timer.get(); + auto delegate = std::make_unique<TestDelegateBase>( + read_buffer.get(), kReadBufferSize, std::move(timer)); delegate->set_do_not_start_read(true); delegate->Start(std::move(request_info), http_session_.get()); // Write request, and deliver response headers. sequenced_data_->RunUntilPaused(); - EXPECT_FALSE(timer->IsRunning()); + EXPECT_FALSE(timer_ptr->IsRunning()); // ReadData should return asynchronously because no data is buffered. int rv = delegate->ReadData(); @@ -1158,8 +1152,7 @@ TEST_F(BidirectionalStreamTest, TestBuffering) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1167,23 +1160,24 @@ TEST_F(BidirectionalStreamTest, TestBuffering) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - MockTimer* timer = new MockTimer(); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( - read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); + auto timer = std::make_unique<MockTimer>(); + MockTimer* timer_ptr = timer.get(); + auto delegate = std::make_unique<TestDelegateBase>( + read_buffer.get(), kReadBufferSize, std::move(timer)); delegate->Start(std::move(request_info), http_session_.get()); // Deliver two DATA frames together. sequenced_data_->RunUntilPaused(); - EXPECT_TRUE(timer->IsRunning()); - timer->Fire(); + EXPECT_TRUE(timer_ptr->IsRunning()); + timer_ptr->Fire(); base::RunLoop().RunUntilIdle(); // This should trigger |more_read_data_pending_| to execute the task at a // later time, and Delegate::OnReadComplete should not have been called. - EXPECT_TRUE(timer->IsRunning()); + EXPECT_TRUE(timer_ptr->IsRunning()); EXPECT_EQ(0, delegate->on_data_read_count()); // Fire the timer now, the two DATA frame should be combined into one // single Delegate::OnReadComplete callback. - timer->Fire(); + timer_ptr->Fire(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, delegate->on_data_read_count()); EXPECT_EQ(kUploadDataSize * 2, @@ -1240,12 +1234,12 @@ TEST_F(BidirectionalStreamTest, TestBufferingWithTrailers) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - MockTimer* timer = new MockTimer(); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( - read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); + auto timer = std::make_unique<MockTimer>(); + MockTimer* timer_ptr = timer.get(); + auto delegate = std::make_unique<TestDelegateBase>( + read_buffer.get(), kReadBufferSize, std::move(timer)); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1254,12 +1248,12 @@ TEST_F(BidirectionalStreamTest, TestBufferingWithTrailers) { delegate->Start(std::move(request_info), http_session_.get()); // Deliver all three DATA frames together. sequenced_data_->RunUntilPaused(); - EXPECT_TRUE(timer->IsRunning()); - timer->Fire(); + EXPECT_TRUE(timer_ptr->IsRunning()); + timer_ptr->Fire(); base::RunLoop().RunUntilIdle(); // This should trigger |more_read_data_pending_| to execute the task at a // later time, and Delegate::OnReadComplete should not have been called. - EXPECT_TRUE(timer->IsRunning()); + EXPECT_TRUE(timer_ptr->IsRunning()); EXPECT_EQ(0, delegate->on_data_read_count()); // Deliver trailers. Remaining read should be completed, since OnClose is @@ -1305,8 +1299,7 @@ TEST_F(BidirectionalStreamTest, DeleteStreamAfterSendData) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "POST"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1316,8 +1309,8 @@ TEST_F(BidirectionalStreamTest, DeleteStreamAfterSendData) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<TestDelegateBase> delegate( - new TestDelegateBase(read_buffer.get(), kReadBufferSize)); + auto delegate = + std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize); delegate->set_do_not_start_read(true); delegate->Start(std::move(request_info), http_session_.get()); // Send the request and receive response headers. @@ -1369,8 +1362,7 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringReadData) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "POST"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1380,8 +1372,8 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringReadData) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<TestDelegateBase> delegate( - new TestDelegateBase(read_buffer.get(), kReadBufferSize)); + auto delegate = + std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize); delegate->set_do_not_start_read(true); delegate->Start(std::move(request_info), http_session_.get()); // Send the request and receive response headers. @@ -1431,8 +1423,7 @@ TEST_F(BidirectionalStreamTest, PropagateProtocolError) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "POST"; request_info->url = default_url_; request_info->extra_headers.SetHeader( @@ -1441,8 +1432,8 @@ TEST_F(BidirectionalStreamTest, PropagateProtocolError) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<TestDelegateBase> delegate( - new TestDelegateBase(read_buffer.get(), kReadBufferSize)); + auto delegate = + std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize); delegate->SetRunUntilCompletion(true); delegate->Start(std::move(request_info), http_session_.get()); @@ -1494,8 +1485,7 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnHeadersReceived) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1503,9 +1493,9 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnHeadersReceived) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate( + auto delegate = std::make_unique<DeleteStreamDelegate>( read_buffer.get(), kReadBufferSize, - DeleteStreamDelegate::Phase::ON_HEADERS_RECEIVED)); + DeleteStreamDelegate::Phase::ON_HEADERS_RECEIVED); delegate->SetRunUntilCompletion(true); delegate->Start(std::move(request_info), http_session_.get()); // Makes sure delegate does not get called. @@ -1549,8 +1539,7 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnDataRead) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1558,9 +1547,9 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnDataRead) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<DeleteStreamDelegate> delegate( - new DeleteStreamDelegate(read_buffer.get(), kReadBufferSize, - DeleteStreamDelegate::Phase::ON_DATA_READ)); + auto delegate = std::make_unique<DeleteStreamDelegate>( + read_buffer.get(), kReadBufferSize, + DeleteStreamDelegate::Phase::ON_DATA_READ); delegate->SetRunUntilCompletion(true); delegate->Start(std::move(request_info), http_session_.get()); // Makes sure delegate does not get called. @@ -1609,8 +1598,7 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnTrailersReceived) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1618,9 +1606,9 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnTrailersReceived) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate( + auto delegate = std::make_unique<DeleteStreamDelegate>( read_buffer.get(), kReadBufferSize, - DeleteStreamDelegate::Phase::ON_TRAILERS_RECEIVED)); + DeleteStreamDelegate::Phase::ON_TRAILERS_RECEIVED); delegate->SetRunUntilCompletion(true); delegate->Start(std::move(request_info), http_session_.get()); // Makes sure delegate does not get called. @@ -1661,8 +1649,7 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnFailed) { InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1670,9 +1657,9 @@ TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnFailed) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<DeleteStreamDelegate> delegate( - new DeleteStreamDelegate(read_buffer.get(), kReadBufferSize, - DeleteStreamDelegate::Phase::ON_FAILED)); + auto delegate = std::make_unique<DeleteStreamDelegate>( + read_buffer.get(), kReadBufferSize, + DeleteStreamDelegate::Phase::ON_FAILED); delegate->SetRunUntilCompletion(true); delegate->Start(std::move(request_info), http_session_.get()); // Makes sure delegate does not get called. @@ -1716,8 +1703,7 @@ TEST_F(BidirectionalStreamTest, TestHonorAlternativeServiceHeader) { session_deps_.enable_quic = true; InitSession(reads, writes, SocketTag()); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "GET"; request_info->url = default_url_; request_info->priority = LOWEST; @@ -1725,9 +1711,9 @@ TEST_F(BidirectionalStreamTest, TestHonorAlternativeServiceHeader) { scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - MockTimer* timer = new MockTimer(); - std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( - read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); + auto timer = std::make_unique<MockTimer>(); + auto delegate = std::make_unique<TestDelegateBase>( + read_buffer.get(), kReadBufferSize, std::move(timer)); delegate->SetRunUntilCompletion(true); delegate->Start(std::move(request_info), http_session_.get()); @@ -1774,8 +1760,7 @@ TEST_F(BidirectionalStreamTest, Tagging) { #endif InitSession(reads, writes, tag); - std::unique_ptr<BidirectionalStreamRequestInfo> request_info( - new BidirectionalStreamRequestInfo); + auto request_info = std::make_unique<BidirectionalStreamRequestInfo>(); request_info->method = "POST"; request_info->url = default_url_; request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength, @@ -1783,8 +1768,8 @@ TEST_F(BidirectionalStreamTest, Tagging) { request_info->socket_tag = tag; scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(kReadBufferSize); - std::unique_ptr<TestDelegateBase> delegate( - new TestDelegateBase(read_buffer.get(), kReadBufferSize)); + auto delegate = + std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize); delegate->Start(std::move(request_info), http_session_.get()); sequenced_data_->RunUntilPaused(); diff --git a/chromium/net/http/broken_alternative_services.h b/chromium/net/http/broken_alternative_services.h index 72a36cbd176..f2e1782445d 100644 --- a/chromium/net/http/broken_alternative_services.h +++ b/chromium/net/http/broken_alternative_services.h @@ -50,7 +50,7 @@ typedef std::list<std::pair<BrokenAlternativeService, base::TimeTicks>> class RecentlyBrokenAlternativeServices : public base::LRUCache<BrokenAlternativeService, int> { public: - RecentlyBrokenAlternativeServices( + explicit RecentlyBrokenAlternativeServices( int max_recently_broken_alternative_service_entries) : base::LRUCache<BrokenAlternativeService, int>( max_recently_broken_alternative_service_entries) {} @@ -74,7 +74,7 @@ class NET_EXPORT_PRIVATE BrokenAlternativeServices { virtual void OnExpireBrokenAlternativeService( const AlternativeService& expired_alternative_service, const NetworkIsolationKey& network_isolation_key) = 0; - virtual ~Delegate() {} + virtual ~Delegate() = default; }; // |delegate| will be notified when a broken alternative service expires. It diff --git a/chromium/net/http/broken_alternative_services_unittest.cc b/chromium/net/http/broken_alternative_services_unittest.cc index 1f331acfe6d..a7b58a266f6 100644 --- a/chromium/net/http/broken_alternative_services_unittest.cc +++ b/chromium/net/http/broken_alternative_services_unittest.cc @@ -28,7 +28,7 @@ class BrokenAlternativeServicesTest public ::testing::Test { public: BrokenAlternativeServicesTest() - : test_task_runner_(new base::TestMockTimeTaskRunner()), + : test_task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>()), test_task_runner_context_(test_task_runner_), broken_services_clock_(test_task_runner_->GetMockTickClock()), broken_services_(50, this, broken_services_clock_) { @@ -42,9 +42,9 @@ class BrokenAlternativeServicesTest void OnExpireBrokenAlternativeService( const AlternativeService& expired_alternative_service, const NetworkIsolationKey& network_isolation_key) override { - expired_alt_svcs_.push_back(BrokenAlternativeService( - expired_alternative_service, network_isolation_key, - true /* use_network_isolation_key */)); + expired_alt_svcs_.emplace_back(expired_alternative_service, + network_isolation_key, + true /* use_network_isolation_key */); } void TestExponentialBackoff(base::TimeDelta initial_delay, diff --git a/chromium/net/http/http_auth_cache.cc b/chromium/net/http/http_auth_cache.cc index 81f82ea9555..4ae47ed7cd2 100644 --- a/chromium/net/http/http_auth_cache.cc +++ b/chromium/net/http/http_auth_cache.cc @@ -341,7 +341,7 @@ void HttpAuthCache::CopyProxyEntriesFrom(const HttpAuthCache& other) { continue; // Sanity check - proxy entries should have an empty NetworkIsolationKey. - DCHECK_EQ(NetworkIsolationKey(), it->first.network_isolation_key); + DCHECK(NetworkIsolationKey() == it->first.network_isolation_key); // Add an Entry with one of the original entry's paths. DCHECK(e.paths_.size() > 0); diff --git a/chromium/net/http/http_auth_controller.cc b/chromium/net/http/http_auth_controller.cc index 576cfb17e12..01809ad2869 100644 --- a/chromium/net/http/http_auth_controller.cc +++ b/chromium/net/http/http_auth_controller.cc @@ -32,10 +32,10 @@ namespace net { namespace { base::Value ControllerParamsToValue(HttpAuth::Target target, const GURL& url) { - base::Value params(base::Value::Type::DICTIONARY); - params.SetStringPath("target", HttpAuth::GetAuthTargetString(target)); - params.SetStringPath("url", url.spec()); - return params; + base::Value::Dict params; + params.Set("target", HttpAuth::GetAuthTargetString(target)); + params.Set("url", url.spec()); + return base::Value(std::move(params)); } } // namespace diff --git a/chromium/net/http/http_auth_controller_unittest.cc b/chromium/net/http/http_auth_controller_unittest.cc index 68d6df5bbd6..c553b83d33f 100644 --- a/chromium/net/http/http_auth_controller_unittest.cc +++ b/chromium/net/http/http_auth_controller_unittest.cc @@ -69,10 +69,11 @@ void RunSingleRoundAuthTest( "\r\n")); HttpAuthHandlerMock::Factory auth_handler_factory; - HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock(); + auto auth_handler = std::make_unique<HttpAuthHandlerMock>(); auth_handler->SetGenerateExpectation((run_mode == RUN_HANDLER_ASYNC), handler_rv); - auth_handler_factory.AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); + auth_handler_factory.AddMockHandler(std::move(auth_handler), + HttpAuth::AUTH_PROXY); auth_handler_factory.set_do_init_from_challenge(true); auto host_resolver = std::make_unique<MockHostResolver>(); @@ -234,29 +235,32 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) { // Handlers for the first attempt at authentication. AUTH_SCHEME_MOCK handler // accepts the default identity and successfully constructs a token. auth_handler_factory.AddMockHandler( - new MockHandler(OK, HttpAuth::AUTH_SCHEME_MOCK), HttpAuth::AUTH_SERVER); + std::make_unique<MockHandler>(OK, HttpAuth::AUTH_SCHEME_MOCK), + HttpAuth::AUTH_SERVER); auth_handler_factory.AddMockHandler( - new MockHandler(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_BASIC), + std::make_unique<MockHandler>(ERR_UNEXPECTED, + HttpAuth::AUTH_SCHEME_BASIC), HttpAuth::AUTH_SERVER); // Handlers for the second attempt. Neither should be used to generate a // token. Instead the controller should realize that there are no viable // identities to use with the AUTH_SCHEME_MOCK handler and fail. auth_handler_factory.AddMockHandler( - new MockHandler(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_MOCK), + std::make_unique<MockHandler>(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_MOCK), HttpAuth::AUTH_SERVER); auth_handler_factory.AddMockHandler( - new MockHandler(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_BASIC), + std::make_unique<MockHandler>(ERR_UNEXPECTED, + HttpAuth::AUTH_SCHEME_BASIC), HttpAuth::AUTH_SERVER); // Fallback handlers for the second attempt. The AUTH_SCHEME_MOCK handler // should be discarded due to the disabled scheme, and the AUTH_SCHEME_BASIC // handler should successfully be used to generate a token. auth_handler_factory.AddMockHandler( - new MockHandler(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_MOCK), + std::make_unique<MockHandler>(ERR_UNEXPECTED, HttpAuth::AUTH_SCHEME_MOCK), HttpAuth::AUTH_SERVER); auth_handler_factory.AddMockHandler( - new MockHandler(OK, HttpAuth::AUTH_SCHEME_BASIC), + std::make_unique<MockHandler>(OK, HttpAuth::AUTH_SCHEME_BASIC), HttpAuth::AUTH_SERVER); auth_handler_factory.set_do_init_from_challenge(true); diff --git a/chromium/net/http/http_auth_filter.h b/chromium/net/http/http_auth_filter.h index c0e42b861e2..f24b81dc906 100644 --- a/chromium/net/http/http_auth_filter.h +++ b/chromium/net/http/http_auth_filter.h @@ -21,7 +21,7 @@ namespace net { // allowed for a particular peer. class NET_EXPORT_PRIVATE HttpAuthFilter { public: - virtual ~HttpAuthFilter() {} + virtual ~HttpAuthFilter() = default; // Checks if (`scheme_host_port`, `target`) is supported by the authentication // scheme. Only the host of `scheme_host_port` is examined. diff --git a/chromium/net/http/http_auth_filter_unittest.cc b/chromium/net/http/http_auth_filter_unittest.cc index 5ac316358d0..dae854d45c9 100644 --- a/chromium/net/http/http_auth_filter_unittest.cc +++ b/chromium/net/http/http_auth_filter_unittest.cc @@ -67,11 +67,11 @@ TEST(HttpAuthFilterTest, EmptyFilter) { TEST(HttpAuthFilterTest, NonEmptyFilter) { // Create an non-empty filter std::string server_allowlist_filter_string; - for (size_t i = 0; i < std::size(server_allowlist_array); ++i) { + for (const auto* server : server_allowlist_array) { if (!server_allowlist_filter_string.empty()) server_allowlist_filter_string += ","; server_allowlist_filter_string += "*"; - server_allowlist_filter_string += server_allowlist_array[i]; + server_allowlist_filter_string += server; } HttpAuthFilterAllowlist filter(server_allowlist_filter_string); for (const auto& test_case : kTestCases) { diff --git a/chromium/net/http/http_auth_gssapi_posix.cc b/chromium/net/http/http_auth_gssapi_posix.cc index e4c25d2b923..e3ab2d76ce6 100644 --- a/chromium/net/http/http_auth_gssapi_posix.cc +++ b/chromium/net/http/http_auth_gssapi_posix.cc @@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "base/format_macros.h" #include "base/logging.h" +#include "base/memory/raw_ptr.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -79,7 +80,7 @@ class ScopedBuffer { private: gss_buffer_t buffer_; - GSSAPILibrary* gssapi_lib_; + raw_ptr<GSSAPILibrary> gssapi_lib_; }; // ScopedName releases a gss_name_t when it goes out of scope. @@ -109,7 +110,7 @@ class ScopedName { private: gss_name_t name_; - GSSAPILibrary* gssapi_lib_; + raw_ptr<GSSAPILibrary> gssapi_lib_; }; bool OidEquals(const gss_OID left, const gss_OID right) { @@ -118,12 +119,12 @@ bool OidEquals(const gss_OID left, const gss_OID right) { return 0 == memcmp(left->elements, right->elements, right->length); } -base::Value GetGssStatusCodeValue(GSSAPILibrary* gssapi_lib, - OM_uint32 status, - OM_uint32 status_code_type) { - base::Value rv{base::Value::Type::DICTIONARY}; +base::Value::Dict GetGssStatusCodeValue(GSSAPILibrary* gssapi_lib, + OM_uint32 status, + OM_uint32 status_code_type) { + base::Value::Dict rv; - rv.SetIntKey("status", status); + rv.Set("status", static_cast<int>(status)); // Message lookups aren't performed if there's no library or if the status // indicates success. @@ -148,7 +149,7 @@ base::Value GetGssStatusCodeValue(GSSAPILibrary* gssapi_lib, // |kMaxMsgLength|. There's no real documented limit to work with here. constexpr size_t kMaxMsgLength = 4096; - base::Value messages{base::Value::Type::LIST}; + base::Value::List messages; do { gss_buffer_desc_struct message_buffer = GSS_C_EMPTY_BUFFER; ScopedBuffer message_buffer_releaser(&message_buffer, gssapi_lib); @@ -174,41 +175,40 @@ base::Value GetGssStatusCodeValue(GSSAPILibrary* gssapi_lib, messages.Append(message_string); } while (message_context != 0 && ++iterations < kMaxDisplayIterations); - if (messages.GetListDeprecated().size() > 0) - rv.SetKey("message", std::move(messages)); + if (!messages.empty()) + rv.Set("message", std::move(messages)); return rv; } -base::Value GetGssStatusValue(GSSAPILibrary* gssapi_lib, - base::StringPiece method, - OM_uint32 major_status, - OM_uint32 minor_status) { - base::Value params{base::Value::Type::DICTIONARY}; - params.SetStringKey("function", method); - params.SetKey("major_status", GetGssStatusCodeValue(gssapi_lib, major_status, - GSS_C_GSS_CODE)); - params.SetKey("minor_status", GetGssStatusCodeValue(gssapi_lib, minor_status, - GSS_C_MECH_CODE)); +base::Value::Dict GetGssStatusValue(GSSAPILibrary* gssapi_lib, + base::StringPiece method, + OM_uint32 major_status, + OM_uint32 minor_status) { + base::Value::Dict params; + params.Set("function", method); + params.Set("major_status", + GetGssStatusCodeValue(gssapi_lib, major_status, GSS_C_GSS_CODE)); + params.Set("minor_status", + GetGssStatusCodeValue(gssapi_lib, minor_status, GSS_C_MECH_CODE)); return params; } -base::Value OidToValue(gss_OID oid) { - base::Value params(base::Value::Type::DICTIONARY); +base::Value::Dict OidToValue(gss_OID oid) { + base::Value::Dict params; if (!oid || oid->length == 0) { - params.SetStringKey("oid", "<Empty OID>"); + params.Set("oid", "<Empty OID>"); return params; } - params.SetIntKey("length", oid->length); + params.Set("length", static_cast<int>(oid->length)); if (!oid->elements) return params; // Cap OID content at arbitrary limit 1k. constexpr OM_uint32 kMaxOidDataSize = 1024; - params.SetKey( - "bytes", - NetLogBinaryValue(oid->elements, std::min(kMaxOidDataSize, oid->length))); + params.Set("bytes", NetLogBinaryValue(oid->elements, std::min(kMaxOidDataSize, + oid->length))); // Based on RFC 2744 Appendix A. Hardcoding the OIDs in the list below to // avoid having a static dependency on the library. @@ -232,52 +232,51 @@ base::Value OidToValue(gss_OID oid) { for (auto& well_known_oid : kWellKnownOIDs) { if (OidEquals(oid, const_cast<const gss_OID>(&well_known_oid.oid_desc))) - params.SetStringKey("oid", well_known_oid.symbolic_name); + params.Set("oid", well_known_oid.symbolic_name); } return params; } -base::Value GetDisplayNameValue(GSSAPILibrary* gssapi_lib, - const gss_name_t gss_name) { +base::Value::Dict GetDisplayNameValue(GSSAPILibrary* gssapi_lib, + const gss_name_t gss_name) { OM_uint32 major_status = 0; OM_uint32 minor_status = 0; gss_buffer_desc_struct name = GSS_C_EMPTY_BUFFER; gss_OID name_type = GSS_C_NO_OID; - base::Value rv{base::Value::Type::DICTIONARY}; + base::Value::Dict rv; major_status = gssapi_lib->display_name(&minor_status, gss_name, &name, &name_type); ScopedBuffer scoped_output_name(&name, gssapi_lib); if (major_status != GSS_S_COMPLETE) { - rv.SetKey("error", GetGssStatusValue(gssapi_lib, "gss_display_name", - major_status, minor_status)); + rv.Set("error", GetGssStatusValue(gssapi_lib, "gss_display_name", + major_status, minor_status)); return rv; } auto name_string = base::StringPiece(reinterpret_cast<const char*>(name.value), name.length); - rv.SetKey("name", base::IsStringUTF8(name_string) - ? NetLogStringValue(name_string) - : NetLogBinaryValue(name.value, name.length)); - rv.SetKey("type", OidToValue(name_type)); + rv.Set("name", base::IsStringUTF8(name_string) + ? NetLogStringValue(name_string) + : NetLogBinaryValue(name.value, name.length)); + rv.Set("type", OidToValue(name_type)); return rv; } -base::Value ContextFlagsToValue(OM_uint32 flags) { - base::Value rv{base::Value::Type::DICTIONARY}; - rv.SetStringKey("value", base::StringPrintf("0x%08x", flags)); - rv.SetBoolKey("delegated", (flags & GSS_C_DELEG_FLAG) == GSS_C_DELEG_FLAG); - rv.SetBoolKey("mutual", (flags & GSS_C_MUTUAL_FLAG) == GSS_C_MUTUAL_FLAG); +base::Value::Dict ContextFlagsToValue(OM_uint32 flags) { + base::Value::Dict rv; + rv.Set("value", base::StringPrintf("0x%08x", flags)); + rv.Set("delegated", (flags & GSS_C_DELEG_FLAG) == GSS_C_DELEG_FLAG); + rv.Set("mutual", (flags & GSS_C_MUTUAL_FLAG) == GSS_C_MUTUAL_FLAG); return rv; } base::Value GetContextStateAsValue(GSSAPILibrary* gssapi_lib, const gss_ctx_id_t context_handle) { - base::Value rv{base::Value::Type::DICTIONARY}; + base::Value::Dict rv; if (context_handle == GSS_C_NO_CONTEXT) { - rv.SetKey("error", - GetGssStatusValue(nullptr, "<none>", GSS_S_NO_CONTEXT, 0)); - return rv; + rv.Set("error", GetGssStatusValue(nullptr, "<none>", GSS_S_NO_CONTEXT, 0)); + return base::Value(std::move(rv)); } OM_uint32 major_status = 0; @@ -299,22 +298,22 @@ base::Value GetContextStateAsValue(GSSAPILibrary* gssapi_lib, &locally_initiated, &open); if (major_status != GSS_S_COMPLETE) { - rv.SetKey("error", GetGssStatusValue(gssapi_lib, "gss_inquire_context", - major_status, minor_status)); - return rv; + rv.Set("error", GetGssStatusValue(gssapi_lib, "gss_inquire_context", + major_status, minor_status)); + return base::Value(std::move(rv)); } ScopedName scoped_src_name(src_name, gssapi_lib); ScopedName scoped_targ_name(targ_name, gssapi_lib); - rv.SetKey("source", GetDisplayNameValue(gssapi_lib, src_name)); - rv.SetKey("target", GetDisplayNameValue(gssapi_lib, targ_name)); + rv.Set("source", GetDisplayNameValue(gssapi_lib, src_name)); + rv.Set("target", GetDisplayNameValue(gssapi_lib, targ_name)); // lifetime_rec is a uint32, while base::Value only takes ints. On 32 bit // platforms uint32 doesn't fit on an int. - rv.SetStringKey("lifetime", base::NumberToString(lifetime_rec)); - rv.SetKey("mechanism", OidToValue(mech_type)); - rv.SetKey("flags", ContextFlagsToValue(ctx_flags)); - rv.SetBoolKey("open", !!open); - return rv; + rv.Set("lifetime", base::NumberToString(lifetime_rec)); + rv.Set("mechanism", OidToValue(mech_type)); + rv.Set("flags", ContextFlagsToValue(ctx_flags)); + rv.Set("open", !!open); + return base::Value(std::move(rv)); } namespace { @@ -322,11 +321,11 @@ namespace { // Return a NetLog value for the result of loading a library. base::Value LibraryLoadResultParams(base::StringPiece library_name, base::StringPiece load_result) { - base::Value params{base::Value::Type::DICTIONARY}; - params.SetStringKey("library_name", library_name); + base::Value::Dict params; + params.Set("library_name", library_name); if (!load_result.empty()) - params.SetStringKey("load_result", load_result); - return params; + params.Set("load_result", load_result); + return base::Value(std::move(params)); } } // namespace @@ -424,10 +423,10 @@ namespace { base::Value BindFailureParams(base::StringPiece library_name, base::StringPiece method) { - base::Value params{base::Value::Type::DICTIONARY}; - params.SetStringKey("library_name", library_name); - params.SetStringKey("method", method); - return params; + base::Value::Dict params; + params.Set("library_name", library_name); + params.Set("method", method); + return base::Value(std::move(params)); } void* BindUntypedMethod(base::NativeLibrary lib, @@ -805,25 +804,25 @@ base::Value ImportNameErrorParams(GSSAPILibrary* library, base::StringPiece spn, OM_uint32 major_status, OM_uint32 minor_status) { - base::Value params{base::Value::Type::DICTIONARY}; - params.SetStringKey("spn", spn); + base::Value::Dict params; + params.Set("spn", spn); if (major_status != GSS_S_COMPLETE) - params.SetKey("status", GetGssStatusValue(library, "import_name", - major_status, minor_status)); - return params; + params.Set("status", GetGssStatusValue(library, "import_name", major_status, + minor_status)); + return base::Value(std::move(params)); } base::Value InitSecContextErrorParams(GSSAPILibrary* library, gss_ctx_id_t context, OM_uint32 major_status, OM_uint32 minor_status) { - base::Value params{base::Value::Type::DICTIONARY}; + base::Value::Dict params; if (major_status != GSS_S_COMPLETE) - params.SetKey("status", GetGssStatusValue(library, "gss_init_sec_context", - major_status, minor_status)); + params.Set("status", GetGssStatusValue(library, "gss_init_sec_context", + major_status, minor_status)); if (context != GSS_C_NO_CONTEXT) - params.SetKey("context", GetContextStateAsValue(library, context)); - return params; + params.Set("context", GetContextStateAsValue(library, context)); + return base::Value(std::move(params)); } } // anonymous namespace diff --git a/chromium/net/http/http_auth_gssapi_posix.h b/chromium/net/http/http_auth_gssapi_posix.h index 5c0580a95ec..3acd8bcbffa 100644 --- a/chromium/net/http/http_auth_gssapi_posix.h +++ b/chromium/net/http/http_auth_gssapi_posix.h @@ -8,6 +8,7 @@ #include <string> #include "base/gtest_prod_util.h" +#include "base/memory/raw_ptr.h" #include "base/native_library.h" #include "base/strings/string_piece_forward.h" #include "base/values.h" @@ -38,7 +39,7 @@ NET_EXPORT_PRIVATE extern gss_OID CHROME_GSS_SPNEGO_MECH_OID_DESC; // that implementation. class NET_EXPORT_PRIVATE GSSAPILibrary { public: - virtual ~GSSAPILibrary() {} + virtual ~GSSAPILibrary() = default; // Initializes the library, including any necessary dynamic libraries. // This is done separately from construction (which happens at startup time) @@ -214,7 +215,7 @@ class ScopedSecurityContext { private: gss_ctx_id_t security_context_ = GSS_C_NO_CONTEXT; - GSSAPILibrary* gssapi_lib_; + raw_ptr<GSSAPILibrary> gssapi_lib_; }; @@ -247,7 +248,7 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpAuthMechanism { const NetLogWithSource& net_log); gss_OID gss_oid_; - GSSAPILibrary* library_; + raw_ptr<GSSAPILibrary> library_; std::string decoded_server_auth_token_; ScopedSecurityContext scoped_sec_context_; HttpAuth::DelegationType delegation_type_ = HttpAuth::DelegationType::kNone; @@ -255,8 +256,8 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpAuthMechanism { // Diagnostics -// GetGssStatusCodeValue constructs a base::Value containing a status code and a -// message. +// GetGssStatusCodeValue constructs a base::Value::Dict containing a status code +// and a message. // // { // "status" : <status value as a number>, @@ -273,12 +274,12 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpAuthMechanism { // identified to look up messages if |status_code_type| is |GSS_C_MECH_CODE|. // Since no mechanism OIDs are passed in, mechanism specific status codes will // likely not have messages. -NET_EXPORT_PRIVATE base::Value GetGssStatusCodeValue( +NET_EXPORT_PRIVATE base::Value::Dict GetGssStatusCodeValue( GSSAPILibrary* gssapi_lib, OM_uint32 status, OM_uint32 status_code_type); -// Given major and minor GSSAPI status codes, returns a base::Value +// Given major and minor GSSAPI status codes, returns a base::Value::Dict // encapsulating the codes as well as their meanings as expanded via // gss_display_status(). // @@ -303,21 +304,22 @@ NET_EXPORT_PRIVATE base::Value GetGssStatusCodeValue( // returned value will be missing the "message" fields. The same is true if the // message lookup failed for some reason, or if the lookups succeeded but // yielded an empty message. -NET_EXPORT_PRIVATE base::Value GetGssStatusValue(GSSAPILibrary* gssapi_lib, - base::StringPiece method, - OM_uint32 major_status, - OM_uint32 minor_status); +NET_EXPORT_PRIVATE base::Value::Dict GetGssStatusValue( + GSSAPILibrary* gssapi_lib, + base::StringPiece method, + OM_uint32 major_status, + OM_uint32 minor_status); -// OidToValue returns a base::Value representing an OID. The structure of the -// value is: +// OidToValue returns a base::Value::Dict representing an OID. The structure of +// the value is: // { // "oid": <symbolic name of OID if it is known> // "length": <length in bytes of serialized OID>, // "bytes": <hexdump of up to 1024 bytes of serialized OID> // } -NET_EXPORT_PRIVATE base::Value OidToValue(const gss_OID oid); +NET_EXPORT_PRIVATE base::Value::Dict OidToValue(const gss_OID oid); -// GetDisplayNameValue returns a base::Value representing a gss_name_t. It +// GetDisplayNameValue returns a base::Value::Dict representing a gss_name_t. It // invokes |gss_display_name()| via |gssapi_lib| to determine the display name // associated with |gss_name|. // @@ -335,8 +337,9 @@ NET_EXPORT_PRIVATE base::Value OidToValue(const gss_OID oid); // // Note that |gss_name_t| is platform dependent. If |gss_display_name| fails, // there's no good value to display in its stead. -NET_EXPORT_PRIVATE base::Value GetDisplayNameValue(GSSAPILibrary* gssapi_lib, - const gss_name_t gss_name); +NET_EXPORT_PRIVATE base::Value::Dict GetDisplayNameValue( + GSSAPILibrary* gssapi_lib, + const gss_name_t gss_name); // GetContextStateAsValue returns a base::Value that describes the state of a // GSSAPI context. The structure of the value is: diff --git a/chromium/net/http/http_auth_gssapi_posix_unittest.cc b/chromium/net/http/http_auth_gssapi_posix_unittest.cc index 92a9cd7945c..31076e26490 100644 --- a/chromium/net/http/http_auth_gssapi_posix_unittest.cc +++ b/chromium/net/http/http_auth_gssapi_posix_unittest.cc @@ -92,7 +92,7 @@ TEST(HttpAuthGSSAPIPOSIXTest, GSSAPIStartup) { // TODO(ahendrickson): Manipulate the libraries and paths to test each of the // libraries we expect, and also whether or not they have the interface // functions we want. - std::unique_ptr<GSSAPILibrary> gssapi(new GSSAPISharedLibrary(std::string())); + auto gssapi = std::make_unique<GSSAPISharedLibrary>(std::string()); DCHECK(gssapi.get()); EXPECT_TRUE( gssapi.get()->Init(NetLogWithSource::Make(NetLogSourceType::NONE))); @@ -117,8 +117,8 @@ TEST(HttpAuthGSSAPIPOSIXTest, GSSAPIStartup) { TEST(HttpAuthGSSAPIPOSIXTest, CustomLibraryMissing) { RecordingNetLogObserver net_log_observer; - std::unique_ptr<GSSAPILibrary> gssapi( - new GSSAPISharedLibrary("/this/library/does/not/exist")); + auto gssapi = + std::make_unique<GSSAPISharedLibrary>("/this/library/does/not/exist"); EXPECT_FALSE( gssapi.get()->Init(NetLogWithSource::Make(NetLogSourceType::NONE))); @@ -182,8 +182,7 @@ TEST(HttpAuthGSSAPIPOSIXTest, CustomLibraryMethodsMissing) { } TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) { - std::unique_ptr<test::MockGSSAPILibrary> mock_library( - new test::MockGSSAPILibrary); + auto mock_library = std::make_unique<test::MockGSSAPILibrary>(); DCHECK(mock_library.get()); mock_library->Init(NetLogWithSource()); const char kAuthResponse[] = "Mary had a little lamb"; @@ -220,13 +219,10 @@ TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) { kAuthResponse) // Output token }; - for (size_t i = 0; i < std::size(queries); ++i) { - mock_library->ExpectSecurityContext(queries[i].expected_package, - queries[i].response_code, - queries[i].minor_response_code, - queries[i].context_info, - queries[i].expected_input_token, - queries[i].output_token); + for (const auto& query : queries) { + mock_library->ExpectSecurityContext( + query.expected_package, query.response_code, query.minor_response_code, + query.context_info, query.expected_input_token, query.output_token); } OM_uint32 major_status = 0; @@ -243,7 +239,7 @@ TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) { gss_buffer_desc output_token = {0, nullptr}; OM_uint32 ret_flags = 0; OM_uint32 time_rec = 0; - for (size_t i = 0; i < std::size(queries); ++i) { + for (const auto& query : queries) { major_status = mock_library->init_sec_context(&minor_status, initiator_cred_handle, &context_handle, @@ -257,7 +253,7 @@ TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) { &output_token, &ret_flags, &time_rec); - EXPECT_EQ(queries[i].response_code, major_status); + EXPECT_EQ(query.response_code, major_status); CopyBuffer(&input_token, &output_token); ClearBuffer(&output_token); } diff --git a/chromium/net/http/http_auth_handler_basic.cc b/chromium/net/http/http_auth_handler_basic.cc index 1b187631747..4314d8b7faf 100644 --- a/chromium/net/http/http_auth_handler_basic.cc +++ b/chromium/net/http/http_auth_handler_basic.cc @@ -132,13 +132,13 @@ int HttpAuthHandlerBasic::Factory::CreateAuthHandler( } // TODO(cbentzel): Move towards model of parsing in the factory // method and only constructing when valid. - std::unique_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerBasic()); + auto tmp_handler = std::make_unique<HttpAuthHandlerBasic>(); if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, network_isolation_key, scheme_host_port, net_log)) { return ERR_INVALID_RESPONSE; } - handler->swap(tmp_handler); + *handler = std::move(tmp_handler); return OK; } diff --git a/chromium/net/http/http_auth_handler_basic.h b/chromium/net/http/http_auth_handler_basic.h index eb5688c7166..c0391b36998 100644 --- a/chromium/net/http/http_auth_handler_basic.h +++ b/chromium/net/http/http_auth_handler_basic.h @@ -35,6 +35,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerBasic : public HttpAuthHandler { std::unique_ptr<HttpAuthHandler>* handler) override; }; + ~HttpAuthHandlerBasic() override = default; + private: // HttpAuthHandler bool Init(HttpAuthChallengeTokenizer* challenge, @@ -47,9 +49,6 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerBasic : public HttpAuthHandler { HttpAuth::AuthorizationResult HandleAnotherChallengeImpl( HttpAuthChallengeTokenizer* challenge) override; - private: - ~HttpAuthHandlerBasic() override = default; - bool ParseChallenge(HttpAuthChallengeTokenizer* challenge); }; diff --git a/chromium/net/http/http_auth_handler_basic_unittest.cc b/chromium/net/http/http_auth_handler_basic_unittest.cc index e87b89b3ee1..136041b70e5 100644 --- a/chromium/net/http/http_auth_handler_basic_unittest.cc +++ b/chromium/net/http/http_auth_handler_basic_unittest.cc @@ -44,7 +44,7 @@ TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) { }; url::SchemeHostPort scheme_host_port(GURL("http://www.example.com")); HttpAuthHandlerBasic::Factory factory; - for (size_t i = 0; i < std::size(tests); ++i) { + for (const auto& test : tests) { std::string challenge = "Basic realm=\"Atlantis\""; SSLInfo null_ssl_info; auto host_resolver = std::make_unique<MockHostResolver>(); @@ -53,15 +53,15 @@ TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) { challenge, HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(), scheme_host_port, NetLogWithSource(), host_resolver.get(), &basic)); - AuthCredentials credentials(base::ASCIIToUTF16(tests[i].username), - base::ASCIIToUTF16(tests[i].password)); + AuthCredentials credentials(base::ASCIIToUTF16(test.username), + base::ASCIIToUTF16(test.password)); HttpRequestInfo request_info; std::string auth_token; TestCompletionCallback callback; int rv = basic->GenerateAuthToken(&credentials, &request_info, callback.callback(), &auth_token); EXPECT_THAT(rv, IsOk()); - EXPECT_STREQ(tests[i].expected_credentials, auth_token.c_str()); + EXPECT_STREQ(test.expected_credentials, auth_token.c_str()); } } @@ -110,11 +110,11 @@ TEST(HttpAuthHandlerBasicTest, HandleAnotherChallenge) { NetworkIsolationKey(), scheme_host_port, NetLogWithSource(), host_resolver.get(), &basic)); - for (size_t i = 0; i < std::size(tests); ++i) { - std::string challenge(tests[i].challenge); + for (const auto& test : tests) { + std::string challenge(test.challenge); HttpAuthChallengeTokenizer tok(challenge.begin(), challenge.end()); - EXPECT_EQ(tests[i].expected_rv, basic->HandleAnotherChallenge(&tok)); + EXPECT_EQ(test.expected_rv, basic->HandleAnotherChallenge(&tok)); } } @@ -203,17 +203,17 @@ TEST(HttpAuthHandlerBasicTest, InitFromChallenge) { }; HttpAuthHandlerBasic::Factory factory; url::SchemeHostPort scheme_host_port(GURL("http://www.example.com")); - for (size_t i = 0; i < std::size(tests); ++i) { - std::string challenge = tests[i].challenge; + for (const auto& test : tests) { + std::string challenge = test.challenge; SSLInfo null_ssl_info; auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> basic; int rv = factory.CreateAuthHandlerFromString( challenge, HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(), scheme_host_port, NetLogWithSource(), host_resolver.get(), &basic); - EXPECT_EQ(tests[i].expected_rv, rv); + EXPECT_EQ(test.expected_rv, rv); if (rv == OK) - EXPECT_EQ(tests[i].expected_realm, basic->realm()); + EXPECT_EQ(test.expected_realm, basic->realm()); } } diff --git a/chromium/net/http/http_auth_handler_digest.cc b/chromium/net/http/http_auth_handler_digest.cc index 0557b3dc6c5..63c58b6892f 100644 --- a/chromium/net/http/http_auth_handler_digest.cc +++ b/chromium/net/http/http_auth_handler_digest.cc @@ -8,6 +8,7 @@ #include "base/hash/md5.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/rand_util.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -78,14 +79,13 @@ std::string HttpAuthHandlerDigest::FixedNonceGenerator::GenerateNonce() const { } HttpAuthHandlerDigest::Factory::Factory() - : nonce_generator_(new DynamicNonceGenerator()) { -} + : nonce_generator_(std::make_unique<DynamicNonceGenerator>()) {} HttpAuthHandlerDigest::Factory::~Factory() = default; void HttpAuthHandlerDigest::Factory::set_nonce_generator( - const NonceGenerator* nonce_generator) { - nonce_generator_.reset(nonce_generator); + std::unique_ptr<const NonceGenerator> nonce_generator) { + nonce_generator_ = std::move(nonce_generator); } int HttpAuthHandlerDigest::Factory::CreateAuthHandler( @@ -101,14 +101,14 @@ int HttpAuthHandlerDigest::Factory::CreateAuthHandler( std::unique_ptr<HttpAuthHandler>* handler) { // TODO(cbentzel): Move towards model of parsing in the factory // method and only constructing when valid. - std::unique_ptr<HttpAuthHandler> tmp_handler( + auto tmp_handler = base::WrapUnique( new HttpAuthHandlerDigest(digest_nonce_count, nonce_generator_.get())); if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, network_isolation_key, scheme_host_port, net_log)) { return ERR_INVALID_RESPONSE; } - handler->swap(tmp_handler); + *handler = std::move(tmp_handler); return OK; } diff --git a/chromium/net/http/http_auth_handler_digest.h b/chromium/net/http/http_auth_handler_digest.h index a170f7a81e1..1d81a1f518d 100644 --- a/chromium/net/http/http_auth_handler_digest.h +++ b/chromium/net/http/http_auth_handler_digest.h @@ -74,7 +74,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerDigest : public HttpAuthHandler { ~Factory() override; // This factory owns the passed in |nonce_generator|. - void set_nonce_generator(const NonceGenerator* nonce_generator); + void set_nonce_generator( + std::unique_ptr<const NonceGenerator> nonce_generator); int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge, HttpAuth::Target target, @@ -91,6 +92,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerDigest : public HttpAuthHandler { std::unique_ptr<const NonceGenerator> nonce_generator_; }; + ~HttpAuthHandlerDigest() override; + private: // HttpAuthHandler bool Init(HttpAuthChallengeTokenizer* challenge, @@ -134,7 +137,6 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerDigest : public HttpAuthHandler { // the handler. The lifetime of the |nonce_generator| must exceed that of this // handler. HttpAuthHandlerDigest(int nonce_count, const NonceGenerator* nonce_generator); - ~HttpAuthHandlerDigest() override; // Parse the challenge, saving the results into this instance. // Returns true on success. diff --git a/chromium/net/http/http_auth_handler_digest_unittest.cc b/chromium/net/http/http_auth_handler_digest_unittest.cc index de6b127775f..cba4635bee3 100644 --- a/chromium/net/http/http_auth_handler_digest_unittest.cc +++ b/chromium/net/http/http_auth_handler_digest_unittest.cc @@ -55,11 +55,11 @@ bool RespondToChallenge(HttpAuth::Target target, EXPECT_FALSE(challenge.empty()); token->clear(); - std::unique_ptr<HttpAuthHandlerDigest::Factory> factory( - new HttpAuthHandlerDigest::Factory()); - HttpAuthHandlerDigest::NonceGenerator* nonce_generator = - new HttpAuthHandlerDigest::FixedNonceGenerator("client_nonce"); - factory->set_nonce_generator(nonce_generator); + auto factory = std::make_unique<HttpAuthHandlerDigest::Factory>(); + auto nonce_generator = + std::make_unique<HttpAuthHandlerDigest::FixedNonceGenerator>( + "client_nonce"); + factory->set_nonce_generator(std::move(nonce_generator)); auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; @@ -80,7 +80,7 @@ bool RespondToChallenge(HttpAuth::Target target, // completes synchronously. That's why this test can get away with a // TestCompletionCallback without an IO thread. TestCompletionCallback callback; - std::unique_ptr<HttpRequestInfo> request(new HttpRequestInfo()); + auto request = std::make_unique<HttpRequestInfo>(); request->url = GURL(request_url); AuthCredentials credentials(u"foo", u"bar"); int rv_generate = handler->GenerateAuthToken( @@ -362,17 +362,16 @@ TEST(HttpAuthHandlerDigestTest, ParseChallenge) { }; url::SchemeHostPort scheme_host_port(GURL("http://www.example.com")); - std::unique_ptr<HttpAuthHandlerDigest::Factory> factory( - new HttpAuthHandlerDigest::Factory()); - for (size_t i = 0; i < std::size(tests); ++i) { + auto factory = std::make_unique<HttpAuthHandlerDigest::Factory>(); + for (const auto& test : tests) { SSLInfo null_ssl_info; auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; int rv = factory->CreateAuthHandlerFromString( - tests[i].challenge, HttpAuth::AUTH_SERVER, null_ssl_info, + test.challenge, HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(), scheme_host_port, NetLogWithSource(), host_resolver.get(), &handler); - if (tests[i].parsed_success) { + if (test.parsed_success) { EXPECT_THAT(rv, IsOk()); } else { EXPECT_NE(OK, rv); @@ -382,13 +381,13 @@ TEST(HttpAuthHandlerDigestTest, ParseChallenge) { ASSERT_TRUE(handler.get() != nullptr); HttpAuthHandlerDigest* digest = static_cast<HttpAuthHandlerDigest*>(handler.get()); - EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str()); - EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str()); - EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str()); - EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str()); - EXPECT_EQ(tests[i].parsed_stale, digest->stale_); - EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_); - EXPECT_EQ(tests[i].parsed_qop, digest->qop_); + EXPECT_STREQ(test.parsed_realm, digest->realm_.c_str()); + EXPECT_STREQ(test.parsed_nonce, digest->nonce_.c_str()); + EXPECT_STREQ(test.parsed_domain, digest->domain_.c_str()); + EXPECT_STREQ(test.parsed_opaque, digest->opaque_.c_str()); + EXPECT_EQ(test.parsed_stale, digest->stale_); + EXPECT_EQ(test.parsed_algorithm, digest->algorithm_); + EXPECT_EQ(test.parsed_qop, digest->qop_); EXPECT_TRUE(handler->encrypts_identity()); EXPECT_FALSE(handler->is_connection_based()); EXPECT_TRUE(handler->NeedsIdentity()); @@ -528,14 +527,13 @@ TEST(HttpAuthHandlerDigestTest, AssembleCredentials) { } }; url::SchemeHostPort scheme_host_port(GURL("http://www.example.com")); - std::unique_ptr<HttpAuthHandlerDigest::Factory> factory( - new HttpAuthHandlerDigest::Factory()); - for (size_t i = 0; i < std::size(tests); ++i) { + auto factory = std::make_unique<HttpAuthHandlerDigest::Factory>(); + for (const auto& test : tests) { SSLInfo null_ssl_info; auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; int rv = factory->CreateAuthHandlerFromString( - tests[i].challenge, HttpAuth::AUTH_SERVER, null_ssl_info, + test.challenge, HttpAuth::AUTH_SERVER, null_ssl_info, NetworkIsolationKey(), scheme_host_port, NetLogWithSource(), host_resolver.get(), &handler); EXPECT_THAT(rv, IsOk()); @@ -543,22 +541,18 @@ TEST(HttpAuthHandlerDigestTest, AssembleCredentials) { HttpAuthHandlerDigest* digest = static_cast<HttpAuthHandlerDigest*>(handler.get()); - std::string creds = - digest->AssembleCredentials(tests[i].req_method, - tests[i].req_path, - AuthCredentials( - base::ASCIIToUTF16(tests[i].username), - base::ASCIIToUTF16(tests[i].password)), - tests[i].cnonce, - tests[i].nonce_count); - - EXPECT_STREQ(tests[i].expected_creds, creds.c_str()); + std::string creds = digest->AssembleCredentials( + test.req_method, test.req_path, + AuthCredentials(base::ASCIIToUTF16(test.username), + base::ASCIIToUTF16(test.password)), + test.cnonce, test.nonce_count); + + EXPECT_STREQ(test.expected_creds, creds.c_str()); } } TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) { - std::unique_ptr<HttpAuthHandlerDigest::Factory> factory( - new HttpAuthHandlerDigest::Factory()); + auto factory = std::make_unique<HttpAuthHandlerDigest::Factory>(); auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; std::string default_challenge = diff --git a/chromium/net/http/http_auth_handler_factory.cc b/chromium/net/http/http_auth_handler_factory.cc index 05e0a4416aa..d3dce69123b 100644 --- a/chromium/net/http/http_auth_handler_factory.cc +++ b/chromium/net/http/http_auth_handler_factory.cc @@ -38,16 +38,16 @@ base::Value NetLogParamsForCreateAuth( const url::SchemeHostPort& scheme_host_port, const absl::optional<bool>& allows_default_credentials, net::NetLogCaptureMode capture_mode) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetKey("scheme", net::NetLogStringValue(scheme)); + base::Value::Dict dict; + dict.Set("scheme", net::NetLogStringValue(scheme)); if (net::NetLogCaptureIncludesSensitive(capture_mode)) - dict.SetKey("challenge", net::NetLogStringValue(challenge)); - dict.SetStringKey("origin", scheme_host_port.Serialize()); + dict.Set("challenge", net::NetLogStringValue(challenge)); + dict.Set("origin", scheme_host_port.Serialize()); if (allows_default_credentials) - dict.SetBoolKey("allows_default_credentials", *allows_default_credentials); + dict.Set("allows_default_credentials", *allows_default_credentials); if (net_error < 0) - dict.SetIntKey("net_error", net_error); - return dict; + dict.Set("net_error", net_error); + return base::Value(std::move(dict)); } } // namespace @@ -102,11 +102,11 @@ void HttpAuthHandlerRegistryFactory::SetHttpAuthPreferences( void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory( const std::string& scheme, - HttpAuthHandlerFactory* factory) { + std::unique_ptr<HttpAuthHandlerFactory> factory) { std::string lower_scheme = base::ToLowerASCII(scheme); if (factory) { factory->set_http_auth_preferences(http_auth_preferences()); - factory_map_[lower_scheme] = base::WrapUnique(factory); + factory_map_[lower_scheme] = std::move(factory); } else { factory_map_.erase(lower_scheme); } @@ -150,26 +150,26 @@ HttpAuthHandlerRegistryFactory::Create( HttpAuthMechanismFactory negotiate_auth_system_factory #endif ) { - std::unique_ptr<HttpAuthHandlerRegistryFactory> registry_factory( - new HttpAuthHandlerRegistryFactory(prefs)); + auto registry_factory = + std::make_unique<HttpAuthHandlerRegistryFactory>(prefs); - registry_factory->RegisterSchemeFactory(kBasicAuthScheme, - new HttpAuthHandlerBasic::Factory()); + registry_factory->RegisterSchemeFactory( + kBasicAuthScheme, std::make_unique<HttpAuthHandlerBasic::Factory>()); - registry_factory->RegisterSchemeFactory(kDigestAuthScheme, - new HttpAuthHandlerDigest::Factory()); + registry_factory->RegisterSchemeFactory( + kDigestAuthScheme, std::make_unique<HttpAuthHandlerDigest::Factory>()); - HttpAuthHandlerNTLM::Factory* ntlm_factory = - new HttpAuthHandlerNTLM::Factory(); + auto ntlm_factory = std::make_unique<HttpAuthHandlerNTLM::Factory>(); #if BUILDFLAG(IS_WIN) ntlm_factory->set_sspi_library( std::make_unique<SSPILibraryDefault>(NTLMSP_NAME)); #endif // BUILDFLAG(IS_WIN) - registry_factory->RegisterSchemeFactory(kNtlmAuthScheme, ntlm_factory); + registry_factory->RegisterSchemeFactory(kNtlmAuthScheme, + std::move(ntlm_factory)); #if BUILDFLAG(USE_KERBEROS) - HttpAuthHandlerNegotiate::Factory* negotiate_factory = - new HttpAuthHandlerNegotiate::Factory(negotiate_auth_system_factory); + auto negotiate_factory = std::make_unique<HttpAuthHandlerNegotiate::Factory>( + negotiate_auth_system_factory); #if BUILDFLAG(IS_WIN) negotiate_factory->set_library( std::make_unique<SSPILibraryDefault>(NEGOSSP_NAME)); @@ -178,7 +178,7 @@ HttpAuthHandlerRegistryFactory::Create( std::make_unique<GSSAPISharedLibrary>(gssapi_library_name)); #endif registry_factory->RegisterSchemeFactory(kNegotiateAuthScheme, - negotiate_factory); + std::move(negotiate_factory)); #endif // BUILDFLAG(USE_KERBEROS) if (prefs) { diff --git a/chromium/net/http/http_auth_handler_factory.h b/chromium/net/http/http_auth_handler_factory.h index d9b9138cc91..4f1b3b466e5 100644 --- a/chromium/net/http/http_auth_handler_factory.h +++ b/chromium/net/http/http_auth_handler_factory.h @@ -50,7 +50,7 @@ class NET_EXPORT HttpAuthHandlerFactory { HttpAuthHandlerFactory(const HttpAuthHandlerFactory&) = delete; HttpAuthHandlerFactory& operator=(const HttpAuthHandlerFactory&) = delete; - virtual ~HttpAuthHandlerFactory() {} + virtual ~HttpAuthHandlerFactory() = default; // Sets the source of the HTTP authentication preferences. // HttpAuthHandlerFactory doesn't own the preferences, and the @@ -194,7 +194,7 @@ class NET_EXPORT HttpAuthHandlerRegistryFactory // for |scheme|. If a factory object used to exist for |scheme|, it will be // deleted. void RegisterSchemeFactory(const std::string& scheme, - HttpAuthHandlerFactory* factory); + std::unique_ptr<HttpAuthHandlerFactory> factory); // Creates an HttpAuthHandlerRegistryFactory. // diff --git a/chromium/net/http/http_auth_handler_factory_unittest.cc b/chromium/net/http/http_auth_handler_factory_unittest.cc index ac993f0fe75..49eba343b6e 100644 --- a/chromium/net/http/http_auth_handler_factory_unittest.cc +++ b/chromium/net/http/http_auth_handler_factory_unittest.cc @@ -67,16 +67,16 @@ TEST(HttpAuthHandlerFactoryTest, RegistryFactory) { /*http_auth_preferences=*/nullptr); url::SchemeHostPort scheme_host_port(GURL("https://www.google.com")); const int kBasicReturnCode = -1; - MockHttpAuthHandlerFactory* mock_factory_basic = - new MockHttpAuthHandlerFactory(kBasicReturnCode); + auto mock_factory_basic = + std::make_unique<MockHttpAuthHandlerFactory>(kBasicReturnCode); const int kDigestReturnCode = -2; - MockHttpAuthHandlerFactory* mock_factory_digest = - new MockHttpAuthHandlerFactory(kDigestReturnCode); + auto mock_factory_digest = + std::make_unique<MockHttpAuthHandlerFactory>(kDigestReturnCode); const int kDigestReturnCodeReplace = -3; - MockHttpAuthHandlerFactory* mock_factory_digest_replace = - new MockHttpAuthHandlerFactory(kDigestReturnCodeReplace); + auto mock_factory_digest_replace = + std::make_unique<MockHttpAuthHandlerFactory>(kDigestReturnCodeReplace); auto host_resovler = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandler> handler; @@ -89,7 +89,8 @@ TEST(HttpAuthHandlerFactoryTest, RegistryFactory) { scheme_host_port, NetLogWithSource(), host_resovler.get(), &handler)); // Test what happens with a single scheme. - registry_factory.RegisterSchemeFactory("Basic", mock_factory_basic); + registry_factory.RegisterSchemeFactory("Basic", + std::move(mock_factory_basic)); EXPECT_EQ( kBasicReturnCode, registry_factory.CreateAuthHandlerFromString( @@ -102,7 +103,8 @@ TEST(HttpAuthHandlerFactoryTest, RegistryFactory) { scheme_host_port, NetLogWithSource(), host_resovler.get(), &handler)); // Test multiple schemes - registry_factory.RegisterSchemeFactory("Digest", mock_factory_digest); + registry_factory.RegisterSchemeFactory("Digest", + std::move(mock_factory_digest)); EXPECT_EQ( kBasicReturnCode, registry_factory.CreateAuthHandlerFromString( @@ -122,7 +124,8 @@ TEST(HttpAuthHandlerFactoryTest, RegistryFactory) { scheme_host_port, NetLogWithSource(), host_resovler.get(), &handler)); // Test replacement of existing auth scheme - registry_factory.RegisterSchemeFactory("Digest", mock_factory_digest_replace); + registry_factory.RegisterSchemeFactory( + "Digest", std::move(mock_factory_digest_replace)); EXPECT_EQ( kBasicReturnCode, registry_factory.CreateAuthHandlerFromString( @@ -136,7 +139,7 @@ TEST(HttpAuthHandlerFactoryTest, RegistryFactory) { } TEST(HttpAuthHandlerFactoryTest, DefaultFactory) { - std::unique_ptr<HostResolver> host_resolver(new MockHostResolver()); + auto host_resolver = std::make_unique<MockHostResolver>(); MockAllowHttpAuthPreferences http_auth_preferences; std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory( HttpAuthHandlerFactory::CreateDefault()); @@ -220,7 +223,7 @@ TEST(HttpAuthHandlerFactoryTest, DefaultFactory) { } TEST(HttpAuthHandlerFactoryTest, HttpAuthUrlFilter) { - std::unique_ptr<HostResolver> host_resolver(new MockHostResolver()); + auto host_resolver = std::make_unique<MockHostResolver>(); MockAllowHttpAuthPreferences http_auth_preferences; // Set the Preference that blocks Basic Auth over HTTP on all of the @@ -273,7 +276,7 @@ TEST(HttpAuthHandlerFactoryTest, HttpAuthUrlFilter) { } TEST(HttpAuthHandlerFactoryTest, BasicFactoryRespectsHTTPEnabledPref) { - std::unique_ptr<HostResolver> host_resolver(new MockHostResolver()); + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory( HttpAuthHandlerFactory::CreateDefault()); @@ -330,7 +333,7 @@ TEST(HttpAuthHandlerFactoryTest, BasicFactoryRespectsHTTPEnabledPref) { } TEST(HttpAuthHandlerFactoryTest, LogCreateAuthHandlerResults) { - std::unique_ptr<HostResolver> host_resolver(new MockHostResolver()); + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory( HttpAuthHandlerFactory::CreateDefault()); url::SchemeHostPort scheme_host_port(GURL("http://www.example.com")); @@ -378,10 +381,12 @@ TEST(HttpAuthHandlerFactoryTest, LogCreateAuthHandlerResults) { auto entries = net_log_observer.GetEntriesWithType( NetLogEventType::AUTH_HANDLER_CREATE_RESULT); ASSERT_EQ(1u, entries.size()); - const std::string* scheme = entries[0].params.FindStringKey("scheme"); + const std::string* scheme = + entries[0].params.GetDict().FindString("scheme"); ASSERT_NE(nullptr, scheme); EXPECT_STRCASEEQ(test_case.expected_scheme, scheme->data()); - absl::optional<int> net_error = entries[0].params.FindIntKey("net_error"); + absl::optional<int> net_error = + entries[0].params.GetDict().FindInt("net_error"); if (test_case.expected_net_error) { ASSERT_TRUE(net_error.has_value()); EXPECT_EQ(test_case.expected_net_error, net_error.value()); @@ -391,7 +396,7 @@ TEST(HttpAuthHandlerFactoryTest, LogCreateAuthHandlerResults) { // The challenge should be logged only when sensitive logging is enabled. const std::string* challenge = - entries[0].params.FindStringKey("challenge"); + entries[0].params.GetDict().FindString("challenge"); if (capture_mode == NetLogCaptureMode::kDefault) { ASSERT_EQ(nullptr, challenge); } else { diff --git a/chromium/net/http/http_auth_handler_mock.cc b/chromium/net/http/http_auth_handler_mock.cc index 9e76f02a001..4bffe8b912a 100644 --- a/chromium/net/http/http_auth_handler_mock.cc +++ b/chromium/net/http/http_auth_handler_mock.cc @@ -146,8 +146,9 @@ HttpAuthHandlerMock::Factory::Factory() { HttpAuthHandlerMock::Factory::~Factory() = default; void HttpAuthHandlerMock::Factory::AddMockHandler( - HttpAuthHandler* handler, HttpAuth::Target target) { - handlers_[target].push_back(base::WrapUnique(handler)); + std::unique_ptr<HttpAuthHandler> handler, + HttpAuth::Target target) { + handlers_[target].push_back(std::move(handler)); } int HttpAuthHandlerMock::Factory::CreateAuthHandler( diff --git a/chromium/net/http/http_auth_handler_mock.h b/chromium/net/http/http_auth_handler_mock.h index ef2be2f1686..70f1738fe61 100644 --- a/chromium/net/http/http_auth_handler_mock.h +++ b/chromium/net/http/http_auth_handler_mock.h @@ -42,7 +42,8 @@ class HttpAuthHandlerMock : public HttpAuthHandler { Factory(); ~Factory() override; - void AddMockHandler(HttpAuthHandler* handler, HttpAuth::Target target); + void AddMockHandler(std::unique_ptr<HttpAuthHandler> handler, + HttpAuth::Target target); void set_do_init_from_challenge(bool do_init_from_challenge) { do_init_from_challenge_ = do_init_from_challenge; diff --git a/chromium/net/http/http_auth_handler_negotiate.cc b/chromium/net/http/http_auth_handler_negotiate.cc index bab8b1b551a..1e83a068a2b 100644 --- a/chromium/net/http/http_auth_handler_negotiate.cc +++ b/chromium/net/http/http_auth_handler_negotiate.cc @@ -40,13 +40,13 @@ namespace { base::Value NetLogParameterChannelBindings( const std::string& channel_binding_token, NetLogCaptureMode capture_mode) { - base::Value dict(base::Value::Type::DICTIONARY); + base::Value::Dict dict; if (!NetLogCaptureIncludesSocketBytes(capture_mode)) - return dict; + return base::Value(std::move(dict)); - dict.SetStringKey("token", base::HexEncode(channel_binding_token.data(), - channel_binding_token.size())); - return dict; + dict.Set("token", base::HexEncode(channel_binding_token.data(), + channel_binding_token.size())); + return base::Value(std::move(dict)); } // Uses |negotiate_auth_system_factory| to create the auth system, otherwise @@ -101,10 +101,11 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( return ERR_UNSUPPORTED_AUTH_SCHEME; // TODO(cbentzel): Move towards model of parsing in the factory // method and only constructing when valid. - std::unique_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( - CreateAuthSystem(auth_library_.get(), http_auth_preferences(), - negotiate_auth_system_factory_), - http_auth_preferences(), host_resolver)); + std::unique_ptr<HttpAuthHandler> tmp_handler( + std::make_unique<HttpAuthHandlerNegotiate>( + CreateAuthSystem(auth_library_.get(), http_auth_preferences(), + negotiate_auth_system_factory_), + http_auth_preferences(), host_resolver)); #elif BUILDFLAG(IS_ANDROID) if (is_unsupported_ || !http_auth_preferences() || http_auth_preferences()->AuthAndroidNegotiateAccountType().empty() || @@ -112,28 +113,31 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( return ERR_UNSUPPORTED_AUTH_SCHEME; // TODO(cbentzel): Move towards model of parsing in the factory // method and only constructing when valid. - std::unique_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( - CreateAuthSystem(http_auth_preferences(), negotiate_auth_system_factory_), - http_auth_preferences(), host_resolver)); + std::unique_ptr<HttpAuthHandler> tmp_handler( + std::make_unique<HttpAuthHandlerNegotiate>( + CreateAuthSystem(http_auth_preferences(), + negotiate_auth_system_factory_), + http_auth_preferences(), host_resolver)); #elif BUILDFLAG(IS_POSIX) if (is_unsupported_) return ERR_UNSUPPORTED_AUTH_SCHEME; -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Note: Don't set is_unsupported_ = true here. AllowGssapiLibraryLoad() // might change to true during a session. if (!http_auth_preferences()->AllowGssapiLibraryLoad()) return ERR_UNSUPPORTED_AUTH_SCHEME; -#endif +#endif // BUILDFLAG(IS_CHROMEOS) if (!auth_library_->Init(net_log)) { is_unsupported_ = true; return ERR_UNSUPPORTED_AUTH_SCHEME; } // TODO(ahendrickson): Move towards model of parsing in the factory // method and only constructing when valid. - std::unique_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( - CreateAuthSystem(auth_library_.get(), http_auth_preferences(), - negotiate_auth_system_factory_), - http_auth_preferences(), host_resolver)); + std::unique_ptr<HttpAuthHandler> tmp_handler( + std::make_unique<HttpAuthHandlerNegotiate>( + CreateAuthSystem(auth_library_.get(), http_auth_preferences(), + negotiate_auth_system_factory_), + http_auth_preferences(), host_resolver)); #endif if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, network_isolation_key, scheme_host_port, diff --git a/chromium/net/http/http_auth_handler_negotiate_unittest.cc b/chromium/net/http/http_auth_handler_negotiate_unittest.cc index 80b03874963..310b2180c1c 100644 --- a/chromium/net/http/http_auth_handler_negotiate_unittest.cc +++ b/chromium/net/http/http_auth_handler_negotiate_unittest.cc @@ -62,10 +62,12 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest, features::kSplitHostCacheByNetworkIsolationKey); network_isolation_key_ = NetworkIsolationKey::CreateTransient(); #if BUILDFLAG(IS_WIN) - auth_library_ = new MockAuthLibrary(const_cast<wchar_t*>(NEGOSSP_NAME)); + auto auth_library = + std::make_unique<MockAuthLibrary>(const_cast<wchar_t*>(NEGOSSP_NAME)); #else - auth_library_ = new MockAuthLibrary(); + auto auth_library = std::make_unique<MockAuthLibrary>(); #endif + auth_library_ = auth_library.get(); resolver_ = std::make_unique<MockCachingHostResolver>( /*cache_invalidation_num=*/0, /*default_result=*/MockHostResolverBase::RuleResolver:: @@ -78,11 +80,12 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest, HttpAuthMechanismFactory()); factory_->set_http_auth_preferences(http_auth_preferences_.get()); #if BUILDFLAG(IS_ANDROID) + auth_library_for_android_ = std::move(auth_library); http_auth_preferences_->set_auth_android_negotiate_account_type( "org.chromium.test.DummySpnegoAuthenticator"); MockAuthLibrary::EnsureTestAccountExists(); #else - factory_->set_library(base::WrapUnique(auth_library_.get())); + factory_->set_library(std::move(auth_library)); #endif // BUILDFLAG(IS_ANDROID) } @@ -178,13 +181,11 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest, kAuthResponse) // Output token }; - for (size_t i = 0; i < std::size(queries); ++i) { - mock_library->ExpectSecurityContext(queries[i].expected_package, - queries[i].response_code, - queries[i].minor_response_code, - queries[i].context_info, - queries[i].expected_input_token, - queries[i].output_token); + for (const auto& query : queries) { + mock_library->ExpectSecurityContext( + query.expected_package, query.response_code, + query.minor_response_code, query.context_info, + query.expected_input_token, query.output_token); } #endif // BUILDFLAG(IS_WIN) } @@ -266,6 +267,8 @@ class HttpAuthHandlerNegotiateTest : public PlatformTest, #if BUILDFLAG(IS_WIN) std::unique_ptr<SecPkgInfoW> security_package_; +#elif BUILDFLAG(IS_ANDROID) + std::unique_ptr<MockAuthLibrary> auth_library_for_android_; #endif // |auth_library_| is passed to |factory_|, which assumes ownership of it, but // can't be a scoped pointer to it since the tests need access when they set @@ -452,8 +455,8 @@ TEST_F(HttpAuthHandlerNegotiateTest, NoKerberosCredentials) { #if BUILDFLAG(USE_EXTERNAL_GSSAPI) TEST_F(HttpAuthHandlerNegotiateTest, MissingGSSAPI) { MockAllowHttpAuthPreferences http_auth_preferences; - std::unique_ptr<HttpAuthHandlerNegotiate::Factory> negotiate_factory( - new HttpAuthHandlerNegotiate::Factory(HttpAuthMechanismFactory())); + auto negotiate_factory = std::make_unique<HttpAuthHandlerNegotiate::Factory>( + HttpAuthMechanismFactory()); negotiate_factory->set_http_auth_preferences(&http_auth_preferences); negotiate_factory->set_library( std::make_unique<GSSAPISharedLibrary>("/this/library/does/not/exist")); @@ -468,8 +471,8 @@ TEST_F(HttpAuthHandlerNegotiateTest, MissingGSSAPI) { } #endif // BUILDFLAG(USE_EXTERNAL_GSSAPI) -// AllowGssapiLibraryLoad() is only supported on Chrome OS. -#if BUILDFLAG(IS_CHROMEOS_ASH) +// AllowGssapiLibraryLoad() is only supported on ChromeOS. +#if BUILDFLAG(IS_CHROMEOS) TEST_F(HttpAuthHandlerNegotiateTest, AllowGssapiLibraryLoad) { // Disabling allow_gssapi_library_load should prevent handler creation. SetupMocks(AuthLibrary()); @@ -485,7 +488,7 @@ TEST_F(HttpAuthHandlerNegotiateTest, AllowGssapiLibraryLoad) { EXPECT_EQ(OK, rv); EXPECT_TRUE(auth_handler); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(IS_CHROMEOS) #endif // BUILDFLAG(IS_POSIX) diff --git a/chromium/net/http/http_auth_handler_ntlm.h b/chromium/net/http/http_auth_handler_ntlm.h index ada68fb3b39..d10b4417af6 100644 --- a/chromium/net/http/http_auth_handler_ntlm.h +++ b/chromium/net/http/http_auth_handler_ntlm.h @@ -92,6 +92,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler { HttpAuthHandlerNTLM(const HttpAuthHandlerNTLM&) = delete; HttpAuthHandlerNTLM& operator=(const HttpAuthHandlerNTLM&) = delete; + ~HttpAuthHandlerNTLM() override; + // HttpAuthHandler bool NeedsIdentity() override; bool AllowsDefaultCredentials() override; @@ -109,8 +111,6 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler { HttpAuthChallengeTokenizer* challenge) override; private: - ~HttpAuthHandlerNTLM() override; - // Parse the challenge, saving the results into this instance. HttpAuth::AuthorizationResult ParseChallenge(HttpAuthChallengeTokenizer* tok); diff --git a/chromium/net/http/http_auth_handler_ntlm_portable.cc b/chromium/net/http/http_auth_handler_ntlm_portable.cc index 2063e5ea5ed..7381263fecf 100644 --- a/chromium/net/http/http_auth_handler_ntlm_portable.cc +++ b/chromium/net/http/http_auth_handler_ntlm_portable.cc @@ -29,14 +29,14 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler( // method and only constructing when valid. // NOTE: Default credentials are not supported for the portable implementation // of NTLM. - std::unique_ptr<HttpAuthHandler> tmp_handler( - new HttpAuthHandlerNTLM(http_auth_preferences())); + auto tmp_handler = + std::make_unique<HttpAuthHandlerNTLM>(http_auth_preferences()); if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, network_isolation_key, scheme_host_port, net_log)) { return ERR_INVALID_RESPONSE; } - handler->swap(tmp_handler); + *handler = std::move(tmp_handler); return OK; } diff --git a/chromium/net/http/http_auth_handler_ntlm_win.cc b/chromium/net/http/http_auth_handler_ntlm_win.cc index f54183ad558..2c0bc7bef49 100644 --- a/chromium/net/http/http_auth_handler_ntlm_win.cc +++ b/chromium/net/http/http_auth_handler_ntlm_win.cc @@ -33,13 +33,13 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler( return ERR_UNSUPPORTED_AUTH_SCHEME; // TODO(cbentzel): Move towards model of parsing in the factory // method and only constructing when valid. - std::unique_ptr<HttpAuthHandler> tmp_handler( - new HttpAuthHandlerNTLM(sspi_library_.get(), http_auth_preferences())); + auto tmp_handler = std::make_unique<HttpAuthHandlerNTLM>( + sspi_library_.get(), http_auth_preferences()); if (!tmp_handler->InitFromChallenge(challenge, target, ssl_info, network_isolation_key, scheme_host_port, net_log)) return ERR_INVALID_RESPONSE; - handler->swap(tmp_handler); + *handler = std::move(tmp_handler); return OK; } @@ -59,7 +59,7 @@ int HttpAuthHandlerNTLM::GenerateAuthTokenImpl( std::move(callback)); } -HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {} +HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() = default; // Require identity on first pass instead of second. bool HttpAuthHandlerNTLM::NeedsIdentity() { diff --git a/chromium/net/http/http_auth_preferences.cc b/chromium/net/http/http_auth_preferences.cc index 4fa3e69de0e..fac4cde5991 100644 --- a/chromium/net/http/http_auth_preferences.cc +++ b/chromium/net/http/http_auth_preferences.cc @@ -31,19 +31,19 @@ bool HttpAuthPreferences::NegotiateEnablePort() const { bool HttpAuthPreferences::NtlmV2Enabled() const { return ntlm_v2_enabled_; } -#endif +#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) #if BUILDFLAG(IS_ANDROID) std::string HttpAuthPreferences::AuthAndroidNegotiateAccountType() const { return auth_android_negotiate_account_type_; } -#endif +#endif // BUILDFLAG(IS_ANDROID) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) bool HttpAuthPreferences::AllowGssapiLibraryLoad() const { return allow_gssapi_library_load_; } -#endif +#endif // BUILDFLAG(IS_CHROMEOS) bool HttpAuthPreferences::CanUseDefaultCredentials( const url::SchemeHostPort& auth_scheme_host_port) const { diff --git a/chromium/net/http/http_auth_preferences.h b/chromium/net/http/http_auth_preferences.h index 894ffefe5ab..5f7d46c49d7 100644 --- a/chromium/net/http/http_auth_preferences.h +++ b/chromium/net/http/http_auth_preferences.h @@ -46,13 +46,13 @@ class NET_EXPORT HttpAuthPreferences { virtual bool NegotiateEnablePort() const; #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) virtual bool NtlmV2Enabled() const; -#endif +#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) #if BUILDFLAG(IS_ANDROID) virtual std::string AuthAndroidNegotiateAccountType() const; #endif -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) virtual bool AllowGssapiLibraryLoad() const; -#endif +#endif // BUILDFLAG(IS_CHROMEOS) virtual bool CanUseDefaultCredentials( const url::SchemeHostPort& auth_scheme_host_port) const; virtual HttpAuth::DelegationType GetDelegationType( @@ -84,13 +84,13 @@ class NET_EXPORT HttpAuthPreferences { void set_ntlm_v2_enabled(bool ntlm_v2_enabled) { ntlm_v2_enabled_ = ntlm_v2_enabled; } -#endif +#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) void set_allow_gssapi_library_load(bool allow_gssapi_library_load) { allow_gssapi_library_load_ = allow_gssapi_library_load; } -#endif +#endif // BUILDFLAG(IS_CHROMEOS) const absl::optional<std::set<std::string>>& allowed_schemes() const { return allowed_schemes_; @@ -119,7 +119,7 @@ class NET_EXPORT HttpAuthPreferences { const std::string& account_type) { auth_android_negotiate_account_type_ = account_type; } -#endif +#endif // BUILDFLAG(IS_ANDROID) private: bool delegate_by_kdc_policy_ = false; @@ -131,15 +131,15 @@ class NET_EXPORT HttpAuthPreferences { #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) bool ntlm_v2_enabled_ = true; -#endif +#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) #if BUILDFLAG(IS_ANDROID) std::string auth_android_negotiate_account_type_; -#endif +#endif // BUILDFLAG(IS_ANDROID) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) bool allow_gssapi_library_load_ = true; -#endif +#endif // BUILDFLAG(IS_CHROMEOS) absl::optional<std::set<std::string>> allowed_schemes_; std::unique_ptr<URLSecurityManager> security_manager_; diff --git a/chromium/net/http/http_auth_preferences_unittest.cc b/chromium/net/http/http_auth_preferences_unittest.cc index c349b729f51..e95f8888c7c 100644 --- a/chromium/net/http/http_auth_preferences_unittest.cc +++ b/chromium/net/http/http_auth_preferences_unittest.cc @@ -41,10 +41,10 @@ TEST(HttpAuthPreferencesTest, DisableNtlmV2) { http_auth_preferences.set_ntlm_v2_enabled(false); EXPECT_FALSE(http_auth_preferences.NtlmV2Enabled()); } -#endif +#endif // BUILDFLAG(IS_POSIX) #if BUILDFLAG(IS_ANDROID) -TEST(HttpAuthPreferencesTest, AuthAndroidhNegotiateAccountType) { +TEST(HttpAuthPreferencesTest, AuthAndroidNegotiateAccountType) { HttpAuthPreferences http_auth_preferences; EXPECT_EQ(std::string(), http_auth_preferences.AuthAndroidNegotiateAccountType()); @@ -52,16 +52,16 @@ TEST(HttpAuthPreferencesTest, AuthAndroidhNegotiateAccountType) { EXPECT_EQ(std::string("foo"), http_auth_preferences.AuthAndroidNegotiateAccountType()); } -#endif +#endif // BUILDFLAG(IS_ANDROID) -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) TEST(HttpAuthPreferencesTest, AllowGssapiLibraryLoad) { HttpAuthPreferences http_auth_preferences; EXPECT_TRUE(http_auth_preferences.AllowGssapiLibraryLoad()); http_auth_preferences.set_allow_gssapi_library_load(false); EXPECT_FALSE(http_auth_preferences.AllowGssapiLibraryLoad()); } -#endif +#endif // BUILDFLAG(IS_CHROMEOS) TEST(HttpAuthPreferencesTest, AuthServerAllowlist) { HttpAuthPreferences http_auth_preferences; diff --git a/chromium/net/http/http_auth_sspi_win.cc b/chromium/net/http/http_auth_sspi_win.cc index e55a34e1a46..02ce74d36c9 100644 --- a/chromium/net/http/http_auth_sspi_win.cc +++ b/chromium/net/http/http_auth_sspi_win.cc @@ -28,47 +28,45 @@ using DelegationType = HttpAuth::DelegationType; namespace { base::Value SecurityStatusToValue(Error mapped_error, SECURITY_STATUS status) { - base::Value params{base::Value::Type::DICTIONARY}; - params.SetIntKey("net_error", mapped_error); - params.SetIntKey("security_status", status); - return params; + base::Value::Dict params; + params.Set("net_error", mapped_error); + params.Set("security_status", static_cast<int>(status)); + return base::Value(std::move(params)); } base::Value AcquireCredentialsHandleParams(const std::u16string* domain, const std::u16string* user, Error result, SECURITY_STATUS status) { - base::Value params{base::Value::Type::DICTIONARY}; + base::Value::Dict params; if (domain && user) { - params.SetStringKey("domain", base::UTF16ToUTF8(*domain)); - params.SetStringKey("user", base::UTF16ToUTF8(*user)); + params.Set("domain", base::UTF16ToUTF8(*domain)); + params.Set("user", base::UTF16ToUTF8(*user)); } - params.SetKey("status", SecurityStatusToValue(result, status)); - return params; + params.Set("status", SecurityStatusToValue(result, status)); + return base::Value(std::move(params)); } base::Value ContextFlagsToValue(DWORD flags) { - base::Value params{base::Value::Type::DICTIONARY}; - params.SetStringKey("value", base::StringPrintf("0x%08lx", flags)); - params.SetBoolKey("delegated", - (flags & ISC_RET_DELEGATE) == ISC_RET_DELEGATE); - params.SetBoolKey("mutual", - (flags & ISC_RET_MUTUAL_AUTH) == ISC_RET_MUTUAL_AUTH); - return params; + base::Value::Dict params; + params.Set("value", base::StringPrintf("0x%08lx", flags)); + params.Set("delegated", (flags & ISC_RET_DELEGATE) == ISC_RET_DELEGATE); + params.Set("mutual", (flags & ISC_RET_MUTUAL_AUTH) == ISC_RET_MUTUAL_AUTH); + return base::Value(std::move(params)); } base::Value ContextAttributesToValue(SSPILibrary* library, PCtxtHandle handle, DWORD attributes) { - base::Value params{base::Value::Type::DICTIONARY}; + base::Value::Dict params; SecPkgContext_NativeNames native_names = {0}; auto qc_result = library->QueryContextAttributesEx( handle, SECPKG_ATTR_NATIVE_NAMES, &native_names, sizeof(native_names)); if (qc_result == SEC_E_OK && native_names.sClientName && native_names.sServerName) { - params.SetStringKey("source", base::as_u16cstr(native_names.sClientName)); - params.SetStringKey("target", base::as_u16cstr(native_names.sServerName)); + params.Set("source", base::as_u16cstr(native_names.sClientName)); + params.Set("target", base::as_u16cstr(native_names.sServerName)); } SecPkgContext_NegotiationInfo negotiation_info = {0}; @@ -77,22 +75,21 @@ base::Value ContextAttributesToValue(SSPILibrary* library, sizeof(negotiation_info)); if (qc_result == SEC_E_OK && negotiation_info.PackageInfo && negotiation_info.PackageInfo->Name) { - params.SetStringKey("mechanism", - base::as_u16cstr(negotiation_info.PackageInfo->Name)); - params.SetBoolKey("open", negotiation_info.NegotiationState != - SECPKG_NEGOTIATION_COMPLETE); + params.Set("mechanism", + base::as_u16cstr(negotiation_info.PackageInfo->Name)); + params.Set("open", negotiation_info.NegotiationState != + SECPKG_NEGOTIATION_COMPLETE); } SecPkgContext_Authority authority = {0}; qc_result = library->QueryContextAttributesEx(handle, SECPKG_ATTR_AUTHORITY, &authority, sizeof(authority)); if (qc_result == SEC_E_OK && authority.sAuthorityName) { - params.SetStringKey("authority", - base::as_u16cstr(authority.sAuthorityName)); + params.Set("authority", base::as_u16cstr(authority.sAuthorityName)); } - params.SetKey("flags", ContextFlagsToValue(attributes)); - return params; + params.Set("flags", ContextFlagsToValue(attributes)); + return base::Value(std::move(params)); } base::Value InitializeSecurityContextParams(SSPILibrary* library, @@ -100,12 +97,13 @@ base::Value InitializeSecurityContextParams(SSPILibrary* library, Error result, SECURITY_STATUS status, DWORD attributes) { - base::Value params{base::Value::Type::DICTIONARY}; - params.SetKey("status", SecurityStatusToValue(result, status)); - if (result == OK) - params.SetKey("context", - ContextAttributesToValue(library, handle, attributes)); - return params; + base::Value::Dict params; + params.Set("status", SecurityStatusToValue(result, status)); + if (result == OK) { + params.Set("context", + ContextAttributesToValue(library, handle, attributes)); + } + return base::Value(std::move(params)); } Error MapAcquireCredentialsStatusToError(SECURITY_STATUS status) { @@ -548,10 +546,10 @@ int HttpAuthSSPI::GetNextSecurityToken(const std::string& spn, context_flags |= (ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH); net_log.BeginEvent(NetLogEventType::AUTH_LIBRARY_INIT_SEC_CTX, [&] { - base::Value params{base::Value::Type::DICTIONARY}; - params.SetStringKey("spn", spn); - params.SetKey("flags", ContextFlagsToValue(context_flags)); - return params; + base::Value::Dict params; + params.Set("spn", spn); + params.Set("flags", ContextFlagsToValue(context_flags)); + return base::Value(std::move(params)); }); // This returns a token that is passed to the remote server. diff --git a/chromium/net/http/http_auth_unittest.cc b/chromium/net/http/http_auth_unittest.cc index 5bdc7fb2997..7ee55269aab 100644 --- a/chromium/net/http/http_auth_unittest.cc +++ b/chromium/net/http/http_auth_unittest.cc @@ -132,16 +132,16 @@ TEST(HttpAuthTest, ChooseBestChallenge) { url::SchemeHostPort scheme_host_port(GURL("http://www.example.com")); std::set<HttpAuth::Scheme> disabled_schemes; MockAllowHttpAuthPreferences http_auth_preferences; - std::unique_ptr<HostResolver> host_resolver(new MockHostResolver()); + auto host_resolver = std::make_unique<MockHostResolver>(); std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory( HttpAuthHandlerFactory::CreateDefault()); http_auth_handler_factory->SetHttpAuthPreferences(kNegotiateAuthScheme, &http_auth_preferences); - for (size_t i = 0; i < std::size(tests); ++i) { + for (const auto& test : tests) { // Make a HttpResponseHeaders object. std::string headers_with_status_line("HTTP/1.1 401 Unauthorized\n"); - headers_with_status_line += tests[i].headers; + headers_with_status_line += test.headers; scoped_refptr<HttpResponseHeaders> headers = HeadersFromResponseText(headers_with_status_line); @@ -153,11 +153,11 @@ TEST(HttpAuthTest, ChooseBestChallenge) { disabled_schemes, NetLogWithSource(), host_resolver.get(), &handler); if (handler.get()) { - EXPECT_EQ(tests[i].challenge_scheme, handler->auth_scheme()); - EXPECT_STREQ(tests[i].challenge_realm, handler->realm().c_str()); + EXPECT_EQ(test.challenge_scheme, handler->auth_scheme()); + EXPECT_STREQ(test.challenge_realm, handler->realm().c_str()); } else { - EXPECT_EQ(HttpAuth::AUTH_SCHEME_MAX, tests[i].challenge_scheme); - EXPECT_STREQ("", tests[i].challenge_realm); + EXPECT_EQ(HttpAuth::AUTH_SCHEME_MAX, test.challenge_scheme); + EXPECT_STREQ("", test.challenge_realm); } } } diff --git a/chromium/net/http/http_basic_state_unittest.cc b/chromium/net/http/http_basic_state_unittest.cc index 662aef260a7..3cd757a287a 100644 --- a/chromium/net/http/http_basic_state_unittest.cc +++ b/chromium/net/http/http_basic_state_unittest.cc @@ -16,10 +16,11 @@ namespace net { namespace { TEST(HttpBasicStateTest, ConstructsProperly) { - ClientSocketHandle* const handle = new ClientSocketHandle; + auto handle = std::make_unique<ClientSocketHandle>(); + ClientSocketHandle* const handle_ptr = handle.get(); // Ownership of |handle| is passed to |state|. - const HttpBasicState state(base::WrapUnique(handle), true /* using_proxy */); - EXPECT_EQ(handle, state.connection()); + const HttpBasicState state(std::move(handle), true /* using_proxy */); + EXPECT_EQ(handle_ptr, state.connection()); EXPECT_TRUE(state.using_proxy()); } @@ -30,13 +31,14 @@ TEST(HttpBasicStateTest, ConstructsProperlyWithDifferentOptions) { } TEST(HttpBasicStateTest, ReleaseConnectionWorks) { - ClientSocketHandle* const handle = new ClientSocketHandle; + auto handle = std::make_unique<ClientSocketHandle>(); + ClientSocketHandle* const handle_ptr = handle.get(); // Ownership of |handle| is passed to |state|. - HttpBasicState state(base::WrapUnique(handle), false); + HttpBasicState state(std::move(handle), false); const std::unique_ptr<ClientSocketHandle> released_connection( state.ReleaseConnection()); - EXPECT_EQ(NULL, state.connection()); - EXPECT_EQ(handle, released_connection.get()); + EXPECT_EQ(nullptr, state.connection()); + EXPECT_EQ(handle_ptr, released_connection.get()); } TEST(HttpBasicStateTest, InitializeWorks) { @@ -62,7 +64,7 @@ TEST(HttpBasicStateTest, DeleteParser) { state.Initialize(&request_info, LOW, NetLogWithSource()); EXPECT_TRUE(state.parser()); state.DeleteParser(); - EXPECT_EQ(NULL, state.parser()); + EXPECT_EQ(nullptr, state.parser()); } TEST(HttpBasicStateTest, GenerateRequestLineNoProxy) { diff --git a/chromium/net/http/http_basic_stream.cc b/chromium/net/http/http_basic_stream.cc index 1dcf2b018f0..d3e39277eeb 100644 --- a/chromium/net/http/http_basic_stream.cc +++ b/chromium/net/http/http_basic_stream.cc @@ -8,6 +8,7 @@ #include <utility> #include "base/bind.h" +#include "net/http/http_network_session.h" #include "net/http/http_raw_request_headers.h" #include "net/http/http_request_info.h" #include "net/http/http_response_body_drainer.h" @@ -88,17 +89,19 @@ void HttpBasicStream::Close(bool not_reusable) { StreamSocket* socket = state_.connection()->socket(); if (not_reusable && socket) socket->Disconnect(); + parser()->OnConnectionClose(); state_.connection()->Reset(); } -HttpStream* HttpBasicStream::RenewStreamForAuth() { +std::unique_ptr<HttpStream> HttpBasicStream::RenewStreamForAuth() { DCHECK(IsResponseBodyComplete()); DCHECK(!parser()->IsMoreDataBuffered()); // The HttpStreamParser object still has a pointer to the connection. Just to // be extra-sure it doesn't touch the connection again, delete it here rather // than leaving it until the destructor is called. state_.DeleteParser(); - return new HttpBasicStream(state_.ReleaseConnection(), state_.using_proxy()); + return std::make_unique<HttpBasicStream>(state_.ReleaseConnection(), + state_.using_proxy()); } bool HttpBasicStream::IsResponseBodyComplete() const { @@ -184,8 +187,8 @@ int HttpBasicStream::GetRemoteEndpoint(IPEndPoint* endpoint) { } void HttpBasicStream::Drain(HttpNetworkSession* session) { - HttpResponseBodyDrainer* drainer = new HttpResponseBodyDrainer(this); - drainer->Start(session); + session->StartResponseDrainer( + std::make_unique<HttpResponseBodyDrainer>(this)); // |drainer| will delete itself. } diff --git a/chromium/net/http/http_basic_stream.h b/chromium/net/http/http_basic_stream.h index 2d1c561a2c0..da8e5253743 100644 --- a/chromium/net/http/http_basic_stream.h +++ b/chromium/net/http/http_basic_stream.h @@ -64,7 +64,7 @@ class NET_EXPORT_PRIVATE HttpBasicStream : public HttpStream { void Close(bool not_reusable) override; - HttpStream* RenewStreamForAuth() override; + std::unique_ptr<HttpStream> RenewStreamForAuth() override; bool IsResponseBodyComplete() const override; diff --git a/chromium/net/http/http_byte_range_unittest.cc b/chromium/net/http/http_byte_range_unittest.cc index 4e17e45fffc..845c4bc50fb 100644 --- a/chromium/net/http/http_byte_range_unittest.cc +++ b/chromium/net/http/http_byte_range_unittest.cc @@ -28,12 +28,12 @@ TEST(HttpByteRangeTest, ValidRanges) { { -1, -1, 100000, true }, }; - for (size_t i = 0; i < std::size(tests); ++i) { + for (const auto& test : tests) { HttpByteRange range; - range.set_first_byte_position(tests[i].first_byte_position); - range.set_last_byte_position(tests[i].last_byte_position); - range.set_suffix_length(tests[i].suffix_length); - EXPECT_EQ(tests[i].valid, range.IsValid()); + range.set_first_byte_position(test.first_byte_position); + range.set_last_byte_position(test.last_byte_position); + range.set_suffix_length(test.suffix_length); + EXPECT_EQ(test.valid, range.IsValid()); } } @@ -60,24 +60,24 @@ TEST(HttpByteRangeTest, SetInstanceSize) { { 10, 10000, -1, 1000000, true, 10, 10000 }, }; - for (size_t i = 0; i < std::size(tests); ++i) { + for (const auto& test : tests) { HttpByteRange range; - range.set_first_byte_position(tests[i].first_byte_position); - range.set_last_byte_position(tests[i].last_byte_position); - range.set_suffix_length(tests[i].suffix_length); + range.set_first_byte_position(test.first_byte_position); + range.set_last_byte_position(test.last_byte_position); + range.set_suffix_length(test.suffix_length); - bool return_value = range.ComputeBounds(tests[i].instance_size); - EXPECT_EQ(tests[i].expected_return_value, return_value); + bool return_value = range.ComputeBounds(test.instance_size); + EXPECT_EQ(test.expected_return_value, return_value); if (return_value) { - EXPECT_EQ(tests[i].expected_lower_bound, range.first_byte_position()); - EXPECT_EQ(tests[i].expected_upper_bound, range.last_byte_position()); + EXPECT_EQ(test.expected_lower_bound, range.first_byte_position()); + EXPECT_EQ(test.expected_upper_bound, range.last_byte_position()); // Try to call SetInstanceSize the second time. - EXPECT_FALSE(range.ComputeBounds(tests[i].instance_size)); + EXPECT_FALSE(range.ComputeBounds(test.instance_size)); // And expect there's no side effect. - EXPECT_EQ(tests[i].expected_lower_bound, range.first_byte_position()); - EXPECT_EQ(tests[i].expected_upper_bound, range.last_byte_position()); - EXPECT_EQ(tests[i].suffix_length, range.suffix_length()); + EXPECT_EQ(test.expected_lower_bound, range.first_byte_position()); + EXPECT_EQ(test.expected_upper_bound, range.last_byte_position()); + EXPECT_EQ(test.suffix_length, range.suffix_length()); } } } @@ -93,8 +93,8 @@ TEST(HttpByteRangeTest, GetHeaderValue) { {HttpByteRange::RightUnbounded(100), "bytes=100-"}, {HttpByteRange::Suffix(100), "bytes=-100"}, }; - for (size_t i = 0; i < std::size(tests); ++i) { - EXPECT_EQ(tests[i].expected, tests[i].range.GetHeaderValue()); + for (const auto& test : tests) { + EXPECT_EQ(test.expected, test.range.GetHeaderValue()); } } diff --git a/chromium/net/http/http_cache.cc b/chromium/net/http/http_cache.cc index 9515e6f0915..1ee1910d709 100644 --- a/chromium/net/http/http_cache.cc +++ b/chromium/net/http/http_cache.cc @@ -48,6 +48,7 @@ #include "net/http/http_util.h" #include "net/log/net_log_with_source.h" #include "net/quic/quic_server_info.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #if BUILDFLAG(IS_POSIX) #include <unistd.h> @@ -95,10 +96,9 @@ std::unique_ptr<HttpCache::BackendFactory> HttpCache::DefaultBackend::InMemory( base::FilePath(), max_bytes, false); } -int HttpCache::DefaultBackend::CreateBackend( +disk_cache::BackendResult HttpCache::DefaultBackend::CreateBackend( NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) { + base::OnceCallback<void(disk_cache::BackendResult)> callback) { DCHECK_GE(max_bytes_, 0); disk_cache::ResetHandling reset_handling = hard_reset_ ? disk_cache::ResetHandling::kReset @@ -108,13 +108,12 @@ int HttpCache::DefaultBackend::CreateBackend( if (app_status_listener_) { return disk_cache::CreateCacheBackend( type_, backend_type_, file_operations_factory_, path_, max_bytes_, - reset_handling, net_log, backend, std::move(callback), - app_status_listener_); + reset_handling, net_log, std::move(callback), app_status_listener_); } #endif return disk_cache::CreateCacheBackend( type_, backend_type_, file_operations_factory_, path_, max_bytes_, - reset_handling, net_log, backend, std::move(callback)); + reset_handling, net_log, std::move(callback)); } #if BUILDFLAG(IS_ANDROID) @@ -131,9 +130,7 @@ HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* entry, bool opened_in) DCHECK(disk_entry); } -HttpCache::ActiveEntry::~ActiveEntry() { - disk_entry->Close(); -} +HttpCache::ActiveEntry::~ActiveEntry() = default; bool HttpCache::ActiveEntry::HasNoTransactions() { return (!writers || writers->IsEmpty()) && readers.empty() && @@ -180,19 +177,14 @@ class HttpCache::WorkItem { WorkItem(WorkItemOperation operation, Transaction* transaction, ActiveEntry** entry) - : operation_(operation), - transaction_(transaction), - entry_(entry), - backend_(nullptr) {} + : operation_(operation), transaction_(transaction), entry_(entry) {} WorkItem(WorkItemOperation operation, Transaction* transaction, - CompletionOnceCallback callback, - disk_cache::Backend** backend) + CompletionOnceCallback callback) : operation_(operation), transaction_(transaction), entry_(nullptr), - callback_(std::move(callback)), - backend_(backend) {} + callback_(std::move(callback)) {} ~WorkItem() = default; // Calls back the transaction with the result of the operation. @@ -205,9 +197,7 @@ class HttpCache::WorkItem { // Notifies the caller about the operation completion. Returns true if the // callback was invoked. - bool DoCallback(int result, disk_cache::Backend* backend) { - if (backend_) - *backend_ = backend; + bool DoCallback(int result) { if (!callback_.is_null()) { std::move(callback_).Run(result); return true; @@ -231,7 +221,6 @@ class HttpCache::WorkItem { raw_ptr<Transaction> transaction_; raw_ptr<ActiveEntry*> entry_; CompletionOnceCallback callback_; // User callback. - raw_ptr<disk_cache::Backend*> backend_; }; //----------------------------------------------------------------------------- @@ -284,11 +273,10 @@ HttpCache::~HttpCache() { // done with said operations, or it will attempt to use deleted data. disk_cache_.reset(); - for (auto pending_it = pending_ops_.begin(); pending_it != pending_ops_.end(); - ++pending_it) { + for (auto& pending_it : pending_ops_) { // We are not notifying the transactions about the cache going away, even // though they are waiting for a callback that will never fire. - PendingOp* pending_op = pending_it->second; + PendingOp* pending_op = pending_it.second; pending_op->writer.reset(); bool delete_pending_op = true; if (building_backend_ && pending_op->callback_will_delete) { @@ -312,7 +300,19 @@ int HttpCache::GetBackend(disk_cache::Backend** backend, return OK; } - return CreateBackend(backend, std::move(callback)); + int rv = + CreateBackend(base::BindOnce(&HttpCache::ReportGetBackendResult, + GetWeakPtr(), backend, std::move(callback))); + if (rv != net::ERR_IO_PENDING) + *backend = disk_cache_.get(); + return rv; +} + +void HttpCache::ReportGetBackendResult(disk_cache::Backend** backend, + CompletionOnceCallback callback, + int net_error) { + *backend = disk_cache_.get(); + std::move(callback).Run(net_error); } disk_cache::Backend* HttpCache::GetCurrentBackend() const { @@ -349,6 +349,9 @@ void HttpCache::OnExternalCacheHit( if (!disk_cache_.get() || mode_ == DISABLE) return; + if (IsSplitCacheEnabled() && network_isolation_key.IsTransient()) + return; + HttpRequestInfo request_info; request_info.url = url; request_info.method = http_method; @@ -361,8 +364,8 @@ void HttpCache::OnExternalCacheHit( request_info.load_flags |= ~LOAD_DO_NOT_SAVE_COOKIES; } - std::string key = - GenerateCacheKey(&request_info, /*use_single_keyed_cache=*/false); + std::string key = *GenerateCacheKeyForRequest( + &request_info, /*use_single_keyed_cache=*/false); disk_cache_->OnExternalCacheHit(key); } @@ -372,11 +375,11 @@ int HttpCache::CreateTransaction( // Do lazy initialization of disk cache if needed. if (!disk_cache_.get()) { // We don't care about the result. - CreateBackend(nullptr, CompletionOnceCallback()); + CreateBackend(CompletionOnceCallback()); } - HttpCache::Transaction* new_transaction = - new HttpCache::Transaction(priority, this); + auto new_transaction = + std::make_unique<HttpCache::Transaction>(priority, this); if (bypass_lock_for_test_) new_transaction->BypassLockForTest(); if (bypass_lock_after_headers_for_test_) @@ -384,7 +387,7 @@ int HttpCache::CreateTransaction( if (fail_conditionalization_for_test_) new_transaction->FailConditionalizationForTest(); - transaction->reset(new_transaction); + *transaction = std::move(new_transaction); return OK; } @@ -443,39 +446,75 @@ std::string HttpCache::GetResourceURLFromHttpCacheKey(const std::string& key) { return key.substr(pos); } -Error HttpCache::CheckResourceExistence( +// static +// Generate a key that can be used inside the cache. +absl::optional<std::string> HttpCache::GenerateCacheKey( const GURL& url, - const base::StringPiece method, + int load_flags, const NetworkIsolationKey& network_isolation_key, - bool is_subframe, - base::OnceCallback<void(Error)> callback) { - if (!disk_cache_) - return ERR_CACHE_MISS; - - HttpRequestInfo request_info; - request_info.url = url; - request_info.method = std::string(method); - request_info.network_isolation_key = network_isolation_key; - request_info.is_subframe_document_resource = is_subframe; + int64_t upload_data_identifier, + bool is_subframe_document_resource, + bool use_single_keyed_cache, + const std::string& single_key_checksum) { + // The first character of the key may vary depending on whether or not sending + // credentials is permitted for this request. This only happens if the + // SplitCacheByIncludeCredentials feature is enabled, or if the single-keyed + // cache is enabled. The single-keyed cache must always be split by + // credentials in order to make coep:credentialless work safely. + const char credential_key = + ((base::FeatureList::IsEnabled( + features::kSplitCacheByIncludeCredentials) || + use_single_keyed_cache) && + (load_flags & LOAD_DO_NOT_SAVE_COOKIES)) + ? '0' + : '1'; - // TODO(https://crbug.com/1325315): Support looking in the single-keyed cache - // for the resource. - std::string key = - GenerateCacheKey(&request_info, /*use_single_keyed_cache=*/false); - disk_cache::EntryResult entry_result = disk_cache_->OpenEntry( - key, net::IDLE, - base::BindOnce(&HttpCache::ResourceExistenceCheckCallback, GetWeakPtr(), - std::move(callback))); + std::string isolation_key; + if (use_single_keyed_cache) { + DCHECK(IsSplitCacheEnabled()); + DCHECK(!(load_flags & + (net::LOAD_VALIDATE_CACHE | net::LOAD_BYPASS_CACHE | + net::LOAD_SKIP_CACHE_VALIDATION | net::LOAD_ONLY_FROM_CACHE | + net::LOAD_DISABLE_CACHE | net::LOAD_SKIP_VARY_CHECK))); + isolation_key = base::StrCat( + {kSingleKeyPrefix, single_key_checksum, kSingleKeySeparator}); + } else if (IsSplitCacheEnabled()) { + // Prepend the key with |kDoubleKeyPrefix| = "_dk_" to mark it as + // double-keyed (and makes it an invalid url so that it doesn't get + // confused with a single-keyed entry). Separate the origin and url + // with invalid whitespace character |kDoubleKeySeparator|. + if (network_isolation_key.IsTransient()) + return absl::nullopt; + std::string subframe_document_resource_prefix = + is_subframe_document_resource ? kSubframeDocumentResourcePrefix : ""; + isolation_key = base::StrCat( + {kDoubleKeyPrefix, subframe_document_resource_prefix, + *network_isolation_key.ToCacheKeyString(), kDoubleKeySeparator}); + } - if (entry_result.net_error() == OK && !entry_result.opened()) - return ERR_CACHE_MISS; + // The key format is: + // credential_key/upload_data_identifier/[isolation_key]url - return entry_result.net_error(); + // Strip out the reference, username, and password sections of the URL and + // concatenate with the credential_key, the post_key, and the network + // isolation key if we are splitting the cache. + return base::StringPrintf("%c/%" PRId64 "/%s%s", credential_key, + upload_data_identifier, isolation_key.c_str(), + HttpUtil::SpecForRequest(url).c_str()); } // static -std::string HttpCache::GenerateCacheKeyForTest(const HttpRequestInfo* request) { - return GenerateCacheKey(request, /*use_single_keyed_cache=*/false); +absl::optional<std::string> HttpCache::GenerateCacheKeyForRequest( + const HttpRequestInfo* request, + bool use_single_keyed_cache) { + DCHECK(request); + const int64_t upload_data_identifier = + request->upload_data_stream ? request->upload_data_stream->identifier() + : int64_t(0); + return GenerateCacheKey( + request->url, request->load_flags, request->network_isolation_key, + upload_data_identifier, request->is_subframe_document_resource, + use_single_keyed_cache, request->checksum); } // static @@ -520,8 +559,9 @@ net::Error HttpCache::CreateAndSetWorkItem(ActiveEntry** entry, return OK; } -int HttpCache::CreateBackend(disk_cache::Backend** backend, - CompletionOnceCallback callback) { +int HttpCache::CreateBackend(CompletionOnceCallback callback) { + DCHECK(!disk_cache_); + if (!backend_factory_.get()) return ERR_FAILED; @@ -529,7 +569,7 @@ int HttpCache::CreateBackend(disk_cache::Backend** backend, const bool callback_is_null = callback.is_null(); std::unique_ptr<WorkItem> item = std::make_unique<WorkItem>( - WI_CREATE_BACKEND, nullptr, std::move(callback), backend); + WI_CREATE_BACKEND, nullptr, std::move(callback)); // This is the only operation that we can do that is not related to any given // entry, so we use an empty key for it. @@ -544,17 +584,18 @@ int HttpCache::CreateBackend(disk_cache::Backend** backend, pending_op->writer = std::move(item); - int rv = backend_factory_->CreateBackend( - net_log_, &pending_op->backend, - base::BindOnce(&HttpCache::OnPendingOpComplete, GetWeakPtr(), - pending_op)); - if (rv == ERR_IO_PENDING) { + disk_cache::BackendResult result = backend_factory_->CreateBackend( + net_log_, base::BindOnce(&HttpCache::OnPendingBackendCreationOpComplete, + GetWeakPtr(), pending_op)); + if (result.net_error == ERR_IO_PENDING) { pending_op->callback_will_delete = true; - return rv; + return result.net_error; } pending_op->writer->ClearCallback(); - OnPendingOpComplete(GetWeakPtr(), pending_op, rv); + int rv = result.net_error; + OnPendingBackendCreationOpComplete(GetWeakPtr(), pending_op, + std::move(result)); return rv; } @@ -566,68 +607,13 @@ int HttpCache::GetBackendForTransaction(Transaction* transaction) { return ERR_FAILED; std::unique_ptr<WorkItem> item = std::make_unique<WorkItem>( - WI_CREATE_BACKEND, transaction, CompletionOnceCallback(), nullptr); + WI_CREATE_BACKEND, transaction, CompletionOnceCallback()); PendingOp* pending_op = GetPendingOp(std::string()); DCHECK(pending_op->writer); pending_op->pending_queue.push_back(std::move(item)); return ERR_IO_PENDING; } -// static -// Generate a key that can be used inside the cache. -std::string HttpCache::GenerateCacheKey(const HttpRequestInfo* request, - bool use_single_keyed_cache) { - // The first character of the key may vary depending on whether or not sending - // credentials is permitted for this request. This only happens if the - // SplitCacheByIncludeCredentials feature is enabled, or if the single-keyed - // cache is enabled. The single-keyed cache must always be split by - // credentials in order to make coep:credentialless work safely. - const char credential_key = - ((base::FeatureList::IsEnabled( - features::kSplitCacheByIncludeCredentials) || - use_single_keyed_cache) && - (request->load_flags & LOAD_DO_NOT_SAVE_COOKIES)) - ? '0' - : '1'; - - const int64_t post_key = request->upload_data_stream - ? request->upload_data_stream->identifier() - : int64_t(0); - std::string isolation_key; - if (use_single_keyed_cache) { - DCHECK(IsSplitCacheEnabled()); - DCHECK(!request->checksum.empty()); - DCHECK(!(request->load_flags & - (net::LOAD_VALIDATE_CACHE | net::LOAD_BYPASS_CACHE | - net::LOAD_SKIP_CACHE_VALIDATION | net::LOAD_ONLY_FROM_CACHE | - net::LOAD_DISABLE_CACHE | net::LOAD_SKIP_VARY_CHECK))); - isolation_key = base::StrCat( - {kSingleKeyPrefix, request->checksum, kSingleKeySeparator}); - } else if (IsSplitCacheEnabled()) { - // Prepend the key with |kDoubleKeyPrefix| = "_dk_" to mark it as - // double-keyed (and makes it an invalid url so that it doesn't get - // confused with a single-keyed entry). Separate the origin and url - // with invalid whitespace character |kDoubleKeySeparator|. - DCHECK(request->network_isolation_key.IsFullyPopulated()); - std::string subframe_document_resource_prefix = - request->is_subframe_document_resource ? kSubframeDocumentResourcePrefix - : ""; - isolation_key = base::StrCat( - {kDoubleKeyPrefix, subframe_document_resource_prefix, - request->network_isolation_key.ToString(), kDoubleKeySeparator}); - } - - // The key format is: - // credential_key/post_key/[isolation_key]url - - // Strip out the reference, username, and password sections of the URL and - // concatenate with the credential_key, the post_key, and the network - // isolation key if we are splitting the cache. - return base::StringPrintf("%c/%" PRId64 "/%s%s", credential_key, post_key, - isolation_key.c_str(), - HttpUtil::SpecForRequest(request->url).c_str()); -} - void HttpCache::DoomActiveEntry(const std::string& key) { auto it = active_entries_.find(key); if (it == active_entries_.end()) @@ -659,7 +645,7 @@ int HttpCache::DoomEntry(const std::string& key, Transaction* transaction) { DCHECK_EQ(0u, doomed_entries_.count(entry_ptr)); doomed_entries_[entry_ptr] = std::move(entry); - entry_ptr->disk_entry->Doom(); + entry_ptr->GetEntry()->Doom(); entry_ptr->doomed = true; DCHECK(!entry_ptr->SafeToDestroy()); @@ -695,6 +681,9 @@ void HttpCache::DoomMainEntryForUrl(const GURL& url, if (!disk_cache_) return; + if (IsSplitCacheEnabled() && isolation_key.IsTransient()) + return; + HttpRequestInfo temp_info; temp_info.url = url; temp_info.method = "GET"; @@ -704,7 +693,7 @@ void HttpCache::DoomMainEntryForUrl(const GURL& url, // single-keyed cache, so therefore it is correct that use_single_keyed_cache // be false. std::string key = - GenerateCacheKey(&temp_info, /*use_single_keyed_cache=*/false); + *GenerateCacheKeyForRequest(&temp_info, /*use_single_keyed_cache=*/false); // Defer to DoomEntry if there is an active entry, otherwise call // AsyncDoomEntry without triggering a callback. @@ -731,16 +720,17 @@ HttpCache::ActiveEntry* HttpCache::FindActiveEntry(const std::string& key) { HttpCache::ActiveEntry* HttpCache::ActivateEntry(disk_cache::Entry* disk_entry, bool opened) { DCHECK(!FindActiveEntry(disk_entry->GetKey())); - ActiveEntry* entry = new ActiveEntry(disk_entry, opened); - active_entries_[disk_entry->GetKey()] = base::WrapUnique(entry); - return entry; + auto entry = std::make_unique<ActiveEntry>(disk_entry, opened); + ActiveEntry* entry_ptr = entry.get(); + active_entries_[disk_entry->GetKey()] = std::move(entry); + return entry_ptr; } void HttpCache::DeactivateEntry(ActiveEntry* entry) { DCHECK(!entry->doomed); DCHECK(entry->SafeToDestroy()); - std::string key = entry->disk_entry->GetKey(); + std::string key = entry->GetEntry()->GetKey(); if (key.empty()) return SlowDeactivateEntry(entry); @@ -888,7 +878,7 @@ void HttpCache::DestroyEntry(ActiveEntry* entry) { int HttpCache::AddTransactionToEntry(ActiveEntry* entry, Transaction* transaction) { DCHECK(entry); - DCHECK(entry->disk_entry); + DCHECK(entry->GetEntry()); // Always add a new transaction to the queue to maintain FIFO order. entry->add_to_entry_queue.push_back(transaction); ProcessQueuedTransactions(entry); @@ -934,7 +924,7 @@ void HttpCache::DoneWithEntry(ActiveEntry* entry, bool is_mode_read_only = transaction->mode() == Transaction::READ; if (!entry_is_complete && !is_mode_read_only && is_partial) - entry->disk_entry->CancelSparseIO(); + entry->GetEntry()->CancelSparseIO(); // Transaction is waiting in the done_headers_queue. auto it = std::find(entry->done_headers_queue.begin(), @@ -1031,12 +1021,12 @@ void HttpCache::DoomEntryValidationNoMatch(ActiveEntry* entry) { entry->headers_transaction = nullptr; if (entry->SafeToDestroy()) { - entry->disk_entry->Doom(); + entry->GetEntry()->Doom(); DestroyEntry(entry); return; } - DoomActiveEntry(entry->disk_entry->GetKey()); + DoomActiveEntry(entry->GetEntry()->GetKey()); // Restart only add_to_entry_queue transactions. // Post task here to avoid a race in creating the entry between |transaction| @@ -1077,10 +1067,10 @@ void HttpCache::ProcessEntryFailure(ActiveEntry* entry) { RemoveAllQueuedTransactions(entry, &list); if (entry->SafeToDestroy()) { - entry->disk_entry->Doom(); + entry->GetEntry()->Doom(); DestroyEntry(entry); } else { - DoomActiveEntry(entry->disk_entry->GetKey()); + DoomActiveEntry(entry->GetEntry()->GetKey()); } // ERR_CACHE_RACE causes the transaction to restart the whole process. for (auto* queued_transaction : list) @@ -1468,7 +1458,7 @@ void HttpCache::OnIOComplete(int result, PendingOp* pending_op) { } // static -void HttpCache::OnPendingOpComplete(const base::WeakPtr<HttpCache>& cache, +void HttpCache::OnPendingOpComplete(base::WeakPtr<HttpCache> cache, PendingOp* pending_op, int rv) { if (cache.get()) { @@ -1482,10 +1472,9 @@ void HttpCache::OnPendingOpComplete(const base::WeakPtr<HttpCache>& cache, } // static -void HttpCache::OnPendingCreationOpComplete( - const base::WeakPtr<HttpCache>& cache, - PendingOp* pending_op, - disk_cache::EntryResult result) { +void HttpCache::OnPendingCreationOpComplete(base::WeakPtr<HttpCache> cache, + PendingOp* pending_op, + disk_cache::EntryResult result) { if (!cache.get()) { // The callback was cancelled so we should delete the pending_op that // was used with this callback. If |result| contains a fresh entry @@ -1501,6 +1490,25 @@ void HttpCache::OnPendingCreationOpComplete( cache->OnIOComplete(rv, pending_op); } +// static +void HttpCache::OnPendingBackendCreationOpComplete( + base::WeakPtr<HttpCache> cache, + PendingOp* pending_op, + disk_cache::BackendResult result) { + if (!cache.get()) { + // The callback was cancelled so we should delete the pending_op that + // was used with this callback. If `result` contains a cache backend, + // it will be destroyed with it. + delete pending_op; + return; + } + + int rv = result.net_error; + pending_op->backend = std::move(result.backend); + pending_op->callback_will_delete = false; + cache->OnIOComplete(rv, pending_op); +} + void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) { std::unique_ptr<WorkItem> item = std::move(pending_op->writer); WorkItemOperation op = item->operation(); @@ -1537,17 +1545,8 @@ void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) { } // The cache may be gone when we return from the callback. - if (!item->DoCallback(result, disk_cache_.get())) + if (!item->DoCallback(result)) item->NotifyTransaction(result, nullptr); } -void HttpCache::ResourceExistenceCheckCallback( - base::OnceCallback<void(Error)> callback, - disk_cache::EntryResult entry_result) { - Error result = (entry_result.net_error() == OK && entry_result.opened()) - ? OK - : ERR_CACHE_MISS; - std::move(callback).Run(result); -} - } // namespace net diff --git a/chromium/net/http/http_cache.h b/chromium/net/http/http_cache.h index c97adfe07fa..987e073e93e 100644 --- a/chromium/net/http/http_cache.h +++ b/chromium/net/http/http_cache.h @@ -35,22 +35,15 @@ #include "net/base/net_errors.h" #include "net/base/net_export.h" #include "net/base/request_priority.h" +#include "net/disk_cache/disk_cache.h" #include "net/http/http_transaction_factory.h" +#include "third_party/abseil-cpp/absl/types/optional.h" class GURL; -namespace base { -namespace android { +namespace base::android { class ApplicationStatusListener; -} // namespace android -} // namespace base - -namespace disk_cache { -class Backend; -class BackendFileOperationsFactory; -class Entry; -class EntryResult; -} // namespace disk_cache +} // namespace base::android namespace net { @@ -74,17 +67,16 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // A BackendFactory creates a backend object to be used by the HttpCache. class NET_EXPORT BackendFactory { public: - virtual ~BackendFactory() {} + virtual ~BackendFactory() = default; - // The actual method to build the backend. Returns a net error code. If - // ERR_IO_PENDING is returned, the |callback| will be notified when the - // operation completes, and |backend| must remain valid until the - // notification arrives. + // The actual method to build the backend. The return value and `callback` + // conventions match disk_cache::CreateCacheBackend + // // The implementation must not access the factory object after invoking the - // |callback| because the object can be deleted from within the callback. - virtual int CreateBackend(NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) = 0; + // `callback` because the object can be deleted from within the callback. + virtual disk_cache::BackendResult CreateBackend( + NetLog* net_log, + base::OnceCallback<void(disk_cache::BackendResult)> callback) = 0; #if BUILDFLAG(IS_ANDROID) virtual void SetAppStatusListener( @@ -112,9 +104,9 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { static std::unique_ptr<BackendFactory> InMemory(int max_bytes); // BackendFactory implementation. - int CreateBackend(NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) override; + disk_cache::BackendResult CreateBackend( + NetLog* net_log, + base::OnceCallback<void(disk_cache::BackendResult)> callback) override; #if BUILDFLAG(IS_ANDROID) void SetAppStatusListener( @@ -186,8 +178,9 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // Retrieves the cache backend for this HttpCache instance. If the backend // is not initialized yet, this method will initialize it. The return value is // a network error code, and it could be ERR_IO_PENDING, in which case the - // |callback| will be notified when the operation completes. The pointer that - // receives the |backend| must remain valid until the operation completes. + // `callback` will be notified when the operation completes. The pointer that + // receives the `backend` must remain valid until the operation completes. + // `callback` will get cancelled if the HttpCache is destroyed. int GetBackend(disk_cache::Backend** backend, CompletionOnceCallback callback); @@ -259,8 +252,21 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // Get the URL from the entry's cache key. static std::string GetResourceURLFromHttpCacheKey(const std::string& key); - // Function to generate cache key for testing. - static std::string GenerateCacheKeyForTest(const HttpRequestInfo* request); + // Generates the cache key for a request. Returns nullopt if the cache is + // configured to be split by the NetworkIsolationKey, and the + // NetworkIsolationKey is transient, in which case nothing should generally be + // stored to disk. + static absl::optional<std::string> GenerateCacheKey( + const GURL& url, + int load_flags, + const NetworkIsolationKey& network_isolation_key, + int64_t upload_data_identifier, + bool is_subframe_document_resource, + bool use_single_keyed_cache, + const std::string& single_key_checksum); + static absl::optional<std::string> GenerateCacheKeyForRequest( + const HttpRequestInfo* request, + bool use_single_keyed_cache = false); // Enable split cache feature if not already overridden in the feature list. // Should only be invoked during process initialization before the HTTP @@ -274,12 +280,6 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // Resets g_init_cache and g_enable_split_cache for tests. static void ClearGlobalsForTesting(); - Error CheckResourceExistence(const GURL& url, - const base::StringPiece method, - const NetworkIsolationKey& network_isolation_key, - bool is_subframe, - base::OnceCallback<void(Error)>); - private: // Types -------------------------------------------------------------------- @@ -360,7 +360,9 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { bool TransactionInReaders(Transaction* transaction) const; - const raw_ptr<disk_cache::Entry> disk_entry; + disk_cache::Entry* GetEntry() { return disk_entry.get(); } + + disk_cache::ScopedEntryPtr disk_entry; // Indicates if the disk_entry was opened or not (i.e.: created). // It is set to true when a transaction is added to an entry so that other, @@ -407,10 +409,13 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { WorkItemOperation operation, PendingOp* pending_op); - // Creates the |backend| object and notifies the |callback| when the operation - // completes. Returns an error code. - int CreateBackend(disk_cache::Backend** backend, - CompletionOnceCallback callback); + // Creates the `disk_cache_` object and notifies the `callback` when the + // operation completes. Returns an error code. + int CreateBackend(CompletionOnceCallback callback); + + void ReportGetBackendResult(disk_cache::Backend** backend, + CompletionOnceCallback callback, + int net_error); // Makes sure that the backend creation is complete before allowing the // provided transaction to use the object. Returns an error code. @@ -419,10 +424,6 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // time after receiving the notification. int GetBackendForTransaction(Transaction* transaction); - // Generates the cache key for this request. - static std::string GenerateCacheKey(const HttpRequestInfo*, - bool use_single_keyed_cache); - // Dooms the entry selected by |key|, if it is currently in the list of active // entries. void DoomActiveEntry(const std::string& key); @@ -624,21 +625,24 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { // This is necessary because |pending_op| owns a disk_cache::Backend that has // been passed in to CreateCacheBackend(), therefore must live until callback // is called. - static void OnPendingOpComplete(const base::WeakPtr<HttpCache>& cache, + static void OnPendingOpComplete(base::WeakPtr<HttpCache> cache, PendingOp* pending_op, int result); // Variant for Open/Create method family, which has a different signature. - static void OnPendingCreationOpComplete(const base::WeakPtr<HttpCache>& cache, + static void OnPendingCreationOpComplete(base::WeakPtr<HttpCache> cache, PendingOp* pending_op, disk_cache::EntryResult result); + // Variant for CreateCacheBackend, which has a different signature. + static void OnPendingBackendCreationOpComplete( + base::WeakPtr<HttpCache> cache, + PendingOp* pending_op, + disk_cache::BackendResult result); + // Processes the backend creation notification. void OnBackendCreated(int result, PendingOp* pending_op); - void ResourceExistenceCheckCallback(base::OnceCallback<void(Error)> callback, - disk_cache::EntryResult entry_result); - // Constants ---------------------------------------------------------------- // Used when generating and accessing keys if cache is split. diff --git a/chromium/net/http/http_cache_lookup_manager.cc b/chromium/net/http/http_cache_lookup_manager.cc index 6ed9cd0d36e..194eb3fba6c 100644 --- a/chromium/net/http/http_cache_lookup_manager.cc +++ b/chromium/net/http/http_cache_lookup_manager.cc @@ -19,17 +19,17 @@ namespace net { base::Value NetLogPushLookupTransactionParams( const NetLogSource& net_log, const ServerPushDelegate::ServerPushHelper* push_helper) { - base::Value dict(base::Value::Type::DICTIONARY); - net_log.AddToEventParameters(&dict); - dict.SetStringKey("push_url", push_helper->GetURL().possibly_invalid_spec()); - return dict; + base::Value::Dict dict; + net_log.AddToEventParameters(dict); + dict.Set("push_url", push_helper->GetURL().possibly_invalid_spec()); + return base::Value(std::move(dict)); } HttpCacheLookupManager::LookupTransaction::LookupTransaction( std::unique_ptr<ServerPushHelper> server_push_helper, NetLog* net_log) : push_helper_(std::move(server_push_helper)), - request_(new HttpRequestInfo()), + request_(std::make_unique<HttpRequestInfo>()), net_log_(NetLogWithSource::Make( net_log, NetLogSourceType::SERVER_PUSH_LOOKUP_TRANSACTION)) {} diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc index 764fd4d65bc..fc53e0bb1ac 100644 --- a/chromium/net/http/http_cache_transaction.cc +++ b/chromium/net/http/http_cache_transaction.cc @@ -4,7 +4,7 @@ #include "net/http/http_cache_transaction.h" -#include "build/build_config.h" // For OS_POSIX +#include "build/build_config.h" // For IS_POSIX #if BUILDFLAG(IS_POSIX) #include <unistd.h> @@ -70,6 +70,13 @@ namespace { constexpr base::TimeDelta kStaleRevalidateTimeout = base::Seconds(60); +uint64_t GetNextTraceId(HttpCache* cache) { + static uint32_t sNextTraceId = 0; + + DCHECK(cache); + return (reinterpret_cast<uint64_t>(cache) << 32) | sNextTraceId++; +} + // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 // a "non-error response" is one with a 2xx (Successful) or 3xx // (Redirection) status code. @@ -91,6 +98,14 @@ enum ExternallyConditionalizedType { EXTERNALLY_CONDITIONALIZED_MAX }; +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class RestrictedPrefetchReused { + kNotReused = 0, + kReused = 1, + kMaxValue = kReused +}; + void RecordPervasivePayloadIndex(const char* histogram_name, int index) { if (index != -1) { base::UmaHistogramExactLinear(histogram_name, index, 101); @@ -161,7 +176,9 @@ static bool HeaderMatches(const HttpRequestHeaders& headers, //----------------------------------------------------------------------------- HttpCache::Transaction::Transaction(RequestPriority priority, HttpCache* cache) - : priority_(priority), cache_(cache->GetWeakPtr()) { + : trace_id_(GetNextTraceId(cache)), + priority_(priority), + cache_(cache->GetWeakPtr()) { TRACE_EVENT1("net", "HttpCacheTransaction::Transaction", "priority", RequestPriorityToString(priority)); static_assert(HttpCache::Transaction::kNumValidationHeaders == @@ -212,8 +229,8 @@ int HttpCache::Transaction::Start(const HttpRequestInfo* request, DCHECK(request); DCHECK(!callback.is_null()); TRACE_EVENT_WITH_FLOW1("net", "HttpCacheTransaction::Start", - net_log.source().id, TRACE_EVENT_FLAG_FLOW_OUT, "url", - request->url.spec()); + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_OUT, + "url", request->url.spec()); // Ensure that we only have one asynchronous call at a time. DCHECK(callback_.is_null()); @@ -310,9 +327,15 @@ bool HttpCache::Transaction::IsReadyToRestartForAuth() { int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { + TRACE_EVENT_WITH_FLOW1( + "net", "HttpCacheTransaction::Read", TRACE_ID_LOCAL(trace_id_), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "buf_len", buf_len); + DCHECK_EQ(next_state_, STATE_NONE); DCHECK(buf); - DCHECK_GT(buf_len, 0); + // TODO(https://crbug.com/1335423): Change to DCHECK_GT() or remove after bug + // is fixed. + CHECK_GT(buf_len, 0); DCHECK(!callback.is_null()); DCHECK(callback_.is_null()); @@ -397,7 +420,7 @@ int HttpCache::Transaction::TransitionToReadingState() { // Full request. // If it's a writer and a full request then it may read from the cache if its // offset is behind the current offset else from the network. - int disk_entry_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); + int disk_entry_size = entry_->GetEntry()->GetDataSize(kResponseContentIndex); if (read_offset_ == disk_entry_size || entry_->writers->network_read_only()) { next_state_ = STATE_NETWORK_READ_CACHE_WRITE; } else { @@ -612,7 +635,7 @@ void HttpCache::Transaction::SetValidatingCannotProceed() { void HttpCache::Transaction::WriterAboutToBeRemovedFromEntry(int result) { TRACE_EVENT_WITH_FLOW1( "net", "HttpCacheTransaction::WriterAboutToBeRemovedFromEntry", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); // Since the transaction can no longer access the network transaction, save // all network related info now. @@ -634,7 +657,7 @@ void HttpCache::Transaction::WriterAboutToBeRemovedFromEntry(int result) { void HttpCache::Transaction::WriteModeTransactionAboutToBecomeReader() { TRACE_EVENT_WITH_FLOW0( "net", "HttpCacheTransaction::WriteModeTransactionAboutToBecomeReader", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); mode_ = READ; if (moved_network_transaction_to_writers_ && @@ -1023,12 +1046,12 @@ int HttpCache::Transaction::DoGetBackendComplete(int result) { mode_ = NONE; if (!ShouldPassThrough()) { - // The flag LOAD_USE_SINGLE_KEYED_CACHE will have been changed to false if - // the entry was marked unusable and the transaction was restarted in - // DoCacheReadResponseComplete(), so it will no longer match the value in - // `request_`. So we pass it through explicitly. - cache_key_ = cache_->GenerateCacheKey( - request_, effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE); + // The flag `use_single_keyed_cache_` will have been changed back to false + // if the entry was marked unusable and the transaction was restarted in + // DoCacheReadResponseComplete(), even though `request_` will still have a + // checksum. So it needs to be passed explicitly. + cache_key_ = + *cache_->GenerateCacheKeyForRequest(request_, use_single_keyed_cache_); // Requested cache access mode. if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { @@ -1095,7 +1118,7 @@ int HttpCache::Transaction::DoGetBackendComplete(int result) { int HttpCache::Transaction::DoInitEntry() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoInitEntry", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(!new_entry_); @@ -1115,7 +1138,7 @@ int HttpCache::Transaction::DoInitEntry() { int HttpCache::Transaction::DoOpenOrCreateEntry() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoOpenOrCreateEntry", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(!new_entry_); TransitionToState(STATE_OPEN_OR_CREATE_ENTRY_COMPLETE); @@ -1176,7 +1199,7 @@ int HttpCache::Transaction::DoOpenOrCreateEntry() { int HttpCache::Transaction::DoOpenOrCreateEntryComplete(int result) { TRACE_EVENT_WITH_FLOW1( "net", "HttpCacheTransaction::DoOpenOrCreateEntryComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", (result == OK ? (new_entry_->opened ? "opened" : "created") : "failed")); @@ -1266,7 +1289,7 @@ int HttpCache::Transaction::DoOpenOrCreateEntryComplete(int result) { int HttpCache::Transaction::DoDoomEntry() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoDoomEntry", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); TransitionToState(STATE_DOOM_ENTRY_COMPLETE); cache_pending_ = true; @@ -1277,9 +1300,10 @@ int HttpCache::Transaction::DoDoomEntry() { } int HttpCache::Transaction::DoDoomEntryComplete(int result) { - TRACE_EVENT_WITH_FLOW1( - "net", "HttpCacheTransaction::DoDoomEntryComplete", net_log().source().id, - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); + TRACE_EVENT_WITH_FLOW1("net", "HttpCacheTransaction::DoDoomEntryComplete", + TRACE_ID_LOCAL(trace_id_), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, + "result", result); net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY, result); cache_pending_ = false; @@ -1291,7 +1315,7 @@ int HttpCache::Transaction::DoDoomEntryComplete(int result) { int HttpCache::Transaction::DoCreateEntry() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoCreateEntry", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(!new_entry_); TransitionToState(STATE_CREATE_ENTRY_COMPLETE); @@ -1302,7 +1326,7 @@ int HttpCache::Transaction::DoCreateEntry() { int HttpCache::Transaction::DoCreateEntryComplete(int result) { TRACE_EVENT_WITH_FLOW1("net", "HttpCacheTransaction::DoCreateEntryComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is @@ -1345,7 +1369,7 @@ int HttpCache::Transaction::DoCreateEntryComplete(int result) { int HttpCache::Transaction::DoAddToEntry() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoAddToEntry", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(new_entry_); cache_pending_ = true; @@ -1421,14 +1445,17 @@ void HttpCache::Transaction::AddCacheLockTimeoutHandler(ActiveEntry* entry) { int HttpCache::Transaction::DoAddToEntryComplete(int result) { TRACE_EVENT_WITH_FLOW1("net", "HttpCacheTransaction::DoAddToEntryComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY, result); - const base::TimeDelta entry_lock_wait = - TimeTicks::Now() - entry_lock_waiting_since_; - UMA_HISTOGRAM_TIMES("HttpCache.EntryLockWait", entry_lock_wait); + if (cache_ && cache_->GetCurrentBackend() && + cache_->GetCurrentBackend()->GetCacheType() != MEMORY_CACHE) { + const base::TimeDelta entry_lock_wait = + TimeTicks::Now() - entry_lock_waiting_since_; + base::UmaHistogramTimes("HttpCache.AddTransactionToEntry", entry_lock_wait); + } entry_lock_waiting_since_ = TimeTicks(); DCHECK(new_entry_); @@ -1464,8 +1491,8 @@ int HttpCache::Transaction::DoAddToEntryComplete(int result) { // TODO(crbug.com/713354) Access timestamp for histograms only if entry is // already written, to avoid data race since cache thread can also access // this. - if (!cache_->IsWritingInProgress(entry_)) - open_entry_last_used_ = entry_->disk_entry->GetLastUsed(); + if (!cache_->IsWritingInProgress(entry())) + open_entry_last_used_ = entry_->GetEntry()->GetLastUsed(); // TODO(jkarlin): We should either handle the case or DCHECK. if (result != OK) { @@ -1489,7 +1516,7 @@ int HttpCache::Transaction::DoAddToEntryComplete(int result) { int HttpCache::Transaction::DoDoneHeadersAddToEntryComplete(int result) { TRACE_EVENT_WITH_FLOW1( "net", "HttpCacheTransaction::DoDoneHeadersAddToEntryComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); // This transaction's response headers did not match its ActiveEntry so it // created a new ActiveEntry (new_entry_) to write to (and doomed the old @@ -1520,23 +1547,23 @@ int HttpCache::Transaction::DoDoneHeadersAddToEntryComplete(int result) { int HttpCache::Transaction::DoCacheReadResponse() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoCacheReadResponse", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(entry_); TransitionToState(STATE_CACHE_READ_RESPONSE_COMPLETE); - io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); + io_buf_len_ = entry_->GetEntry()->GetDataSize(kResponseInfoIndex); read_buf_ = base::MakeRefCounted<IOBuffer>(io_buf_len_); net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_INFO); - return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(), + return entry_->GetEntry()->ReadData(kResponseInfoIndex, 0, read_buf_.get(), io_buf_len_, io_callback_); } int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { TRACE_EVENT_WITH_FLOW2("net", "HttpCacheTransaction::DoCacheReadResponseComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result, "io_buf_len", io_buf_len_); net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_INFO, @@ -1556,9 +1583,9 @@ int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { // We've read the single keyed entry and it turned out to be unusable. Let's // retry reading from the split cache. - if (effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) { + if (use_single_keyed_cache_) { DCHECK(!network_trans_); - effective_load_flags_ &= ~LOAD_USE_SINGLE_KEYED_CACHE; + use_single_keyed_cache_ = false; DoneWithEntryForRestartWithCache(); TransitionToState(STATE_GET_BACKEND); return OK; @@ -1572,8 +1599,8 @@ int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { // TODO(crbug.com/713354) Only get data size if there is no other transaction // currently writing the response body due to the data race mentioned in the // associated bug. - if (!cache_->IsWritingInProgress(entry_)) { - int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); + if (!cache_->IsWritingInProgress(entry())) { + int current_size = entry_->GetEntry()->GetDataSize(kResponseContentIndex); int64_t full_response_length = response_.headers->GetContentLength(); // Some resources may have slipped in as truncated when they're not. @@ -1627,6 +1654,11 @@ int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { updated_prefetch_response_->restricted_prefetch = false; } + base::UmaHistogramEnumeration("HttpCache.RestrictedPrefetchReuse", + restricted_prefetch_reuse + ? RestrictedPrefetchReused::kReused + : RestrictedPrefetchReused::kNotReused); + TransitionToState(STATE_WRITE_UPDATED_PREFETCH_RESPONSE); return OK; } @@ -1638,7 +1670,7 @@ int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { int HttpCache::Transaction::DoCacheWriteUpdatedPrefetchResponse(int result) { TRACE_EVENT_WITH_FLOW0( "net", "HttpCacheTransaction::DoCacheWriteUpdatedPrefetchResponse", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(updated_prefetch_response_); // TODO(jkarlin): If DoUpdateCachedResponse is also called for this @@ -1653,7 +1685,7 @@ int HttpCache::Transaction::DoCacheWriteUpdatedPrefetchResponseComplete( TRACE_EVENT_WITH_FLOW0( "net", "HttpCacheTransaction::DoCacheWriteUpdatedPrefetchResponseComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); updated_prefetch_response_.reset(); TransitionToState(STATE_CACHE_DISPATCH_VALIDATION); @@ -1663,7 +1695,7 @@ int HttpCache::Transaction::DoCacheWriteUpdatedPrefetchResponseComplete( int HttpCache::Transaction::DoCacheDispatchValidation() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoCacheDispatchValidation", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); if (!entry_) { // Entry got destroyed when twiddling unused-since-prefetch bit. @@ -1705,7 +1737,7 @@ int HttpCache::Transaction::DoCacheDispatchValidation() { int HttpCache::Transaction::DoCacheQueryData() { TransitionToState(STATE_CACHE_QUERY_DATA_COMPLETE); - return entry_->disk_entry->ReadyForSparseIO(io_callback_); + return entry_->GetEntry()->ReadyForSparseIO(io_callback_); } int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { @@ -1726,7 +1758,7 @@ int HttpCache::Transaction::DoStartPartialCacheValidation() { } TransitionToState(STATE_COMPLETE_PARTIAL_CACHE_VALIDATION); - return partial_->ShouldValidateCache(entry_->disk_entry, io_callback_); + return partial_->ShouldValidateCache(entry_->GetEntry(), io_callback_); } int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { @@ -1742,7 +1774,7 @@ int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { return result; } - partial_->PrepareCacheValidation(entry_->disk_entry, + partial_->PrepareCacheValidation(entry_->GetEntry(), &custom_request_->extra_headers); if (reading_ && partial_->IsCurrentRangeCached()) { @@ -1758,7 +1790,7 @@ int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) { int HttpCache::Transaction::DoCacheUpdateStaleWhileRevalidateTimeout() { TRACE_EVENT_WITH_FLOW0( "net", "HttpCacheTransaction::DoCacheUpdateStaleWhileRevalidateTimeout", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); response_.stale_revalidate_timeout = cache_->clock_->Now() + kStaleRevalidateTimeout; @@ -1771,7 +1803,7 @@ int HttpCache::Transaction::DoCacheUpdateStaleWhileRevalidateTimeoutComplete( TRACE_EVENT_WITH_FLOW0( "net", "HttpCacheTransaction::DoCacheUpdateStaleWhileRevalidateTimeoutComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(!reading_); TransitionToState(STATE_CONNECTED_CALLBACK); @@ -1780,7 +1812,7 @@ int HttpCache::Transaction::DoCacheUpdateStaleWhileRevalidateTimeoutComplete( int HttpCache::Transaction::DoSendRequest() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoSendRequest", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(mode_ & WRITE || mode_ == NONE); DCHECK(!network_trans_.get()); @@ -1819,7 +1851,7 @@ int HttpCache::Transaction::DoSendRequest() { int HttpCache::Transaction::DoSendRequestComplete(int result) { TRACE_EVENT_WITH_FLOW1("net", "HttpCacheTransaction::DoSendRequestComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); if (!cache_.get()) { @@ -1867,7 +1899,7 @@ int HttpCache::Transaction::DoSendRequestComplete(int result) { // We received the response headers and there is no error. int HttpCache::Transaction::DoSuccessfulSendRequest() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoSuccessfulSendRequest", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(!new_response_); const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); @@ -1907,7 +1939,7 @@ int HttpCache::Transaction::DoSuccessfulSendRequest() { // The single-keyed cache only accepts responses with code 200 or 304. // Anything else is considered unusable. - if ((effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) && + if (use_single_keyed_cache_ && !(new_response->headers->response_code() == 200 || new_response->headers->response_code() == 304)) { // Either the new response will be written back to the cache, in which case @@ -1994,7 +2026,7 @@ int HttpCache::Transaction::DoSuccessfulSendRequest() { // We received 304 or 206 and we want to update the cached response headers. int HttpCache::Transaction::DoUpdateCachedResponse() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoUpdateCachedResponse", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); int rv = OK; // Update the cached response based on the headers and properties of @@ -2014,15 +2046,11 @@ int HttpCache::Transaction::DoUpdateCachedResponse() { if (mark_single_keyed_cache_entry_unusable_) { response_.single_keyed_cache_entry_unusable = true; } - if (new_response_->vary_data.is_valid()) { - response_.vary_data = new_response_->vary_data; - } else if (response_.vary_data.is_valid()) { - // There is a vary header in the stored response but not in the current one. - // Update the data with the new request headers. - HttpVaryData new_vary_data; - new_vary_data.Init(*request_, *response_.headers.get()); - response_.vary_data = new_vary_data; - } + + // If the new response didn't have a vary header, we continue to use the + // header from the stored response per the effect of headers->Update(). + // Update the data with the new/updated request headers. + response_.vary_data.Init(*request_, *response_.headers); if (ShouldDisableCaching(*response_.headers)) { if (!entry_->doomed) { @@ -2031,7 +2059,7 @@ int HttpCache::Transaction::DoUpdateCachedResponse() { } TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE); } else { - if (effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) { + if (use_single_keyed_cache_) { DCHECK_EQ(method_, "GET"); ChecksumHeaders(); } @@ -2052,7 +2080,7 @@ int HttpCache::Transaction::DoUpdateCachedResponse() { int HttpCache::Transaction::DoCacheWriteUpdatedResponse() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoCacheWriteUpdatedResponse", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); TransitionToState(STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE); return WriteResponseInfoToEntry(response_, false); @@ -2061,7 +2089,7 @@ int HttpCache::Transaction::DoCacheWriteUpdatedResponse() { int HttpCache::Transaction::DoCacheWriteUpdatedResponseComplete(int result) { TRACE_EVENT_WITH_FLOW0( "net", "HttpCacheTransaction::DoCacheWriteUpdatedResponseComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); TransitionToState(STATE_UPDATE_CACHED_RESPONSE_COMPLETE); return OnWriteResponseInfoToEntryComplete(result); @@ -2070,7 +2098,7 @@ int HttpCache::Transaction::DoCacheWriteUpdatedResponseComplete(int result) { int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) { TRACE_EVENT_WITH_FLOW1( "net", "HttpCacheTransaction::DoUpdateCachedResponseComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); if (mode_ == UPDATE) { DCHECK(!handling_206_); @@ -2109,7 +2137,7 @@ int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) { int HttpCache::Transaction::DoOverwriteCachedResponse() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoOverwriteCachedResponse", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); if (mode_ & READ) { TransitionToState(STATE_PARTIAL_HEADERS_RECEIVED); @@ -2122,7 +2150,7 @@ int HttpCache::Transaction::DoOverwriteCachedResponse() { SetResponse(*new_response_); - if (effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) { + if (use_single_keyed_cache_) { DCHECK_EQ(method_, "GET"); ChecksumHeaders(); } @@ -2151,7 +2179,7 @@ int HttpCache::Transaction::DoOverwriteCachedResponse() { int HttpCache::Transaction::DoCacheWriteResponse() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoCacheWriteResponse", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(response_.headers); // Invalidate any current entry with a successful response if this transaction @@ -2187,7 +2215,7 @@ int HttpCache::Transaction::DoCacheWriteResponse() { int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { TRACE_EVENT_WITH_FLOW1( "net", "HttpCacheTransaction::DoCacheWriteResponseComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); TransitionToState(STATE_TRUNCATE_CACHED_DATA); return OnWriteResponseInfoToEntryComplete(result); @@ -2195,14 +2223,14 @@ int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) { int HttpCache::Transaction::DoTruncateCachedData() { TRACE_EVENT_WITH_FLOW0("net", "HttpCacheTransaction::DoTruncateCachedData", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); TransitionToState(STATE_TRUNCATE_CACHED_DATA_COMPLETE); if (!entry_) return OK; net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_WRITE_DATA); // Truncate the stream. - return entry_->disk_entry->WriteData(kResponseContentIndex, /*offset=*/0, + return entry_->GetEntry()->WriteData(kResponseContentIndex, /*offset=*/0, /*buf=*/nullptr, /*buf_len=*/0, io_callback_, /*truncate=*/true); } @@ -2210,7 +2238,7 @@ int HttpCache::Transaction::DoTruncateCachedData() { int HttpCache::Transaction::DoTruncateCachedDataComplete(int result) { TRACE_EVENT_WITH_FLOW1( "net", "HttpCacheTransaction::DoTruncateCachedDataComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); if (entry_) { net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_DATA, @@ -2263,7 +2291,7 @@ int HttpCache::Transaction::DoHeadersPhaseCannotProceed(int result) { int HttpCache::Transaction::DoFinishHeaders(int result) { TRACE_EVENT_WITH_FLOW1( - "net", "HttpCacheTransaction::DoFinishHeaders", net_log().source().id, + "net", "HttpCacheTransaction::DoFinishHeaders", TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); if (!cache_.get() || !entry_ || result != OK) { TransitionToState(STATE_NONE); @@ -2296,7 +2324,7 @@ int HttpCache::Transaction::DoFinishHeaders(int result) { int HttpCache::Transaction::DoFinishHeadersComplete(int rv) { TRACE_EVENT_WITH_FLOW1("net", "HttpCacheTransaction::DoFinishHeadersComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", rv); entry_lock_waiting_since_ = TimeTicks(); @@ -2325,7 +2353,7 @@ int HttpCache::Transaction::DoFinishHeadersComplete(int rv) { int HttpCache::Transaction::DoNetworkReadCacheWrite() { TRACE_EVENT_WITH_FLOW2("net", "HttpCacheTransaction::DoNetworkReadCacheWrite", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "read_offset", read_offset_, "read_buf_len", read_buf_len_); @@ -2337,7 +2365,7 @@ int HttpCache::Transaction::DoNetworkReadCacheWrite() { int HttpCache::Transaction::DoNetworkReadCacheWriteComplete(int result) { TRACE_EVENT_WITH_FLOW1( "net", "HttpCacheTransaction::DoNetworkReadCacheWriteComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); if (!cache_.get()) { TransitionToState(STATE_NONE); @@ -2408,7 +2436,7 @@ int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { int HttpCache::Transaction::DoNetworkRead() { TRACE_EVENT_WITH_FLOW2( - "net", "HttpCacheTransaction::DoNetworkRead", net_log().source().id, + "net", "HttpCacheTransaction::DoNetworkRead", TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "read_offset", read_offset_, "read_buf_len", read_buf_len_); TransitionToState(STATE_NETWORK_READ_COMPLETE); @@ -2417,7 +2445,7 @@ int HttpCache::Transaction::DoNetworkRead() { int HttpCache::Transaction::DoNetworkReadComplete(int result) { TRACE_EVENT_WITH_FLOW1("net", "HttpCacheTransaction::DoNetworkReadComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); @@ -2435,7 +2463,7 @@ int HttpCache::Transaction::DoNetworkReadComplete(int result) { int HttpCache::Transaction::DoCacheReadData() { TRACE_EVENT_WITH_FLOW2( - "net", "HttpCacheTransaction::DoCacheReadData", net_log().source().id, + "net", "HttpCacheTransaction::DoCacheReadData", TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "read_offset", read_offset_, "read_buf_len", read_buf_len_); @@ -2449,18 +2477,18 @@ int HttpCache::Transaction::DoCacheReadData() { net_log_.BeginEvent(NetLogEventType::HTTP_CACHE_READ_DATA); if (partial_) { - return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), + return partial_->CacheRead(entry_->GetEntry(), read_buf_.get(), read_buf_len_, io_callback_); } - return entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, + return entry_->GetEntry()->ReadData(kResponseContentIndex, read_offset_, read_buf_.get(), read_buf_len_, io_callback_); } int HttpCache::Transaction::DoCacheReadDataComplete(int result) { TRACE_EVENT_WITH_FLOW1("net", "HttpCacheTransaction::DoCacheReadDataComplete", - net_log().source().id, + TRACE_ID_LOCAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result", result); net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_READ_DATA, @@ -2498,7 +2526,7 @@ int HttpCache::Transaction::DoCacheReadDataComplete(int result) { } int HttpCache::Transaction::DoMarkSingleKeyedCacheEntryUnusable() { - DCHECK(effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE); + DCHECK(use_single_keyed_cache_); response_.single_keyed_cache_entry_unusable = true; TransitionToState(STATE_MARK_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE_COMPLETE); return WriteResponseInfoToEntry(response_, /*truncated=*/false); @@ -2534,6 +2562,9 @@ void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log) { effective_load_flags_ = request_->load_flags; method_ = request_->method; + if (!request_->checksum.empty()) + use_single_keyed_cache_ = true; + if (cache_->mode() == DISABLE) effective_load_flags_ |= LOAD_DISABLE_CACHE; @@ -2562,9 +2593,9 @@ void HttpCache::Transaction::SetRequest(const NetLogWithSource& net_log) { if (request_->extra_headers.HasHeader(HttpRequestHeaders::kRange)) range_found = true; - for (size_t i = 0; i < std::size(kSpecialHeaders); ++i) { - if (HeaderMatches(request_->extra_headers, kSpecialHeaders[i].search)) { - effective_load_flags_ |= kSpecialHeaders[i].load_flag; + for (const auto& special_header : kSpecialHeaders) { + if (HeaderMatches(request_->extra_headers, special_header.search)) { + effective_load_flags_ |= special_header.load_flag; special_headers = true; break; } @@ -2821,9 +2852,9 @@ int HttpCache::Transaction::BeginPartialCacheValidation() { int HttpCache::Transaction::ValidateEntryHeadersAndContinue() { DCHECK_EQ(mode_, READ_WRITE); - if (!partial_->UpdateFromStoredHeaders(response_.headers.get(), - entry_->disk_entry, truncated_, - cache_->IsWritingInProgress(entry_))) { + if (!partial_->UpdateFromStoredHeaders( + response_.headers.get(), entry_->GetEntry(), truncated_, + cache_->IsWritingInProgress(entry()))) { return DoRestartPartialRequest(); } @@ -3273,6 +3304,15 @@ int HttpCache::Transaction::DoConnectedCallback() { int HttpCache::Transaction::DoConnectedCallbackComplete(int result) { if (result != OK) { + if (result == + ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY) { + DoomInconsistentEntry(); + UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); + TransitionToState(reading_ ? STATE_SEND_REQUEST + : STATE_HEADERS_PHASE_CANNOT_PROCEED); + return OK; + } + if (result == ERR_INCONSISTENT_IP_ADDRESS_SPACE) { DoomInconsistentEntry(); } else { @@ -3392,7 +3432,7 @@ int HttpCache::Transaction::WriteResponseInfoToEntry( // When writing headers, we normally only write the non-transient headers. bool skip_transient_headers = true; - scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); + auto data = base::MakeRefCounted<PickledIOBuffer>(); response.Persist(data->pickle(), skip_transient_headers, truncated); data->Done(); @@ -3618,7 +3658,7 @@ HttpTransaction* HttpCache::Transaction::network_transaction() { // bool HttpCache::Transaction::CanResume(bool has_data) { // Double check that there is something worth keeping. - if (has_data && !entry_->disk_entry->GetDataSize(kResponseContentIndex)) + if (has_data && !entry_->GetEntry()->GetDataSize(kResponseContentIndex)) return false; if (method_ != "GET") @@ -3637,6 +3677,12 @@ bool HttpCache::Transaction::CanResume(bool has_data) { void HttpCache::Transaction::SetResponse(const HttpResponseInfo& response) { response_ = response; + + if (response_.headers) { + DCHECK(request_); + response_.vary_data.Init(*request_, *response_.headers); + } + SyncCacheEntryStatusToResponse(); } @@ -3912,7 +3958,7 @@ void HttpCache::Transaction::UpdateSecurityHeadersBeforeForwarding() { } void HttpCache::Transaction::ChecksumHeaders() { - DCHECK(effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE); + DCHECK(use_single_keyed_cache_); DCHECK(!checksum_); checksum_ = crypto::SecureHash::Create(crypto::SecureHash::SHA256); // For efficiency and concision, we list known headers matching a wildcard @@ -3933,7 +3979,7 @@ void HttpCache::Transaction::ChecksumHeaders() { "cross-origin-embedder-policy", "cross-origin-opener-policy", "cross-origin-resource-policy", - "location" + "location", "sec-websocket-accept", "sec-websocket-extensions", "sec-websocket-key", @@ -3942,20 +3988,22 @@ void HttpCache::Transaction::ChecksumHeaders() { "upgrade", "vary", }); - // Iterate the response headers looking for matches. - size_t iter = 0; - std::string name; - std::string value; // Pairs of (lower_case_header_name, header_value). std::vector<std::pair<std::string, std::string>> filtered_headers; // It's good to set the initial allocation size of the vector to the // expected size to avoid a lot of reallocations. This value was chosen as // it is a nice round number. filtered_headers.reserve(16); - while (response_.headers->EnumerateHeaderLines(&iter, &name, &value)) { - std::string lowered_name = base::ToLowerASCII(name); - if (kHeadersToInclude.contains(lowered_name)) { - filtered_headers.emplace_back(lowered_name, value); + { + // Iterate the response headers looking for matches. + size_t iter = 0; + std::string name; + std::string value; + while (response_.headers->EnumerateHeaderLines(&iter, &name, &value)) { + std::string lowered_name = base::ToLowerASCII(name); + if (kHeadersToInclude.contains(lowered_name)) { + filtered_headers.emplace_back(lowered_name, value); + } } } std::sort(filtered_headers.begin(), filtered_headers.end()); @@ -3972,7 +4020,7 @@ bool HttpCache::Transaction::FinishAndCheckChecksum() { if (!checksum_) return true; - DCHECK(effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE); + DCHECK(use_single_keyed_cache_); return ResponseChecksumMatches(std::move(checksum_)); } diff --git a/chromium/net/http/http_cache_transaction.h b/chromium/net/http/http_cache_transaction.h index 88ed80876e4..0a937a3b13e 100644 --- a/chromium/net/http/http_cache_transaction.h +++ b/chromium/net/http/http_cache_transaction.h @@ -610,21 +610,28 @@ class NET_EXPORT_PRIVATE HttpCache::Transaction : public HttpTransaction { State next_state_{STATE_NONE}; + // Used for tracing. + const uint64_t trace_id_; + // Initial request with which Start() was invoked. raw_ptr<const HttpRequestInfo> initial_request_ = nullptr; + // `custom_request_` is assigned to `request_` after allocation. It must be + // declared before `request_` so that it will be destroyed afterwards to + // prevent that pointer from dangling. + std::unique_ptr<HttpRequestInfo> custom_request_; + raw_ptr<const HttpRequestInfo> request_ = nullptr; std::string method_; RequestPriority priority_; NetLogWithSource net_log_; - std::unique_ptr<HttpRequestInfo> custom_request_; HttpRequestHeaders request_headers_copy_; // If extra_headers specified a "if-modified-since" or "if-none-match", // |external_validation_| contains the value of those headers. ValidationHeaders external_validation_; base::WeakPtr<HttpCache> cache_; - raw_ptr<HttpCache::ActiveEntry> entry_ = nullptr; + raw_ptr<HttpCache::ActiveEntry, DanglingUntriaged> entry_ = nullptr; HttpCache::ActiveEntry* new_entry_ = nullptr; std::unique_ptr<HttpTransaction> network_trans_; CompletionOnceCallback callback_; // Consumer's callback. @@ -640,7 +647,7 @@ class NET_EXPORT_PRIVATE HttpCache::Transaction : public HttpTransaction { // WriteResponseInfoToEntry() resets this to absl::nullopt. std::unique_ptr<HttpResponseInfo> updated_prefetch_response_; - raw_ptr<const HttpResponseInfo> new_response_ = nullptr; + raw_ptr<const HttpResponseInfo, DanglingUntriaged> new_response_ = nullptr; std::string cache_key_; Mode mode_ = NONE; bool reading_ = false; // We are already reading. Never reverts to @@ -666,6 +673,8 @@ class NET_EXPORT_PRIVATE HttpCache::Transaction : public HttpTransaction { false; // Fail ConditionalizeRequest. bool mark_single_keyed_cache_entry_unusable_ = false; // Set single_keyed_cache_entry_unusable. + // This is initialised in Start(). + bool use_single_keyed_cache_ = false; scoped_refptr<IOBuffer> read_buf_; diff --git a/chromium/net/http/http_cache_unittest.cc b/chromium/net/http/http_cache_unittest.cc index 09f1f94f4a6..931e1322fc7 100644 --- a/chromium/net/http/http_cache_unittest.cc +++ b/chromium/net/http/http_cache_unittest.cc @@ -174,8 +174,8 @@ void DeferCallback(bool* defer) { class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { public: - explicit DeleteCacheCompletionCallback(MockHttpCache* cache) - : cache_(cache) {} + explicit DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache) + : cache_(std::move(cache)) {} DeleteCacheCompletionCallback(const DeleteCacheCompletionCallback&) = delete; DeleteCacheCompletionCallback& operator=( @@ -188,11 +188,11 @@ class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { private: void OnComplete(int result) { - delete cache_; + cache_.reset(); SetResult(result); } - raw_ptr<MockHttpCache> cache_; + std::unique_ptr<MockHttpCache> cache_; }; //----------------------------------------------------------------------------- @@ -772,7 +772,7 @@ std::string GenerateCacheKey(const std::string& url) { using HttpCacheTest = TestWithTaskEnvironment; class HttpCacheIOCallbackTest : public HttpCacheTest { public: - HttpCacheIOCallbackTest() {} + HttpCacheIOCallbackTest() = default; ~HttpCacheIOCallbackTest() override = default; // HttpCache::ActiveEntry is private, doing this allows tests to use it @@ -814,7 +814,7 @@ class HttpCacheIOCallbackTest : public HttpCacheTest { class HttpSplitCacheKeyTest : public HttpCacheTest { public: - HttpSplitCacheKeyTest() {} + HttpSplitCacheKeyTest() = default; ~HttpSplitCacheKeyTest() override = default; std::string ComputeCacheKey(const std::string& url_string) { @@ -825,7 +825,7 @@ class HttpSplitCacheKeyTest : public HttpCacheTest { request_info.method = "GET"; request_info.network_isolation_key = net::NetworkIsolationKey(site, site); MockHttpCache cache; - return cache.http_cache()->GenerateCacheKeyForTest(&request_info); + return *cache.http_cache()->GenerateCacheKeyForRequest(&request_info); } }; @@ -1075,6 +1075,73 @@ TEST_F(HttpCacheTest, } } +// This test verifies that when the callback passed to SetConnectedCallback() +// returns +// `ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY`, the +// cache entry is invalidated, and we'll retry the connection from the network. +TEST_F( + HttpCacheTest, + SimpleGET_ConnectedCallbackOnCacheHitReturnPrivateNetworkAccessBlockedError) { + MockHttpCache cache; + + ScopedMockTransaction mock_transaction(kSimpleGET_Transaction); + mock_transaction.transport_info = TestTransportInfo(); + + // Populate the cache. + RunTransactionTest(cache.http_cache(), mock_transaction); + + MockHttpRequest request(kSimpleGET_Transaction); + + { + // Attempt to read from cache entry, but abort transaction due to a + // connected callback error. + ConnectedHandler connected_handler; + connected_handler.set_result( + ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY); + + std::unique_ptr<HttpTransaction> transaction; + EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk()); + ASSERT_THAT(transaction, NotNull()); + + transaction->SetConnectedCallback(connected_handler.Callback()); + + TestCompletionCallback callback; + ASSERT_THAT( + transaction->Start(&request, callback.callback(), NetLogWithSource()), + IsError(ERR_IO_PENDING)); + EXPECT_THAT( + callback.WaitForResult(), + IsError( + ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY)); + + // Used the cache entry only. + EXPECT_THAT(connected_handler.transports(), + ElementsAre(CachedTestTransportInfo(), TestTransportInfo())); + } + + { + // Request the same resource once more, observe that it is not read from + // cache. + ConnectedHandler connected_handler; + + std::unique_ptr<HttpTransaction> transaction; + EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk()); + ASSERT_THAT(transaction, NotNull()); + + transaction->SetConnectedCallback(connected_handler.Callback()); + + TestCompletionCallback callback; + ASSERT_THAT( + transaction->Start(&request, callback.callback(), NetLogWithSource()), + IsError(ERR_IO_PENDING)); + EXPECT_THAT(callback.WaitForResult(), IsOk()); + + // Used the network only. + EXPECT_THAT(connected_handler.transports(), + ElementsAre(TestTransportInfo())); + } +} + // This test verifies that the callback passed to SetConnectedCallback() is // called with the right transport type when the cached entry was originally // fetched via proxy. @@ -3804,12 +3871,11 @@ TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch1) { EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); } - for (size_t i = 0; i < context_list.size(); i++) { - if (context_list[i]->result == ERR_IO_PENDING) - context_list[i]->result = context_list[i]->callback.WaitForResult(); + for (auto& context : context_list) { + if (context->result == ERR_IO_PENDING) + context->result = context->callback.WaitForResult(); - ReadAndVerifyTransaction(context_list[i]->trans.get(), - kSimpleGET_Transaction); + ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); } EXPECT_EQ(2, cache.network_layer()->transaction_count()); @@ -5336,7 +5402,8 @@ TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelFirst) { // Allow all requests to move from the Create queue to the active entry. // All would have been added to writers. base::RunLoop().RunUntilIdle(); - std::string cache_key = cache.http_cache()->GenerateCacheKeyForTest(&request); + std::string cache_key = + *cache.http_cache()->GenerateCacheKeyForRequest(&request); EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key)); // The second transaction skipped validation, thus only one network @@ -5601,8 +5668,9 @@ TEST_F(HttpCacheTest, SimpleGET_ManyWriters_DeleteCache) { // Tests that we queue requests when initializing the backend. TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) { - MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); - MockHttpCache cache(base::WrapUnique(factory)); + auto factory = std::make_unique<MockBlockingBackendFactory>(); + MockBlockingBackendFactory* factory_ptr = factory.get(); + MockHttpCache cache(std::move(factory)); MockHttpRequest request0(kSimpleGET_Transaction); MockHttpRequest request1(kTypicalGET_Transaction); @@ -5632,7 +5700,7 @@ TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) { // The first request should be creating the disk cache. EXPECT_FALSE(context_list[0]->callback.have_result()); - factory->FinishCreation(); + factory_ptr->FinishCreation(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(3, cache.network_layer()->transaction_count()); @@ -5647,8 +5715,9 @@ TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) { // Tests that we can cancel requests that are queued waiting for the backend // to be initialized. TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) { - MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); - MockHttpCache cache(base::WrapUnique(factory)); + auto factory = std::make_unique<MockBlockingBackendFactory>(); + MockBlockingBackendFactory* factory_ptr = factory.get(); + MockHttpCache cache(std::move(factory)); MockHttpRequest request0(kSimpleGET_Transaction); MockHttpRequest request1(kTypicalGET_Transaction); @@ -5685,7 +5754,7 @@ TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) { context_list[0].reset(); // Complete the last transaction. - factory->FinishCreation(); + factory_ptr->FinishCreation(); context_list[2]->result = context_list[2]->callback.GetResult(context_list[2]->result); @@ -5695,10 +5764,11 @@ TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) { EXPECT_EQ(1, cache.disk_cache()->create_count()); } -// Tests that we can delete the cache while creating the backend. +// Tests that we can delete the HttpCache while creating the backend. TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend) { - MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); - auto cache = std::make_unique<MockHttpCache>(base::WrapUnique(factory)); + auto factory = std::make_unique<MockBlockingBackendFactory>(); + MockBlockingBackendFactory* factory_ptr = factory.get(); + auto cache = std::make_unique<MockHttpCache>(std::move(factory)); MockHttpRequest request(kSimpleGET_Transaction); @@ -5714,45 +5784,43 @@ TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend) { // The request should be creating the disk cache. EXPECT_FALSE(c->callback.have_result()); - // We cannot call FinishCreation because the factory itself will go away with - // the cache. - CompletionOnceCallback callback = factory->ReleaseCallback(); - std::unique_ptr<disk_cache::Backend>* backend = factory->backend(); + // Manually arrange for completion to happen after ~HttpCache. + // This can't be done via FinishCreation() since that's in `factory`, and + // that's owned by `cache`. + disk_cache::BackendResultCallback callback = factory_ptr->ReleaseCallback(); cache.reset(); base::RunLoop().RunUntilIdle(); - // Even though |HttpCache| is destroyed, the Backend that was passed in to - // disk_cache::CreateCacheBackend() must still be valid until the callback is - // called. - backend->reset(); - // |callback| will destroy |backend|. - std::move(callback).Run(ERR_ABORTED); + // Simulate the backend completion callback running now the HttpCache is gone. + std::move(callback).Run(disk_cache::BackendResult::MakeError(ERR_ABORTED)); } // Tests that we can delete the cache while creating the backend, from within // one of the callbacks. TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend2) { - MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); - MockHttpCache* cache = new MockHttpCache(base::WrapUnique(factory)); + auto factory = std::make_unique<MockBlockingBackendFactory>(); + MockBlockingBackendFactory* factory_ptr = factory.get(); + auto cache = std::make_unique<MockHttpCache>(std::move(factory)); + auto* cache_ptr = cache.get(); - DeleteCacheCompletionCallback cb(cache); + DeleteCacheCompletionCallback cb(std::move(cache)); disk_cache::Backend* backend; - int rv = cache->http_cache()->GetBackend(&backend, cb.callback()); + int rv = cache_ptr->http_cache()->GetBackend(&backend, cb.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Now let's queue a regular transaction MockHttpRequest request(kSimpleGET_Transaction); auto c = std::make_unique<Context>(); - c->result = cache->CreateTransaction(&c->trans); + c->result = cache_ptr->CreateTransaction(&c->trans); ASSERT_THAT(c->result, IsOk()); c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); // And another direct backend request. TestCompletionCallback cb2; - rv = cache->http_cache()->GetBackend(&backend, cb2.callback()); + rv = cache_ptr->http_cache()->GetBackend(&backend, cb2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Just to make sure that everything is still pending. @@ -5762,7 +5830,7 @@ TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend2) { EXPECT_FALSE(c->callback.have_result()); // Generate the callback. - factory->FinishCreation(); + factory_ptr->FinishCreation(); rv = cb.WaitForResult(); // The cache should be gone by now. @@ -8309,7 +8377,8 @@ TEST_F(HttpCacheTest, Sparse_WaitForEntry) { // Simulate a previous transaction being cancelled. disk_cache::Entry* entry; MockHttpRequest request(transaction); - std::string cache_key = cache.http_cache()->GenerateCacheKeyForTest(&request); + std::string cache_key = + *cache.http_cache()->GenerateCacheKeyForRequest(&request); ASSERT_TRUE(cache.OpenBackendEntry(cache_key, &entry)); entry->CancelSparseIO(); @@ -9737,7 +9806,8 @@ TEST_F(HttpCacheTest, PersistHttpResponseInfo) { HttpResponseInfo response1; response1.was_cached = false; response1.remote_endpoint = expected_endpoint; - response1.headers = new HttpResponseHeaders("HTTP/1.1 200 OK"); + response1.headers = + base::MakeRefCounted<HttpResponseHeaders>("HTTP/1.1 200 OK"); // Pickle. base::Pickle pickle; @@ -10916,7 +10986,7 @@ TEST_F(HttpCacheTest, SplitCacheWithNetworkIsolationKey) { // Now make a request with an opaque subframe site. It shouldn't be // cached. trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_data); - EXPECT_TRUE(trans_info.network_isolation_key.ToString().empty()); + EXPECT_EQ(absl::nullopt, trans_info.network_isolation_key.ToCacheKeyString()); RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, trans_info, &response); EXPECT_FALSE(response.was_cached); @@ -11140,7 +11210,7 @@ TEST_F(HttpCacheTest, SplitCache) { // Now make a request with an opaque top frame origin. It shouldn't be // cached. trans_info.network_isolation_key = NetworkIsolationKey(site_data, site_data); - EXPECT_TRUE(trans_info.network_isolation_key.ToString().empty()); + EXPECT_EQ(absl::nullopt, trans_info.network_isolation_key.ToCacheKeyString()); RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction, trans_info, &response); EXPECT_FALSE(response.was_cached); @@ -11811,7 +11881,7 @@ HttpCacheHugeResourceTest::GetTestModes() { for (const auto phase : kTransactionPhases) for (const auto initializer : kInitializers) - test_modes.push_back(std::make_pair(phase, initializer)); + test_modes.emplace_back(phase, initializer); return test_modes; } @@ -12754,7 +12824,7 @@ TEST_F(HttpCacheTest, GetResourceURLFromHttpCacheKey) { class TestCompletionCallbackForHttpCache : public TestCompletionCallbackBase { public: - TestCompletionCallbackForHttpCache() {} + TestCompletionCallbackForHttpCache() = default; ~TestCompletionCallbackForHttpCache() override = default; CompletionRepeatingCallback callback() { @@ -13516,10 +13586,8 @@ class HttpCacheSingleKeyedCacheTest : public HttpCacheTest { const MockTransaction& trans_info, const NetworkIsolationKey& network_isolation_key, const std::string& checksum) { - MockTransaction transaction(trans_info); - transaction.load_flags |= LOAD_USE_SINGLE_KEYED_CACHE; + ScopedMockTransaction transaction(trans_info); - AddMockTransaction(&transaction); MockHttpRequest request(transaction); request.network_isolation_key = network_isolation_key; request.checksum = checksum; @@ -13640,6 +13708,38 @@ TEST_F(HttpCacheSingleKeyedCacheTest, GETWithBadResponseCode) { } } +// This is identical to GETWithBadResponseCode but with a different response +// code. It's not very realistic as it doesn't call DoneReading(), but it covers +// the relevant code path. +TEST_F(HttpCacheSingleKeyedCacheTest, RedirectUnusable) { + MockHttpCache cache; + MockTransaction transaction = kSimpleGET_Transaction; + transaction.status = "HTTP/1.1 301 Moved Permanently"; + const auto site_a = SchemefulSite(GURL("https://a.com/")); + // The first request adds the item to the single-keyed cache. + { + RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction, + NetworkIsolationKey(site_a, site_a), + kChecksumForSimpleGET); + + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + } + + // The second request verifies that the cache entry is not re-used + // but a new one is created in the split cache. + { + RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction, + NetworkIsolationKey(site_a, site_a), + kChecksumForSimpleGET); + + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, cache.disk_cache()->open_count()); + EXPECT_EQ(2, cache.disk_cache()->create_count()); + } +} + TEST_F(HttpCacheSingleKeyedCacheTest, SuccessfulRevalidation) { MockHttpCache cache; MockTransaction transaction = kSimpleGET_Transaction; diff --git a/chromium/net/http/http_cache_writers.cc b/chromium/net/http/http_cache_writers.cc index 9a9b3b9647a..76b70c258b5 100644 --- a/chromium/net/http/http_cache_writers.cc +++ b/chromium/net/http/http_cache_writers.cc @@ -81,7 +81,9 @@ int HttpCache::Writers::Read(scoped_refptr<IOBuffer> buf, CompletionOnceCallback callback, Transaction* transaction) { DCHECK(buf); - DCHECK_GT(buf_len, 0); + // TODO(https://crbug.com/1335423): Change to DCHECK_GT() or remove after bug + // is fixed. + CHECK_GT(buf_len, 0); DCHECK(!callback.is_null()); DCHECK(transaction); @@ -279,8 +281,7 @@ void HttpCache::Writers::ProcessFailure(int error) { void HttpCache::Writers::TruncateEntry() { DCHECK(ShouldTruncate()); - - scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); + auto data = base::MakeRefCounted<PickledIOBuffer>(); response_info_truncation_.Persist(data->pickle(), true /* skip_transient_headers*/, true /* response_truncated */); @@ -496,7 +497,7 @@ int HttpCache::Writers::DoCacheWriteData(int num_bytes) { read_buf_.get(), num_bytes, std::move(io_callback), true); } else { - rv = partial->CacheWrite(entry_->disk_entry, read_buf_.get(), num_bytes, + rv = partial->CacheWrite(entry_->GetEntry(), read_buf_.get(), num_bytes, std::move(io_callback)); } return rv; @@ -504,32 +505,38 @@ int HttpCache::Writers::DoCacheWriteData(int num_bytes) { int HttpCache::Writers::DoCacheWriteDataComplete(int result) { DCHECK(!all_writers_.empty()); - next_state_ = State::NONE; + DCHECK_GE(write_len_, 0); + + if (result != write_len_) { + next_state_ = State::NONE; + + // Note that it is possible for cache write to fail if the size of the file + // exceeds the per-file limit. + OnCacheWriteFailure(); + + // |active_transaction_| can continue reading from the network. + return write_len_; + } + if (checksum_) { if (write_len_ > 0) { checksum_->Update(read_buf_->data(), write_len_); } else { - // The write to the cache may have failed if result < 0, but even in that - // case we want to check whether the data we've read from the network is - // valid or not. CHECK(active_transaction_); if (!active_transaction_->ResponseChecksumMatches(std::move(checksum_))) { next_state_ = State::MARK_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE; + return result; } } } - if (result != write_len_) { - // Note that it is possible for cache write to fail if the size of the file - // exceeds the per-file limit. - OnCacheWriteFailure(); + next_state_ = State::NONE; + OnDataReceived(write_len_); - // |active_transaction_| can continue reading from the network. - result = write_len_; - } else { - OnDataReceived(result); - } - return result; + // If we came from DoMarkSingleKeyedCacheUnusableComplete() then result will + // be the size of the metadata that was written. But DoLoop() needs to know + // the number of bytes of data that were written. So return that instead. + return write_len_; } int HttpCache::Writers::DoMarkSingleKeyedCacheEntryUnusable() { @@ -555,15 +562,11 @@ int HttpCache::Writers::DoMarkSingleKeyedCacheEntryUnusable() { int HttpCache::Writers::DoMarkSingleKeyedCacheEntryUnusableComplete( int result) { - next_state_ = State::NONE; - - if (result < 0) { - OnCacheWriteFailure(); - } - - // DoLoop() wants the size of the data write, not the size of the metadata - // write. - return write_len_; + DCHECK(!checksum_); + // We run DoCacheWriteDataComplete again, but this time `checksum_` is null so + // we won't come back here. + next_state_ = State::CACHE_WRITE_DATA_COMPLETE; + return result < 0 ? result : write_len_; } void HttpCache::Writers::OnDataReceived(int result) { @@ -607,6 +610,8 @@ void HttpCache::Writers::OnDataReceived(int result) { make_readers.insert(writer.first); all_writers_.clear(); SetCacheCallback(true, make_readers); + // We assume the set callback will be called immediately. + DCHECK_EQ(next_state_, State::NONE); return; } diff --git a/chromium/net/http/http_chunked_decoder_unittest.cc b/chromium/net/http/http_chunked_decoder_unittest.cc index 4dbefb346f1..f3a34c1ba91 100644 --- a/chromium/net/http/http_chunked_decoder_unittest.cc +++ b/chromium/net/http/http_chunked_decoder_unittest.cc @@ -397,7 +397,7 @@ TEST(HttpChunkedDecoderTest, MultipleExtraDataBlocks) { // Test when the line with the chunk length is too long. TEST(HttpChunkedDecoderTest, LongChunkLengthLine) { int big_chunk_length = HttpChunkedDecoder::kMaxLineBufLen; - std::unique_ptr<char[]> big_chunk(new char[big_chunk_length + 1]); + auto big_chunk = std::make_unique<char[]>(big_chunk_length + 1); memset(big_chunk.get(), '0', big_chunk_length); big_chunk[big_chunk_length] = 0; const char* const inputs[] = { @@ -411,7 +411,7 @@ TEST(HttpChunkedDecoderTest, LongChunkLengthLine) { // long. TEST(HttpChunkedDecoderTest, LongLengthLengthLine) { int big_chunk_length = HttpChunkedDecoder::kMaxLineBufLen; - std::unique_ptr<char[]> big_chunk(new char[big_chunk_length + 1]); + auto big_chunk = std::make_unique<char[]>(big_chunk_length + 1); memset(big_chunk.get(), '0', big_chunk_length); big_chunk[big_chunk_length] = 0; const char* const inputs[] = { diff --git a/chromium/net/http/http_content_disposition_unittest.cc b/chromium/net/http/http_content_disposition_unittest.cc index 2e3dfb25e82..d526dbfc716 100644 --- a/chromium/net/http/http_content_disposition_unittest.cc +++ b/chromium/net/http/http_content_disposition_unittest.cc @@ -201,11 +201,10 @@ TEST(HttpContentDispositionTest, Filename) { {"attachment; foobar=x; filename=\"foo.html\"", "", L"foo.html"}, }; - for (size_t i = 0; i < std::size(tests); ++i) { - HttpContentDisposition header(tests[i].header, tests[i].referrer_charset); - EXPECT_EQ(tests[i].expected, - base::UTF8ToWide(header.filename())) - << "Failed on input: " << tests[i].header; + for (const auto& test : tests) { + HttpContentDisposition header(test.header, test.referrer_charset); + EXPECT_EQ(test.expected, base::UTF8ToWide(header.filename())) + << "Failed on input: " << test.header; } } @@ -414,12 +413,12 @@ TEST(HttpContentDispositionTest, tc2231) { // TODO(abarth): http://greenbytes.de/tech/tc2231/#attrfc2047token // TODO(abarth): http://greenbytes.de/tech/tc2231/#attrfc2047quoted }; - for (size_t i = 0; i < std::size(tests); ++i) { - HttpContentDisposition header(tests[i].header, std::string()); - EXPECT_EQ(tests[i].expected_type, header.type()) - << "Failed on input: " << tests[i].header; - EXPECT_EQ(tests[i].expected_filename, base::UTF8ToWide(header.filename())) - << "Failed on input: " << tests[i].header; + for (const auto& test : tests) { + HttpContentDisposition header(test.header, std::string()); + EXPECT_EQ(test.expected_type, header.type()) + << "Failed on input: " << test.header; + EXPECT_EQ(test.expected_filename, base::UTF8ToWide(header.filename())) + << "Failed on input: " << test.header; } } diff --git a/chromium/net/http/http_network_session.cc b/chromium/net/http/http_network_session.cc index 457bb677150..e90b6c1c30b 100644 --- a/chromium/net/http/http_network_session.cc +++ b/chromium/net/http/http_network_session.cc @@ -72,6 +72,10 @@ spdy::SettingsMap AddDefaultHttp2Settings(spdy::SettingsMap http2_settings) { http2_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] = kSpdyMaxHeaderListSize; + it = http2_settings.find(spdy::SETTINGS_ENABLE_PUSH); + if (it == http2_settings.end()) + http2_settings[spdy::SETTINGS_ENABLE_PUSH] = kSpdyDisablePush; + return http2_settings; } @@ -83,6 +87,8 @@ HttpNetworkSessionParams::HttpNetworkSessionParams() time_func(&base::TimeTicks::Now) { enable_early_data = base::FeatureList::IsEnabled(features::kEnableTLS13EarlyData); + use_dns_https_svcb_alpn = + base::FeatureList::IsEnabled(features::kUseDnsHttpsSvcbAlpn); } HttpNetworkSessionParams::HttpNetworkSessionParams( @@ -228,18 +234,19 @@ HttpNetworkSession::~HttpNetworkSession() { spdy_session_pool_.CloseAllSessions(); } -void HttpNetworkSession::AddResponseDrainer( +void HttpNetworkSession::StartResponseDrainer( std::unique_ptr<HttpResponseBodyDrainer> drainer) { DCHECK(!base::Contains(response_drainers_, drainer.get())); HttpResponseBodyDrainer* drainer_ptr = drainer.get(); - response_drainers_[drainer_ptr] = std::move(drainer); + response_drainers_.insert(std::move(drainer)); + drainer_ptr->Start(this); } void HttpNetworkSession::RemoveResponseDrainer( HttpResponseBodyDrainer* drainer) { DCHECK(base::Contains(response_drainers_, drainer)); - response_drainers_[drainer].release(); - response_drainers_.erase(drainer); + + response_drainers_.erase(response_drainers_.find(drainer)); } ClientSocketPool* HttpNetworkSession::GetSocketPool( diff --git a/chromium/net/http/http_network_session.h b/chromium/net/http/http_network_session.h index e963d52b9dd..e447de32fc9 100644 --- a/chromium/net/http/http_network_session.h +++ b/chromium/net/http/http_network_session.h @@ -17,6 +17,7 @@ #include "base/bind.h" #include "base/containers/flat_set.h" +#include "base/containers/unique_ptr_adapters.h" #include "base/memory/memory_pressure_monitor.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" @@ -82,8 +83,11 @@ const uint32_t kSpdyMaxHeaderListSize = 256 * 1024; // Specifies the maximum concurrent streams server could send (via push). const uint32_t kSpdyMaxConcurrentPushedStreams = 1000; - // Self-contained structure with all the simple configuration options - // supported by the HttpNetworkSession. +// Specifies the the default value for the push setting, which is disabled. +const uint32_t kSpdyDisablePush = 0; + +// Self-contained structure with all the simple configuration options +// supported by the HttpNetworkSession. struct NET_EXPORT HttpNetworkSessionParams { HttpNetworkSessionParams(); HttpNetworkSessionParams(const HttpNetworkSessionParams& other); @@ -178,6 +182,9 @@ struct NET_EXPORT HttpNetworkSessionParams { // default network does (hence underlying objects should not drop their // state). bool ignore_ip_address_changes = false; + + // Whether to use the ALPN information in the DNS HTTPS record. + bool use_dns_https_svcb_alpn = false; }; // Structure with pointers to the dependencies of the HttpNetworkSession. @@ -204,8 +211,9 @@ struct NET_EXPORT HttpNetworkSessionContext { raw_ptr<NetworkQualityEstimator> network_quality_estimator; raw_ptr<QuicContext> quic_context; #if BUILDFLAG(ENABLE_REPORTING) - raw_ptr<ReportingService> reporting_service; - raw_ptr<NetworkErrorLoggingService> network_error_logging_service; + raw_ptr<ReportingService, DanglingUntriaged> reporting_service; + raw_ptr<NetworkErrorLoggingService, DanglingUntriaged> + network_error_logging_service; #endif // Optional factory to use for creating QuicCryptoClientStreams. @@ -228,9 +236,9 @@ class NET_EXPORT HttpNetworkSession { HttpAuthCache* http_auth_cache() { return &http_auth_cache_; } SSLClientContext* ssl_client_context() { return &ssl_client_context_; } - void AddResponseDrainer(std::unique_ptr<HttpResponseBodyDrainer> drainer); + void StartResponseDrainer(std::unique_ptr<HttpResponseBodyDrainer> drainer); - // Removes the drainer from the session. Does not dispose of it. + // Removes the drainer from the session. void RemoveResponseDrainer(HttpResponseBodyDrainer* drainer); // Returns the socket pool of the given type for use with the specified @@ -330,8 +338,9 @@ class NET_EXPORT HttpNetworkSession { const raw_ptr<HostResolver> host_resolver_; #if BUILDFLAG(ENABLE_REPORTING) - const raw_ptr<ReportingService> reporting_service_; - const raw_ptr<NetworkErrorLoggingService> network_error_logging_service_; + const raw_ptr<ReportingService, DanglingUntriaged> reporting_service_; + const raw_ptr<NetworkErrorLoggingService, DanglingUntriaged> + network_error_logging_service_; #endif const raw_ptr<ProxyResolutionService> proxy_resolution_service_; const raw_ptr<SSLConfigService> ssl_config_service_; @@ -346,7 +355,7 @@ class NET_EXPORT HttpNetworkSession { QuicStreamFactory quic_stream_factory_; SpdySessionPool spdy_session_pool_; std::unique_ptr<HttpStreamFactory> http_stream_factory_; - std::map<HttpResponseBodyDrainer*, std::unique_ptr<HttpResponseBodyDrainer>> + std::set<std::unique_ptr<HttpResponseBodyDrainer>, base::UniquePtrComparator> response_drainers_; NextProtoVector next_protos_; SSLConfig::ApplicationSettings application_settings_; diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc index 5f530c81fcc..180daca912d 100644 --- a/chromium/net/http/http_network_transaction.cc +++ b/chromium/net/http/http_network_transaction.cc @@ -338,7 +338,7 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { if (stream_.get()) { total_received_bytes_ += stream_->GetTotalReceivedBytes(); total_sent_bytes_ += stream_->GetTotalSentBytes(); - HttpStream* new_stream = nullptr; + std::unique_ptr<HttpStream> new_stream; if (keep_alive && stream_->CanReuseConnection()) { // We should call connection_->set_idle_time(), but this doesn't occur // often enough to be worth the trouble. @@ -358,7 +358,7 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { DCHECK_EQ(0, new_stream->GetTotalSentBytes()); next_state_ = STATE_CONNECTED_CALLBACK; } - stream_.reset(new_stream); + stream_ = std::move(new_stream); } // Reset the other member variables. @@ -1203,13 +1203,18 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { // Unless this is a WebSocket request, in which case we pass it on up. if (response_.headers->response_code() / 100 == 1 && !ForWebSocketHandshake()) { - response_.headers = new HttpResponseHeaders(std::string()); + response_.headers = + base::MakeRefCounted<HttpResponseHeaders>(std::string()); next_state_ = STATE_READ_HEADERS; return OK; } + const bool has_body_with_null_source = + request_->upload_data_stream && + request_->upload_data_stream->has_null_source(); if (response_.headers->response_code() == 421 && - (enable_ip_based_pooling_ || enable_alternative_services_)) { + (enable_ip_based_pooling_ || enable_alternative_services_) && + !has_body_with_null_source) { #if BUILDFLAG(ENABLE_REPORTING) GenerateNetworkErrorLoggingReport(OK); #endif // BUILDFLAG(ENABLE_REPORTING) @@ -1281,7 +1286,9 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { int HttpNetworkTransaction::DoReadBody() { DCHECK(read_buf_.get()); - DCHECK_GT(read_buf_len_, 0); + // TODO(https://crbug.com/1335423): Change to DCHECK_GT() or remove after bug + // is fixed. + CHECK_GT(read_buf_len_, 0); DCHECK(stream_ != nullptr); next_state_ = STATE_READ_BODY_COMPLETE; diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc index 26120aade9c..0897eb3e2ba 100644 --- a/chromium/net/http/http_network_transaction_unittest.cc +++ b/chromium/net/http/http_network_transaction_unittest.cc @@ -193,7 +193,7 @@ bool IsTransportSocketPoolStalled(HttpNetworkSession* session) { std::string GetHeaders(const base::Value& params) { if (!params.is_dict()) return ""; - const base::Value* header_list = params.FindListKey("headers"); + const base::Value::List* header_list = params.GetDict().FindList("headers"); if (!header_list) return ""; std::string headers; @@ -914,10 +914,10 @@ TEST_F(HttpNetworkTransactionTest, SimpleGETHostResolutionFailure) { request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - MockHostResolver* resolver = new MockHostResolver(); + auto resolver = std::make_unique<MockHostResolver>(); resolver->rules()->AddSimulatedTimeoutFailure("www.example.org"); session_deps_.net_log = net::NetLog::Get(); - session_deps_.host_resolver.reset(resolver); + session_deps_.host_resolver = std::move(resolver); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; @@ -1576,7 +1576,7 @@ TEST_F(HttpNetworkTransactionTest, ReuseConnection) { "hello", "world" }; - for (int i = 0; i < 2; ++i) { + for (const auto* expected_response_data : kExpectedResponseData) { HttpRequestInfo request; request.method = "GET"; request.url = GURL("http://www.example.org/"); @@ -1603,7 +1603,7 @@ TEST_F(HttpNetworkTransactionTest, ReuseConnection) { std::string response_data; rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); - EXPECT_EQ(kExpectedResponseData[i], response_data); + EXPECT_EQ(expected_response_data, response_data); } } @@ -2086,7 +2086,7 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest( if (write_failure) { ASSERT_FALSE(read_failure); data1_writes.push_back(*write_failure); - data1_reads.push_back(MockRead(ASYNC, OK)); + data1_reads.emplace_back(ASYNC, OK); } else { ASSERT_TRUE(read_failure); if (use_spdy) { @@ -2094,10 +2094,10 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest( if (chunked_upload) data1_writes.push_back(CreateMockWrite(spdy_request_body)); } else { - data1_writes.push_back(MockWrite(kHttpRequest)); + data1_writes.emplace_back(kHttpRequest); if (chunked_upload) { - data1_writes.push_back(MockWrite("6\r\nfoobar\r\n")); - data1_writes.push_back(MockWrite("0\r\n\r\n")); + data1_writes.emplace_back("6\r\nfoobar\r\n"); + data1_writes.emplace_back("0\r\n\r\n"); } } data1_reads.push_back(*read_failure); @@ -2116,19 +2116,18 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest( data2_writes.push_back(CreateMockWrite(spdy_request_body, seq++, ASYNC)); data2_reads.push_back(CreateMockRead(spdy_response, seq++, ASYNC)); data2_reads.push_back(CreateMockRead(spdy_data, seq++, ASYNC)); - data2_reads.push_back(MockRead(ASYNC, OK, seq++)); + data2_reads.emplace_back(ASYNC, OK, seq++); } else { int seq = 0; - data2_writes.push_back( - MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), seq++)); + data2_writes.emplace_back(ASYNC, kHttpRequest, strlen(kHttpRequest), seq++); if (chunked_upload) { - data2_writes.push_back(MockWrite(ASYNC, "6\r\nfoobar\r\n", 11, seq++)); - data2_writes.push_back(MockWrite(ASYNC, "0\r\n\r\n", 5, seq++)); + data2_writes.emplace_back(ASYNC, "6\r\nfoobar\r\n", 11, seq++); + data2_writes.emplace_back(ASYNC, "0\r\n\r\n", 5, seq++); } - data2_reads.push_back( - MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), seq++)); - data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), seq++)); - data2_reads.push_back(MockRead(ASYNC, OK, seq++)); + data2_reads.emplace_back(ASYNC, kHttpResponse, strlen(kHttpResponse), + seq++); + data2_reads.emplace_back(ASYNC, kHttpData, strlen(kHttpData), seq++); + data2_reads.emplace_back(ASYNC, OK, seq++); } SequencedSocketData data2(data2_reads, data2_writes); session_deps_.socket_factory->AddSocketDataProvider(&data2); @@ -3043,14 +3042,15 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) { request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); - MockHostResolver* resolver = new MockHostResolver(); + auto resolver = std::make_unique<MockHostResolver>(); + auto* resolver_ptr = resolver.get(); session_deps_.net_log = net::NetLog::Get(); - session_deps_.host_resolver.reset(resolver); + session_deps_.host_resolver = std::move(resolver); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - resolver->rules()->ClearRules(); - resolver->rules()->AddRule("www.example.org", "127.0.0.1"); + resolver_ptr->rules()->ClearRules(); + resolver_ptr->rules()->AddRule("www.example.org", "127.0.0.1"); MockWrite data_writes1[] = { MockWrite("GET / HTTP/1.1\r\n" @@ -3115,8 +3115,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) { ASSERT_FALSE(endpoint.address().empty()); EXPECT_EQ("127.0.0.1:80", endpoint.ToString()); - resolver->rules()->ClearRules(); - resolver->rules()->AddRule("www.example.org", "127.0.0.2"); + resolver_ptr->rules()->ClearRules(); + resolver_ptr->rules()->AddRule("www.example.org", "127.0.0.2"); TestCompletionCallback callback2; @@ -3608,7 +3608,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; NetLogWithSource net_log_with_source = @@ -3758,7 +3758,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -3906,7 +3906,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -4019,7 +4019,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -4133,7 +4133,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -4260,7 +4260,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); @@ -4349,7 +4349,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -4410,7 +4410,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyMatchesServerAuthNoTunnel) { // Proxy matches request URL. session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); NetLogWithSource net_log_with_source = NetLogWithSource::Make(NetLogSourceType::NONE); @@ -4567,7 +4567,7 @@ TEST_F(HttpNetworkTransactionTest, // Proxy matches request URL. session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); NetLogWithSource net_log_with_source = NetLogWithSource::Make(NetLogSourceType::NONE); @@ -4821,7 +4821,7 @@ TEST_F(HttpNetworkTransactionTest, // Proxy matches request URL. session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); NetLogWithSource net_log_with_source = NetLogWithSource::Make(NetLogSourceType::NONE); @@ -5088,7 +5088,7 @@ TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -5195,7 +5195,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -5258,14 +5258,14 @@ TEST_F(HttpNetworkTransactionTest, // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>(); auth_handler_factory->set_do_init_from_challenge(true); auto mock_handler = std::make_unique<HttpAuthHandlerMock>(); mock_handler->set_allows_default_credentials(true); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_PROXY); session_deps_.http_auth_handler_factory = std::move(auth_handler_factory); @@ -5374,14 +5374,14 @@ TEST_F(HttpNetworkTransactionTest, // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>(); auth_handler_factory->set_do_init_from_challenge(true); auto mock_handler = std::make_unique<HttpAuthHandlerMock>(); mock_handler->set_allows_default_credentials(true); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_PROXY); session_deps_.http_auth_handler_factory = std::move(auth_handler_factory); @@ -5495,14 +5495,14 @@ TEST_F(HttpNetworkTransactionTest, // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>(); auth_handler_factory->set_do_init_from_challenge(true); auto mock_handler = std::make_unique<HttpAuthHandlerMock>(); mock_handler->set_allows_default_credentials(true); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_PROXY); session_deps_.http_auth_handler_factory = std::move(auth_handler_factory); @@ -5595,7 +5595,7 @@ TEST_F(HttpNetworkTransactionTest, // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>(); @@ -5612,13 +5612,13 @@ TEST_F(HttpNetworkTransactionTest, mock_handler->set_allows_default_credentials(true); mock_handler->set_allows_explicit_credentials(true); mock_handler->set_connection_based(true); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_PROXY); mock_handler = std::make_unique<HttpAuthHandlerMock>(); mock_handler->set_allows_default_credentials(true); mock_handler->set_allows_explicit_credentials(true); mock_handler->set_connection_based(true); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_PROXY); session_deps_.http_auth_handler_factory = std::move(auth_handler_factory); @@ -5713,20 +5713,20 @@ TEST_F(HttpNetworkTransactionTest, // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>(); auth_handler_factory->set_do_init_from_challenge(true); auto mock_handler = std::make_unique<HttpAuthHandlerMock>(); mock_handler->set_allows_default_credentials(true); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_PROXY); // Add another handler for the second challenge. It supports default // credentials, but they shouldn't be used, since they were already tried. mock_handler = std::make_unique<HttpAuthHandlerMock>(); mock_handler->set_allows_default_credentials(true); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_PROXY); session_deps_.http_auth_handler_factory = std::move(auth_handler_factory); @@ -5824,7 +5824,7 @@ TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) { mock_handler->set_allows_explicit_credentials(true); mock_handler->set_connection_based(true); mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_SERVER); // Add another handler for the second challenge. It supports default @@ -5833,7 +5833,7 @@ TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) { mock_handler->set_allows_default_credentials(true); mock_handler->set_allows_explicit_credentials(true); mock_handler->set_connection_based(true); - auth_handler_factory->AddMockHandler(mock_handler.release(), + auth_handler_factory->AddMockHandler(std::move(mock_handler), HttpAuth::AUTH_SERVER); session_deps_.http_auth_handler_factory = std::move(auth_handler_factory); @@ -5937,14 +5937,14 @@ TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) { // schemes, based on the path of the URL being requests. class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver { public: - SameProxyWithDifferentSchemesProxyResolver() {} + SameProxyWithDifferentSchemesProxyResolver() = default; SameProxyWithDifferentSchemesProxyResolver( const SameProxyWithDifferentSchemesProxyResolver&) = delete; SameProxyWithDifferentSchemesProxyResolver& operator=( const SameProxyWithDifferentSchemesProxyResolver&) = delete; - ~SameProxyWithDifferentSchemesProxyResolver() override {} + ~SameProxyWithDifferentSchemesProxyResolver() override = default; static constexpr uint16_t kProxyPort = 10000; @@ -6216,7 +6216,7 @@ TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); NetLogWithSource net_log_with_source = NetLogWithSource::Make(NetLogSourceType::NONE); @@ -6321,7 +6321,7 @@ TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); NetLogWithSource net_log_with_source = NetLogWithSource::Make(NetLogSourceType::NONE); @@ -6458,12 +6458,12 @@ TEST_F(HttpNetworkTransactionTest, ProxyHostResolutionFailure) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); - MockHostResolver* resolver = new MockHostResolver(); + auto resolver = std::make_unique<MockHostResolver>(); resolver->rules()->AddSimulatedTimeoutFailure("proxy"); session_deps_.net_log = net::NetLog::Get(); - session_deps_.host_resolver.reset(resolver); + session_deps_.host_resolver = std::move(resolver); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; @@ -6487,7 +6487,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -6569,7 +6569,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -6650,7 +6650,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) { // Configure SPDY proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); NetLogWithSource net_log_with_source = NetLogWithSource::Make(NetLogSourceType::NONE); @@ -6723,7 +6723,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) { // Configure against https proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -6821,7 +6821,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -6908,7 +6908,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -7001,7 +7001,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -7222,7 +7222,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session( @@ -7360,7 +7360,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session( @@ -7487,7 +7487,7 @@ TEST_F(HttpNetworkTransactionTest, TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) { // Configure against https proxy server "proxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session( @@ -7866,7 +7866,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { // Configure against https proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -7972,7 +7972,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetryNoKeepAlive) { // Configure against https proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -8094,7 +8094,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetryNoKeepAliveChangeProxy) { // Configure against https proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service->SetProxyDelegate( proxy_delegate.get()); @@ -8220,7 +8220,7 @@ TEST_F(HttpNetworkTransactionTest, // Configure against https proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service->SetProxyDelegate( proxy_delegate.get()); @@ -8334,7 +8334,7 @@ void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -8551,7 +8551,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -9448,7 +9448,7 @@ TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) { // The NTLM test data expects the proxy to be named 'server'. The origin is // https://origin/. session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS); SSLContextConfig config; @@ -9645,7 +9645,7 @@ TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -11020,12 +11020,12 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { // Tests that nonce count increments when multiple auth attempts // are started with the same nonce. TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) { - HttpAuthHandlerDigest::Factory* digest_factory = - new HttpAuthHandlerDigest::Factory(); - HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator = - new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef"); - digest_factory->set_nonce_generator(nonce_generator); - session_deps_.http_auth_handler_factory.reset(digest_factory); + auto digest_factory = std::make_unique<HttpAuthHandlerDigest::Factory>(); + auto nonce_generator = + std::make_unique<HttpAuthHandlerDigest::FixedNonceGenerator>( + "0123456789abcdef"); + digest_factory->set_nonce_generator(std::move(nonce_generator)); + session_deps_.http_auth_handler_factory = std::move(digest_factory); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); // Transaction 1: authenticate (foo, bar) on MyRealm1 @@ -11170,16 +11170,6 @@ TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { response->response_time = base::Time::Now(); response->was_cached = true; // (Wouldn't ever actually be true...) - { // Setup state for response_.vary_data - HttpRequestInfo request; - std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n"); - std::replace(temp.begin(), temp.end(), '\n', '\0'); - scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp)); - request.extra_headers.SetHeader("Foo", "1"); - request.extra_headers.SetHeader("bar", "23"); - EXPECT_TRUE(response->vary_data.Init(request, *headers.get())); - } - // Cause the above state to be reset. trans.ResetStateForRestart(); @@ -11191,7 +11181,6 @@ TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { EXPECT_FALSE(response->headers); EXPECT_FALSE(response->was_cached); EXPECT_EQ(0U, response->ssl_info.cert_status); - EXPECT_FALSE(response->vary_data.is_valid()); } // Test HTTPS connections to a site with a bad certificate @@ -11253,7 +11242,7 @@ TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) { // proxy TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); HttpRequestInfo request; @@ -11331,7 +11320,7 @@ TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { // Test HTTPS connections to a site, going through an HTTPS proxy TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -11395,7 +11384,7 @@ TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { // Test that an HTTPS Proxy cannot redirect a CONNECT request for main frames. TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -11462,7 +11451,7 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectSubresourceViaHttpsProxy) { base::HistogramTester histograms; session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -11508,9 +11497,9 @@ TEST_F(HttpNetworkTransactionTest, TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) { base::HistogramTester histograms; - session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromAutoDetectedPacResult( - "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); + session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService:: + CreateFixedFromAutoDetectedPacResultForTest("HTTPS proxy:70", + TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); HttpRequestInfo request; @@ -11556,7 +11545,7 @@ TEST_F(HttpNetworkTransactionTest, TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { base::HistogramTester histograms; session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -11627,7 +11616,7 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) { // Test that an HTTPS proxy's response to a CONNECT request is filtered. TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); HttpRequestInfo request; @@ -11672,7 +11661,7 @@ TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) { // Test that a SPDY proxy's response to a CONNECT request is filtered. TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); HttpRequestInfo request; @@ -11737,7 +11726,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) { // Configure against https proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -11870,7 +11859,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) { // HTTPS proxy TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); HttpRequestInfo request; @@ -12002,7 +11991,7 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) { std::string() /* accept-language */, setting_user_agent); } session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); for (const char* request_user_agent : kTestUserAgents) { @@ -12378,7 +12367,7 @@ TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -12434,7 +12423,7 @@ TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -12495,7 +12484,7 @@ TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -12550,7 +12539,7 @@ TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -12618,7 +12607,7 @@ TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); @@ -12781,26 +12770,28 @@ TEST_F(HttpNetworkTransactionTest, GroupIdForDirectConnections) { }, }; - for (size_t i = 0; i < std::size(tests); ++i) { + for (const auto& test : tests) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( - tests[i].proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS); + ConfiguredProxyResolutionService::CreateFixedForTest( + test.proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session( SetupSessionForGroupIdTests(&session_deps_)); HttpNetworkSessionPeer peer(session.get()); - CaptureGroupIdTransportSocketPool* transport_conn_pool = - new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_); + auto transport_conn_pool = + std::make_unique<CaptureGroupIdTransportSocketPool>( + &dummy_connect_job_params_); + auto* transport_conn_pool_ptr = transport_conn_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); mock_pool_manager->SetSocketPool(ProxyServer::Direct(), - base::WrapUnique(transport_conn_pool)); + std::move(transport_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); EXPECT_EQ(ERR_IO_PENDING, - GroupIdTransactionHelper(tests[i].url, session.get())); - EXPECT_EQ(tests[i].expected_group_id, - transport_conn_pool->last_group_id_received()); - EXPECT_TRUE(transport_conn_pool->socket_requested()); + GroupIdTransactionHelper(test.url, session.get())); + EXPECT_EQ(test.expected_group_id, + transport_conn_pool_ptr->last_group_id_received()); + EXPECT_TRUE(transport_conn_pool_ptr->socket_requested()); } } @@ -12839,10 +12830,10 @@ TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) { }, }; - for (size_t i = 0; i < std::size(tests); ++i) { + for (const auto& test : tests) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( - tests[i].proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS); + ConfiguredProxyResolutionService::CreateFixedForTest( + test.proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session( SetupSessionForGroupIdTests(&session_deps_)); @@ -12850,17 +12841,17 @@ TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) { ProxyServer proxy_server(ProxyServer::SCHEME_HTTP, HostPortPair("http_proxy", 80)); - CaptureGroupIdTransportSocketPool* http_proxy_pool = - new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_); + auto http_proxy_pool = std::make_unique<CaptureGroupIdTransportSocketPool>( + &dummy_connect_job_params_); + auto* http_proxy_pool_ptr = http_proxy_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPool(proxy_server, - base::WrapUnique(http_proxy_pool)); + mock_pool_manager->SetSocketPool(proxy_server, std::move(http_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); EXPECT_EQ(ERR_IO_PENDING, - GroupIdTransactionHelper(tests[i].url, session.get())); - EXPECT_EQ(tests[i].expected_group_id, - http_proxy_pool->last_group_id_received()); + GroupIdTransactionHelper(test.url, session.get())); + EXPECT_EQ(test.expected_group_id, + http_proxy_pool_ptr->last_group_id_received()); } } @@ -12917,31 +12908,31 @@ TEST_F(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) { }, }; - for (size_t i = 0; i < std::size(tests); ++i) { + for (const auto& test : tests) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( - tests[i].proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS); + ConfiguredProxyResolutionService::CreateFixedForTest( + test.proxy_server, TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session( SetupSessionForGroupIdTests(&session_deps_)); HttpNetworkSessionPeer peer(session.get()); ProxyServer proxy_server( - ProxyUriToProxyServer(tests[i].proxy_server, ProxyServer::SCHEME_HTTP)); + ProxyUriToProxyServer(test.proxy_server, ProxyServer::SCHEME_HTTP)); ASSERT_TRUE(proxy_server.is_valid()); - CaptureGroupIdTransportSocketPool* socks_conn_pool = - new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_); + auto socks_conn_pool = std::make_unique<CaptureGroupIdTransportSocketPool>( + &dummy_connect_job_params_); + auto* socks_conn_pool_ptr = socks_conn_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPool(proxy_server, - base::WrapUnique(socks_conn_pool)); + mock_pool_manager->SetSocketPool(proxy_server, std::move(socks_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); EXPECT_EQ(ERR_IO_PENDING, - GroupIdTransactionHelper(tests[i].url, session.get())); - EXPECT_EQ(tests[i].expected_group_id, - socks_conn_pool->last_group_id_received()); + GroupIdTransactionHelper(test.url, session.get())); + EXPECT_EQ(test.expected_group_id, + socks_conn_pool_ptr->last_group_id_received()); } } @@ -12953,7 +12944,7 @@ TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) { net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS); // This simulates failure resolving all hostnames; that means we will fail @@ -13126,7 +13117,7 @@ TEST_F(HttpNetworkTransactionTest, DrainResetOK) { // Test HTTPS connections going through a proxy that sends extra data. TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); HttpRequestInfo request; @@ -13308,9 +13299,10 @@ TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) { CompletionOnceCallback callback_; }; - FakeUploadElementReader* fake_reader = new FakeUploadElementReader; + auto fake_reader = std::make_unique<FakeUploadElementReader>(); + auto* fake_reader_ptr = fake_reader.get(); std::vector<std::unique_ptr<UploadElementReader>> element_readers; - element_readers.push_back(base::WrapUnique(fake_reader)); + element_readers.push_back(std::move(fake_reader)); ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); HttpRequestInfo request; @@ -13333,7 +13325,7 @@ TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) { base::RunLoop().RunUntilIdle(); // Transaction is pending on request body initialization. - CompletionOnceCallback init_callback = fake_reader->TakeCallback(); + CompletionOnceCallback init_callback = fake_reader_ptr->TakeCallback(); ASSERT_FALSE(init_callback.is_null()); // Return Init()'s result after the transaction gets destroyed. @@ -15849,15 +15841,15 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { for (const auto& test_config : test_configs) { SCOPED_TRACE(::testing::Message() << "Test config at " << test_config.line_number); - HttpAuthHandlerMock::Factory* auth_factory( - new HttpAuthHandlerMock::Factory()); - session_deps_.http_auth_handler_factory.reset(auth_factory); + auto auth_factory = std::make_unique<HttpAuthHandlerMock::Factory>(); + auto* auth_factory_ptr = auth_factory.get(); + session_deps_.http_auth_handler_factory = std::move(auth_factory); SSLInfo empty_ssl_info; // Set up authentication handlers as necessary. if (test_config.proxy_auth_timing != AUTH_NONE) { for (int n = 0; n < 3; n++) { - HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); + auto auth_handler = std::make_unique<HttpAuthHandlerMock>(); std::string auth_challenge = "Mock realm=proxy"; url::SchemeHostPort scheme_host_port(GURL(test_config.proxy_url)); HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(), @@ -15868,11 +15860,12 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { auth_handler->SetGenerateExpectation( test_config.proxy_auth_timing == AUTH_ASYNC, n == 0 ? test_config.first_generate_proxy_token_rv : OK); - auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY); + auth_factory_ptr->AddMockHandler(std::move(auth_handler), + HttpAuth::AUTH_PROXY); } } if (test_config.server_auth_timing != AUTH_NONE) { - HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); + auto auth_handler = std::make_unique<HttpAuthHandlerMock>(); std::string auth_challenge = "Mock realm=server"; url::SchemeHostPort scheme_host_port(GURL(test_config.server_url)); HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(), @@ -15883,7 +15876,8 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { auth_handler->SetGenerateExpectation( test_config.server_auth_timing == AUTH_ASYNC, test_config.first_generate_server_token_rv); - auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER); + auth_factory_ptr->AddMockHandler(std::move(auth_handler), + HttpAuth::AUTH_SERVER); // The second handler always succeeds. It should only be used where there // are multiple auth sessions for server auth in the same network @@ -15894,12 +15888,12 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { empty_ssl_info, NetworkIsolationKey(), scheme_host_port, NetLogWithSource()); second_handler->SetGenerateExpectation(true, OK); - auth_factory->AddMockHandler(second_handler.release(), - HttpAuth::AUTH_SERVER); + auth_factory_ptr->AddMockHandler(std::move(second_handler), + HttpAuth::AUTH_SERVER); } if (test_config.proxy_url) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( test_config.proxy_url, TRAFFIC_ANNOTATION_FOR_TESTS); } else { session_deps_.proxy_resolution_service = @@ -15929,8 +15923,8 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { // kProxyChallenge uses Proxy-Connection: close which means that the // socket is closed and a new one will be created for the next request. if (read_write_round.read.data == kProxyChallenge.data) { - mock_reads.push_back(std::vector<MockRead>()); - mock_writes.push_back(std::vector<MockWrite>()); + mock_reads.emplace_back(); + mock_writes.emplace_back(); } if (read_write_round.extra_read) { @@ -15992,14 +15986,15 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { // Do multi-round authentication and make sure it works correctly. - HttpAuthHandlerMock::Factory* auth_factory( - new HttpAuthHandlerMock::Factory()); - session_deps_.http_auth_handler_factory.reset(auth_factory); + auto auth_factory = std::make_unique<HttpAuthHandlerMock::Factory>(); + auto* auth_factory_ptr = auth_factory.get(); + session_deps_.http_auth_handler_factory = std::move(auth_factory); session_deps_.proxy_resolution_service = ConfiguredProxyResolutionService::CreateDirect(); session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1"); - HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock()); + auto auth_handler = std::make_unique<HttpAuthHandlerMock>(); + auto* auth_handler_ptr = auth_handler.get(); auth_handler->set_connection_based(true); std::string auth_challenge = "Mock realm=server"; GURL url("http://www.example.com"); @@ -16009,7 +16004,8 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER, empty_ssl_info, NetworkIsolationKey(), url::SchemeHostPort(url), NetLogWithSource()); - auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER); + auth_factory_ptr->AddMockHandler(std::move(auth_handler), + HttpAuth::AUTH_SERVER); int rv = OK; const HttpResponseInfo* response = nullptr; @@ -16027,15 +16023,16 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { HttpNetworkSessionPeer session_peer(session.get()); CommonConnectJobParams common_connect_job_params( session->CreateCommonConnectJobParams()); - TransportClientSocketPool* transport_pool = new TransportClientSocketPool( + auto transport_pool = std::make_unique<TransportClientSocketPool>( 50, // Max sockets for pool 1, // Max sockets per group base::Seconds(10), // unused_idle_socket_timeout ProxyServer::Direct(), false, // is_for_websockets &common_connect_job_params); + auto* transport_pool_ptr = transport_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); mock_pool_manager->SetSocketPool(ProxyServer::Direct(), - base::WrapUnique(transport_pool)); + std::move(transport_pool)); session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); @@ -16096,7 +16093,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { SecureDnsPolicy::kAllow); // First round of authentication. - auth_handler->SetGenerateExpectation(false, OK); + auth_handler_ptr->SetGenerateExpectation(false, OK); rv = trans.Start(&request, callback.callback(), NetLogWithSource()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); @@ -16104,9 +16101,9 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->auth_challenge.has_value()); - EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, - auth_handler->state()); + auth_handler_ptr->state()); // In between rounds, another request comes in for the same domain. // It should not be able to grab the TCP socket that trans has already @@ -16121,7 +16118,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { // the pool until after authentication completes. // Second round of authentication. - auth_handler->SetGenerateExpectation(false, OK); + auth_handler_ptr->SetGenerateExpectation(false, OK); rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); @@ -16129,12 +16126,12 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge.has_value()); - EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, - auth_handler->state()); + auth_handler_ptr->state()); // Third round of authentication. - auth_handler->SetGenerateExpectation(false, OK); + auth_handler_ptr->SetGenerateExpectation(false, OK); rv = trans.RestartWithAuth(AuthCredentials(), callback.callback()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); @@ -16142,12 +16139,12 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge.has_value()); - EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup)); EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN, - auth_handler->state()); + auth_handler_ptr->state()); // Fourth round of authentication, which completes successfully. - auth_handler->SetGenerateExpectation(false, OK); + auth_handler_ptr->SetGenerateExpectation(false, OK); rv = trans.RestartWithAuth(AuthCredentials(), callback.callback()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); @@ -16155,13 +16152,13 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge.has_value()); - EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup)); // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real // auth handler should transition to a DONE state in concert with the remote // server. But that's not something we can test here with a mock handler. EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE, - auth_handler->state()); + auth_handler_ptr->state()); // Read the body since the fourth round was successful. This will also // release the socket back to the pool. @@ -16175,7 +16172,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { EXPECT_EQ(0, rv); // There are still 0 idle sockets, since the trans_compete transaction // will be handed it immediately after trans releases it to the group. - EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(0u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup)); // The competing request can now finish. Wait for the headers and then // read the body. @@ -16189,7 +16186,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) { EXPECT_EQ(0, rv); // Finally, the socket is released to the group. - EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup)); + EXPECT_EQ(1u, transport_pool_ptr->IdleSocketCountInGroup(kSocketGroup)); } // This tests the case that a request is issued via http instead of spdy after @@ -16398,7 +16395,7 @@ TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) { // Test a basic GET request through a proxy. TEST_F(HttpNetworkTransactionTest, ProxyGet) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -16465,7 +16462,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyGet) { // Test a basic HTTPS GET request through a proxy. TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -16550,7 +16547,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) { // literal host. TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -16628,7 +16625,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) { // while establishing the tunnel. TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); RecordingNetLogObserver net_log_observer; session_deps_.net_log = NetLog::Get(); @@ -16762,9 +16759,9 @@ TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) { ERR_CERT_AUTHORITY_INVALID, ERR_CERT_DATE_INVALID, }; - for (size_t i = 0; i < std::size(kErrors); i++) { - CheckErrorIsPassedBack(kErrors[i], ASYNC); - CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS); + for (int error : kErrors) { + CheckErrorIsPassedBack(error, ASYNC); + CheckErrorIsPassedBack(error, SYNCHRONOUS); } } @@ -16986,7 +16983,7 @@ TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) { // proxy. TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); @@ -17637,6 +17634,164 @@ TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) { } TEST_F(HttpNetworkTransactionTest, + Response421WithStreamingBodyWithNonNullSource) { + const std::string ip_addr = "1.2.3.4"; + IPAddress ip; + ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr)); + IPEndPoint peer_addr = IPEndPoint(ip, 443); + + session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>(); + session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr); + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + const std::string request_body = "hello"; + spdy::SpdySerializedFrame req1 = spdy_util_.ConstructChunkedSpdyPost({}, 0); + spdy::SpdySerializedFrame req1_body = + spdy_util_.ConstructSpdyDataFrame(1, request_body, /*fin=*/true); + spdy::SpdySerializedFrame rst = + spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL); + MockWrite writes1[] = { + CreateMockWrite(req1, 0), + CreateMockWrite(req1_body, 1), + CreateMockWrite(rst, 4), + }; + + spdy::Http2HeaderBlock response_headers; + response_headers[spdy::kHttp2StatusHeader] = "421"; + spdy::SpdySerializedFrame resp1 = + spdy_util_.ConstructSpdyReply(1, std::move(response_headers)); + MockRead reads1[] = {CreateMockRead(resp1, 2), MockRead(ASYNC, 0, 3)}; + + MockConnect connect1(ASYNC, OK, peer_addr); + SequencedSocketData data1(connect1, reads1, writes1); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + + AddSSLSocketData(); + + SpdyTestUtil spdy_util2; + spdy::SpdySerializedFrame req2 = spdy_util2.ConstructChunkedSpdyPost({}, 0); + spdy::SpdySerializedFrame req2_body = + spdy_util2.ConstructSpdyDataFrame(1, request_body, /*fin=*/true); + MockWrite writes2[] = { + CreateMockWrite(req2, 0), + CreateMockWrite(req2_body, 1), + }; + + spdy::Http2HeaderBlock resp2_headers; + resp2_headers[spdy::kHttp2StatusHeader] = "200"; + spdy::SpdySerializedFrame resp2 = + spdy_util2.ConstructSpdyReply(1, std::move(resp2_headers)); + spdy::SpdySerializedFrame resp2_body( + spdy_util2.ConstructSpdyDataFrame(1, true)); + MockRead reads2[] = {CreateMockRead(resp2, 2), CreateMockRead(resp2_body, 3), + MockRead(ASYNC, 0, 4)}; + + MockConnect connect2(ASYNC, OK, peer_addr); + SequencedSocketData data2(connect2, reads2, writes2); + session_deps_.socket_factory->AddSocketDataProvider(&data2); + + AddSSLSocketData(); + + TestCompletionCallback callback; + HttpRequestInfo request; + ChunkedUploadDataStream upload_data_stream(0, /*has_null_source=*/false); + upload_data_stream.AppendData(request_body.data(), request_body.size(), + /*is_done=*/true); + request.method = "POST"; + request.url = GURL("https://www.example.org"); + request.load_flags = 0; + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + request.upload_data_stream = &upload_data_stream; + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + + int rv = trans.Start(&request, callback.callback(), + NetLogWithSource::Make(NetLogSourceType::NONE)); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + rv = callback.WaitForResult(); + EXPECT_THAT(rv, IsOk()); + + const HttpResponseInfo* response = trans.GetResponseInfo(); + std::string response_data; + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); + EXPECT_TRUE(response->was_fetched_via_spdy); + EXPECT_TRUE(response->was_alpn_negotiated); + EXPECT_TRUE(response->ssl_info.cert); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); + EXPECT_EQ("hello!", response_data); +} + +TEST_F(HttpNetworkTransactionTest, Response421WithStreamingBodyWithNullSource) { + const std::string ip_addr = "1.2.3.4"; + IPAddress ip; + ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr)); + IPEndPoint peer_addr = IPEndPoint(ip, 443); + + session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>(); + session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr); + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + + const std::string request_body = "hello"; + spdy::SpdySerializedFrame req1 = spdy_util_.ConstructChunkedSpdyPost({}, 0); + spdy::SpdySerializedFrame req1_body = + spdy_util_.ConstructSpdyDataFrame(1, request_body, /*fin=*/true); + spdy::SpdySerializedFrame rst = + spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL); + MockWrite writes1[] = { + CreateMockWrite(req1, 0), + CreateMockWrite(req1_body, 1), + CreateMockWrite(rst, 5), + }; + + spdy::Http2HeaderBlock response_headers; + response_headers[spdy::kHttp2StatusHeader] = "421"; + spdy::SpdySerializedFrame resp1 = + spdy_util_.ConstructSpdyReply(1, std::move(response_headers)); + spdy::SpdySerializedFrame resp1_body( + spdy_util_.ConstructSpdyDataFrame(1, true)); + MockRead reads1[] = {CreateMockRead(resp1, 2), CreateMockRead(resp1_body, 3), + MockRead(ASYNC, 0, 4)}; + + MockConnect connect1(ASYNC, OK, peer_addr); + SequencedSocketData data1(connect1, reads1, writes1); + session_deps_.socket_factory->AddSocketDataProvider(&data1); + + AddSSLSocketData(); + + TestCompletionCallback callback; + HttpRequestInfo request; + ChunkedUploadDataStream upload_data_stream(0, /*has_null_source=*/true); + upload_data_stream.AppendData(request_body.data(), request_body.size(), + /*is_done=*/true); + request.method = "POST"; + request.url = GURL("https://www.example.org"); + request.load_flags = 0; + request.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + request.upload_data_stream = &upload_data_stream; + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + + int rv = trans.Start(&request, callback.callback(), + NetLogWithSource::Make(NetLogSourceType::NONE)); + EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); + rv = callback.WaitForResult(); + EXPECT_THAT(rv, IsOk()); + + const HttpResponseInfo* response = trans.GetResponseInfo(); + std::string response_data; + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine()); + EXPECT_TRUE(response->was_fetched_via_spdy); + EXPECT_TRUE(response->was_alpn_negotiated); + EXPECT_TRUE(response->ssl_info.cert); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); + EXPECT_EQ("hello!", response_data); +} + +TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingWithHostCacheExpiration) { // Set up HostResolver to invalidate cached entries after 1 cached resolve. session_deps_.host_resolver = @@ -18136,7 +18291,7 @@ TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { data1.set_connect_data(connect_data1); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = net::NetLog::Get(); SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy @@ -19477,7 +19632,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -19584,7 +19739,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -19657,7 +19812,7 @@ TEST_F(HttpNetworkTransactionTest, WebSocketNotSentOverQuicProxy) { for (bool secure : {true, false}) { SCOPED_TRACE(secure); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.enable_quic = true; @@ -19930,15 +20085,16 @@ TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) { ProxyConfig proxy_config; proxy_config.set_pac_url(GURL("http://fooproxyurl")); proxy_config.set_pac_mandatory(true); - MockAsyncProxyResolverFactory* proxy_resolver_factory = - new MockAsyncProxyResolverFactory(false); + auto proxy_resolver_factory = + std::make_unique<MockAsyncProxyResolverFactory>(false); + auto* proxy_resolver_factory_ptr = proxy_resolver_factory.get(); MockAsyncProxyResolver resolver; session_deps_.proxy_resolution_service = std::make_unique<ConfiguredProxyResolutionService>( std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation( proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)), - base::WrapUnique(proxy_resolver_factory), nullptr, + std::move(proxy_resolver_factory), nullptr, /*quick_check_enabled=*/true); HttpRequestInfo request; request.method = "GET"; @@ -19953,7 +20109,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) { int rv = trans.Start(&request, callback.callback(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( + proxy_resolver_factory_ptr->pending_requests()[0]->CompleteNowWithForwarder( ERR_FAILED, &resolver); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED)); @@ -19961,7 +20117,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) { TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.enable_quic = false; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -20244,7 +20400,7 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontProcessNelHeaderProxy) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.net_log = NetLog::Get(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -21194,7 +21350,7 @@ TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) { // Configure against proxy server "myproxy:70". session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -21879,7 +22035,7 @@ TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorAsync) { TEST_F(HttpNetworkTransactionTest, AuthEverything) { // Note these hosts must match the CheckBasic*Auth() functions. session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>(); @@ -22066,7 +22222,7 @@ TEST_F(HttpNetworkTransactionTest, AuthEverything) { TEST_F(HttpNetworkTransactionTest, AuthEverythingWithConnectClose) { // Note these hosts must match the CheckBasic*Auth() functions. session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); auto cert_request_info_proxy = base::MakeRefCounted<SSLCertRequestInfo>(); @@ -22306,7 +22462,7 @@ TEST_F(HttpNetworkTransactionTest, AuthEverythingWithConnectClose) { TEST_F(HttpNetworkTransactionTest, ProxyHTTPAndServerTLSAuth) { // Note these hosts must match the CheckBasic*Auth() functions. session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); auto cert_request_info_origin = base::MakeRefCounted<SSLCertRequestInfo>(); @@ -22664,7 +22820,7 @@ TEST_F(HttpNetworkTransactionTest, NetworkIsolationH2) { SCOPED_TRACE(use_proxy); if (use_proxy) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS proxy:443", TRAFFIC_ANNOTATION_FOR_TESTS); } else { session_deps_.proxy_resolution_service = @@ -23120,7 +23276,7 @@ TEST_F(HttpNetworkTransactionTest, NetworkIsolationSSLProxy) { {}); session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS); const SchemefulSite kSite1(GURL("http://origin1/")); diff --git a/chromium/net/http/http_proxy_client_socket.cc b/chromium/net/http/http_proxy_client_socket.cc index 80623ee1e66..59e203f374a 100644 --- a/chromium/net/http/http_proxy_client_socket.cc +++ b/chromium/net/http/http_proxy_client_socket.cc @@ -36,14 +36,14 @@ HttpProxyClientSocket::HttpProxyClientSocket( const std::string& user_agent, const HostPortPair& endpoint, const ProxyServer& proxy_server, - HttpAuthController* http_auth_controller, + scoped_refptr<HttpAuthController> http_auth_controller, ProxyDelegate* proxy_delegate, const NetworkTrafficAnnotationTag& traffic_annotation) : io_callback_(base::BindRepeating(&HttpProxyClientSocket::OnIOComplete, base::Unretained(this))), socket_(std::move(socket)), endpoint_(endpoint), - auth_(http_auth_controller), + auth_(std::move(http_auth_controller)), proxy_server_(proxy_server), proxy_delegate_(proxy_delegate), traffic_annotation_(traffic_annotation), diff --git a/chromium/net/http/http_proxy_client_socket.h b/chromium/net/http/http_proxy_client_socket.h index 4c82607381c..4ac6588f139 100644 --- a/chromium/net/http/http_proxy_client_socket.h +++ b/chromium/net/http/http_proxy_client_socket.h @@ -44,7 +44,7 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket { const std::string& user_agent, const HostPortPair& endpoint, const ProxyServer& proxy_server, - HttpAuthController* http_auth_controller, + scoped_refptr<HttpAuthController> http_auth_controller, ProxyDelegate* proxy_delegate, const NetworkTrafficAnnotationTag& traffic_annotation); diff --git a/chromium/net/http/http_proxy_client_socket_fuzzer.cc b/chromium/net/http/http_proxy_client_socket_fuzzer.cc index ad3397f5681..fc3af857cd8 100644 --- a/chromium/net/http/http_proxy_client_socket_fuzzer.cc +++ b/chromium/net/http/http_proxy_client_socket_fuzzer.cc @@ -43,8 +43,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { net::RecordingNetLogObserver net_log_observer; net::TestCompletionCallback callback; - std::unique_ptr<net::FuzzedSocket> fuzzed_socket( - new net::FuzzedSocket(&data_provider, net::NetLog::Get())); + auto fuzzed_socket = + std::make_unique<net::FuzzedSocket>(&data_provider, net::NetLog::Get()); CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback())); // Create auth handler supporting basic and digest schemes. Other schemes can diff --git a/chromium/net/http/http_proxy_client_socket_unittest.cc b/chromium/net/http/http_proxy_client_socket_unittest.cc index 236542a093f..7fb2455eea4 100644 --- a/chromium/net/http/http_proxy_client_socket_unittest.cc +++ b/chromium/net/http/http_proxy_client_socket_unittest.cc @@ -20,22 +20,23 @@ namespace { TEST(HttpProxyClientSocketTest, Tag) { StaticSocketDataProvider data; - MockTaggingStreamSocket* tagging_sock = - new MockTaggingStreamSocket(std::make_unique<MockTCPClientSocket>( - AddressList(), nullptr /* net_log */, &data)); + auto tagging_sock = std::make_unique<MockTaggingStreamSocket>( + std::make_unique<MockTCPClientSocket>(AddressList(), + nullptr /* net_log */, &data)); + auto* tagging_sock_ptr = tagging_sock.get(); // |socket| takes ownership of |tagging_sock|, but the test keeps a non-owning // pointer to it. HttpProxyClientSocket socket( - std::unique_ptr<StreamSocket>(tagging_sock), /*user_agent=*/"", - HostPortPair(), ProxyServer(), /*http_auth_controller=*/nullptr, + std::move(tagging_sock), /*user_agent=*/"", HostPortPair(), ProxyServer(), + /*http_auth_controller=*/nullptr, /*proxy_delegate=*/nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); - EXPECT_EQ(tagging_sock->tag(), SocketTag()); + EXPECT_EQ(tagging_sock_ptr->tag(), SocketTag()); #if BUILDFLAG(IS_ANDROID) SocketTag tag(0x12345678, 0x87654321); socket.ApplySocketTag(tag); - EXPECT_EQ(tagging_sock->tag(), tag); + EXPECT_EQ(tagging_sock_ptr->tag(), tag); #endif // BUILDFLAG(IS_ANDROID) } diff --git a/chromium/net/http/http_proxy_connect_job.cc b/chromium/net/http/http_proxy_connect_job.cc index 9a95455672c..47bcec0954a 100644 --- a/chromium/net/http/http_proxy_connect_job.cc +++ b/chromium/net/http/http_proxy_connect_job.cc @@ -200,7 +200,7 @@ HttpProxyConnectJob::HttpProxyConnectJob( host_resolver()) : nullptr) {} -HttpProxyConnectJob::~HttpProxyConnectJob() {} +HttpProxyConnectJob::~HttpProxyConnectJob() = default; const RequestPriority HttpProxyConnectJob::kH2QuicTunnelPriority = DEFAULT_PRIORITY; @@ -532,7 +532,7 @@ int HttpProxyConnectJob::DoHttpProxyConnect() { transport_socket_ = std::make_unique<HttpProxyClientSocket>( nested_connect_job_->PassSocket(), GetUserAgent(), params_->endpoint(), ProxyServer(GetProxyServerScheme(), GetDestination()), - http_auth_controller_.get(), common_connect_job_params()->proxy_delegate, + http_auth_controller_, common_connect_job_params()->proxy_delegate, params_->traffic_annotation()); nested_connect_job_.reset(); return transport_socket_->Connect(base::BindOnce( @@ -624,8 +624,8 @@ int HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) { // |transport_socket_| will set itself as |stream|'s delegate. transport_socket_ = std::make_unique<SpdyProxyClientSocket>( stream, ProxyServer(GetProxyServerScheme(), GetDestination()), - GetUserAgent(), params_->endpoint(), net_log(), - http_auth_controller_.get(), common_connect_job_params()->proxy_delegate); + GetUserAgent(), params_->endpoint(), net_log(), http_auth_controller_, + common_connect_job_params()->proxy_delegate); return transport_socket_->Connect(base::BindOnce( &HttpProxyConnectJob::OnIOComplete, base::Unretained(this))); } @@ -699,7 +699,7 @@ int HttpProxyConnectJob::DoQuicProxyCreateStreamComplete(int result) { transport_socket_ = std::make_unique<QuicProxyClientSocket>( std::move(quic_stream), std::move(quic_session_), ProxyServer(GetProxyServerScheme(), GetDestination()), GetUserAgent(), - params_->endpoint(), net_log(), http_auth_controller_.get(), + params_->endpoint(), net_log(), http_auth_controller_, common_connect_job_params()->proxy_delegate); return transport_socket_->Connect(base::BindOnce( &HttpProxyConnectJob::OnIOComplete, base::Unretained(this))); diff --git a/chromium/net/http/http_proxy_connect_job_unittest.cc b/chromium/net/http/http_proxy_connect_job_unittest.cc index e35978efa98..b433ca83e12 100644 --- a/chromium/net/http/http_proxy_connect_job_unittest.cc +++ b/chromium/net/http/http_proxy_connect_job_unittest.cc @@ -76,7 +76,7 @@ class HttpProxyConnectJobTest : public ::testing::TestWithParam<HttpProxyType>, InitCommonConnectJobParams(); } - virtual ~HttpProxyConnectJobTest() { + ~HttpProxyConnectJobTest() override { // Reset global field trial parameters to defaults values. base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); HttpProxyConnectJob::UpdateFieldTrialParametersForTesting(); diff --git a/chromium/net/http/http_request_headers.cc b/chromium/net/http/http_request_headers.cc index ea36ce6f63d..55e366bf4cd 100644 --- a/chromium/net/http/http_request_headers.cc +++ b/chromium/net/http/http_request_headers.cc @@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/values.h" +#include "net/base/url_util.h" #include "net/http/http_log_util.h" #include "net/http/http_util.h" #include "net/log/net_log_capture_mode.h" @@ -21,6 +22,19 @@ namespace net { +namespace { + +bool SupportsStreamType( + const absl::optional<base::flat_set<SourceStream::SourceType>>& + accepted_stream_types, + SourceStream::SourceType type) { + if (!accepted_stream_types) + return true; + return accepted_stream_types->contains(type); +} + +} // namespace + const char HttpRequestHeaders::kConnectMethod[] = "CONNECT"; const char HttpRequestHeaders::kDeleteMethod[] = "DELETE"; const char HttpRequestHeaders::kGetMethod[] = "GET"; @@ -180,16 +194,16 @@ void HttpRequestHeaders::AddHeadersFromString( } void HttpRequestHeaders::MergeFrom(const HttpRequestHeaders& other) { - for (auto it = other.headers_.begin(); it != other.headers_.end(); ++it) { - SetHeader(it->key, it->value); + for (const auto& header : other.headers_) { + SetHeader(header.key, header.value); } } std::string HttpRequestHeaders::ToString() const { std::string output; - for (auto it = headers_.begin(); it != headers_.end(); ++it) { - base::StringAppendF(&output, "%s: %s\r\n", it->key.c_str(), - it->value.c_str()); + for (const auto& header : headers_) { + base::StringAppendF(&output, "%s: %s\r\n", header.key.c_str(), + header.value.c_str()); } output.append("\r\n"); return output; @@ -198,17 +212,61 @@ std::string HttpRequestHeaders::ToString() const { base::Value HttpRequestHeaders::NetLogParams( const std::string& request_line, NetLogCaptureMode capture_mode) const { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetKey("line", NetLogStringValue(request_line)); - base::Value headers(base::Value::Type::LIST); + base::Value::Dict dict; + dict.Set("line", NetLogStringValue(request_line)); + base::Value::List headers; for (const auto& header : headers_) { std::string log_value = ElideHeaderValueForNetLog(capture_mode, header.key, header.value); headers.Append( NetLogStringValue(base::StrCat({header.key, ": ", log_value}))); } - dict.SetKey("headers", std::move(headers)); - return dict; + dict.Set("headers", std::move(headers)); + return base::Value(std::move(dict)); +} + +void HttpRequestHeaders::SetAcceptEncodingIfMissing( + const GURL& url, + const absl::optional<base::flat_set<SourceStream::SourceType>>& + accepted_stream_types, + bool enable_brotli) { + if (HasHeader(kAcceptEncoding)) + return; + + // If a range is specifically requested, set the "Accepted Encoding" header to + // "identity". + if (HasHeader(kRange)) { + SetHeader(kAcceptEncoding, "identity"); + return; + } + + // 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 (SupportsStreamType(accepted_stream_types, + SourceStream::SourceType::TYPE_GZIP)) { + advertised_encoding_names.push_back("gzip"); + } + if (SupportsStreamType(accepted_stream_types, + SourceStream::SourceType::TYPE_DEFLATE)) { + advertised_encoding_names.push_back("deflate"); + } + // Advertise "br" encoding only if transferred data is opaque to proxy. + if (enable_brotli && + SupportsStreamType(accepted_stream_types, + SourceStream::SourceType::TYPE_BROTLI)) { + if (url.SchemeIsCryptographic() || IsLocalhost(url)) { + advertised_encoding_names.push_back("br"); + } + } + if (!advertised_encoding_names.empty()) { + // Tell the server what compression formats are supported. + SetHeader( + kAcceptEncoding, + base::JoinString(base::make_span(advertised_encoding_names), ", ")); + } } HttpRequestHeaders::HeaderVector::iterator HttpRequestHeaders::FindHeader( diff --git a/chromium/net/http/http_request_headers.h b/chromium/net/http/http_request_headers.h index c1a956e0a80..0f4257c657f 100644 --- a/chromium/net/http/http_request_headers.h +++ b/chromium/net/http/http_request_headers.h @@ -14,9 +14,13 @@ #include <string> #include <vector> +#include "base/containers/flat_set.h" #include "base/strings/string_piece.h" #include "net/base/net_export.h" +#include "net/filter/source_stream.h" #include "net/log/net_log_capture_mode.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" namespace base { class Value; @@ -186,6 +190,14 @@ class NET_EXPORT HttpRequestHeaders { const HeaderVector& GetHeaderVector() const { return headers_; } + // Sets Accept-Encoding header based on `url` and `accepted_stream_types`, if + // it does not exist. "br" is appended only when `enable_brotli` is true. + void SetAcceptEncodingIfMissing( + const GURL& url, + const absl::optional<base::flat_set<SourceStream::SourceType>>& + accepted_stream_types, + bool enable_brotli); + private: HeaderVector::iterator FindHeader(const base::StringPiece& key); HeaderVector::const_iterator FindHeader(const base::StringPiece& key) const; diff --git a/chromium/net/http/http_response_body_drainer.cc b/chromium/net/http/http_response_body_drainer.cc index 9591c58c96f..0be2c28d986 100644 --- a/chromium/net/http/http_response_body_drainer.cc +++ b/chromium/net/http/http_response_body_drainer.cc @@ -25,6 +25,7 @@ HttpResponseBodyDrainer::HttpResponseBodyDrainer(HttpStream* stream) HttpResponseBodyDrainer::~HttpResponseBodyDrainer() = default; void HttpResponseBodyDrainer::Start(HttpNetworkSession* session) { + session_ = session; read_buf_ = base::MakeRefCounted<IOBuffer>(kDrainBodyBufferSize); next_state_ = STATE_DRAIN_RESPONSE_BODY; int rv = DoLoop(OK); @@ -32,8 +33,6 @@ void HttpResponseBodyDrainer::Start(HttpNetworkSession* session) { if (rv == ERR_IO_PENDING) { timer_.Start(FROM_HERE, base::Seconds(kTimeoutInSeconds), this, &HttpResponseBodyDrainer::OnTimerFired); - session_ = session; - session->AddResponseDrainer(base::WrapUnique(this)); return; } @@ -110,9 +109,6 @@ void HttpResponseBodyDrainer::OnTimerFired() { void HttpResponseBodyDrainer::Finish(int result) { DCHECK_NE(ERR_IO_PENDING, result); - if (session_) - session_->RemoveResponseDrainer(this); - if (result < 0 || !stream_->CanReuseConnection()) { stream_->Close(true /* no keep-alive */); } else { @@ -120,7 +116,7 @@ void HttpResponseBodyDrainer::Finish(int result) { stream_->Close(false /* keep-alive */); } - delete this; + session_->RemoveResponseDrainer(this); } } // namespace net diff --git a/chromium/net/http/http_response_body_drainer.h b/chromium/net/http/http_response_body_drainer.h index 5ba92fa0be1..c1007ab08e7 100644 --- a/chromium/net/http/http_response_body_drainer.h +++ b/chromium/net/http/http_response_body_drainer.h @@ -33,8 +33,8 @@ class NET_EXPORT_PRIVATE HttpResponseBodyDrainer { ~HttpResponseBodyDrainer(); // Starts reading the body until completion, or we hit the buffer limit, or we - // timeout. After Start(), |this| will eventually delete itself. If it - // doesn't complete immediately, it will add itself to |session|. + // timeout. After Start(), |this| will eventually delete itself via + // HttpNetworkSession::RemoveResponseDrainer(). void Start(HttpNetworkSession* session); private: diff --git a/chromium/net/http/http_response_body_drainer_unittest.cc b/chromium/net/http/http_response_body_drainer_unittest.cc index 13cdd3c74eb..d4bc1bdec10 100644 --- a/chromium/net/http/http_response_body_drainer_unittest.cc +++ b/chromium/net/http/http_response_body_drainer_unittest.cc @@ -128,7 +128,7 @@ class MockHttpStream : public HttpStream { result_waiter_->set_result(not_reusable); } - HttpStream* RenewStreamForAuth() override { return nullptr; } + std::unique_ptr<HttpStream> RenewStreamForAuth() override { return nullptr; } bool IsResponseBodyComplete() const override { return is_complete_; } @@ -238,15 +238,16 @@ class HttpResponseBodyDrainerTest : public TestWithTaskEnvironment { HttpResponseBodyDrainerTest() : proxy_resolution_service_( ConfiguredProxyResolutionService::CreateDirect()), - ssl_config_service_(new SSLConfigServiceDefaults), - http_server_properties_(new HttpServerProperties()), + ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()), + http_server_properties_(std::make_unique<HttpServerProperties>()), session_(CreateNetworkSession()), - mock_stream_(new MockHttpStream(&result_waiter_)), - drainer_(new HttpResponseBodyDrainer(mock_stream_)) {} + mock_stream_(new MockHttpStream(&result_waiter_)) { + drainer_ = std::make_unique<HttpResponseBodyDrainer>(mock_stream_); + } ~HttpResponseBodyDrainerTest() override = default; - HttpNetworkSession* CreateNetworkSession() { + std::unique_ptr<HttpNetworkSession> CreateNetworkSession() { HttpNetworkSessionContext context; context.client_socket_factory = &socket_factory_; context.proxy_resolution_service = proxy_resolution_service_.get(); @@ -256,7 +257,8 @@ class HttpResponseBodyDrainerTest : public TestWithTaskEnvironment { context.transport_security_state = &transport_security_state_; context.ct_policy_enforcer = &ct_policy_enforcer_; context.quic_context = &quic_context_; - return new HttpNetworkSession(HttpNetworkSessionParams(), context); + return std::make_unique<HttpNetworkSession>(HttpNetworkSessionParams(), + context); } std::unique_ptr<ProxyResolutionService> proxy_resolution_service_; @@ -269,27 +271,27 @@ class HttpResponseBodyDrainerTest : public TestWithTaskEnvironment { MockClientSocketFactory socket_factory_; const std::unique_ptr<HttpNetworkSession> session_; CloseResultWaiter result_waiter_; - const raw_ptr<MockHttpStream> mock_stream_; // Owned by |drainer_|. - const raw_ptr<HttpResponseBodyDrainer> drainer_; // Deletes itself. + const raw_ptr<MockHttpStream> mock_stream_; // Owned by |drainer_|. + std::unique_ptr<HttpResponseBodyDrainer> drainer_; }; TEST_F(HttpResponseBodyDrainerTest, DrainBodySyncSingleOK) { mock_stream_->set_num_chunks(1); mock_stream_->set_sync(); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_FALSE(result_waiter_.WaitForResult()); } TEST_F(HttpResponseBodyDrainerTest, DrainBodySyncOK) { mock_stream_->set_num_chunks(3); mock_stream_->set_sync(); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_FALSE(result_waiter_.WaitForResult()); } TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncOK) { mock_stream_->set_num_chunks(3); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_FALSE(result_waiter_.WaitForResult()); } @@ -299,7 +301,7 @@ TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncOK) { TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncEmptyChunk) { mock_stream_->set_num_chunks(4); mock_stream_->set_is_last_chunk_zero_size(); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_FALSE(result_waiter_.WaitForResult()); } @@ -307,28 +309,28 @@ TEST_F(HttpResponseBodyDrainerTest, DrainBodySyncEmptyChunk) { mock_stream_->set_num_chunks(4); mock_stream_->set_sync(); mock_stream_->set_is_last_chunk_zero_size(); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_FALSE(result_waiter_.WaitForResult()); } TEST_F(HttpResponseBodyDrainerTest, DrainBodySizeEqualsDrainBuffer) { mock_stream_->set_num_chunks( HttpResponseBodyDrainer::kDrainBodyBufferSize / kMagicChunkSize); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_FALSE(result_waiter_.WaitForResult()); } TEST_F(HttpResponseBodyDrainerTest, DrainBodyTimeOut) { mock_stream_->set_num_chunks(2); mock_stream_->set_stall_reads_forever(); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_TRUE(result_waiter_.WaitForResult()); } TEST_F(HttpResponseBodyDrainerTest, CancelledBySession) { mock_stream_->set_num_chunks(2); mock_stream_->set_stall_reads_forever(); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); // HttpNetworkSession should delete |drainer_|. } @@ -338,14 +340,14 @@ TEST_F(HttpResponseBodyDrainerTest, DrainBodyTooLarge) { too_many_chunks += 1; // Now it's too large. mock_stream_->set_num_chunks(too_many_chunks); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_TRUE(result_waiter_.WaitForResult()); } TEST_F(HttpResponseBodyDrainerTest, DrainBodyCantReuse) { mock_stream_->set_num_chunks(1); mock_stream_->set_can_reuse_connection(false); - drainer_->Start(session_.get()); + session_->StartResponseDrainer(std::move(drainer_)); EXPECT_TRUE(result_waiter_.WaitForResult()); } diff --git a/chromium/net/http/http_response_headers.cc b/chromium/net/http/http_response_headers.cc index 727cebff27e..54a82879c64 100644 --- a/chromium/net/http/http_response_headers.cc +++ b/chromium/net/http/http_response_headers.cc @@ -110,13 +110,12 @@ const char* const kNonUpdatedHeaderPrefixes[] = { }; bool ShouldUpdateHeader(base::StringPiece name) { - for (size_t i = 0; i < std::size(kNonUpdatedHeaders); ++i) { - if (base::EqualsCaseInsensitiveASCII(name, kNonUpdatedHeaders[i])) + for (const auto* header : kNonUpdatedHeaders) { + if (base::EqualsCaseInsensitiveASCII(name, header)) return false; } - for (size_t i = 0; i < std::size(kNonUpdatedHeaderPrefixes); ++i) { - if (base::StartsWith(name, kNonUpdatedHeaderPrefixes[i], - base::CompareCase::INSENSITIVE_ASCII)) + for (const auto* prefix : kNonUpdatedHeaderPrefixes) { + if (base::StartsWith(name, prefix, base::CompareCase::INSENSITIVE_ASCII)) return false; } return true; @@ -141,6 +140,7 @@ void CheckDoesNotHaveEmbeddedNulls(base::StringPiece str) { const char HttpResponseHeaders::kContentRange[] = "Content-Range"; const char HttpResponseHeaders::kLastModified[] = "Last-Modified"; +const char HttpResponseHeaders::kVary[] = "Vary"; struct HttpResponseHeaders::ParsedHeader { // A header "continuation" contains only a subsequent value for the @@ -636,9 +636,9 @@ HttpVersion HttpResponseHeaders::ParseVersion( std::string::const_iterator line_end) { std::string::const_iterator p = line_begin; - // RFC2616 sec 3.1: HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT - // TODO: (1*DIGIT apparently means one or more digits, but we only handle 1). - // TODO: handle leading zeros, which is allowed by the rfc1616 sec 3.1. + // RFC9112 Section 2.3: + // HTTP-version = HTTP-name "/" DIGIT "." DIGIT + // HTTP-name = %s"HTTP" if (!base::StartsWith(base::MakeStringPiece(line_begin, line_end), "http", base::CompareCase::INSENSITIVE_ASCII)) { @@ -887,18 +887,18 @@ void HttpResponseHeaders::AddNonCacheableHeaders(HeaderSet* result) const { } void HttpResponseHeaders::AddHopByHopHeaders(HeaderSet* result) { - for (size_t i = 0; i < std::size(kHopByHopResponseHeaders); ++i) - result->insert(std::string(kHopByHopResponseHeaders[i])); + for (const auto* header : kHopByHopResponseHeaders) + result->insert(std::string(header)); } void HttpResponseHeaders::AddCookieHeaders(HeaderSet* result) { - for (size_t i = 0; i < std::size(kCookieResponseHeaders); ++i) - result->insert(std::string(kCookieResponseHeaders[i])); + for (const auto* header : kCookieResponseHeaders) + result->insert(std::string(header)); } void HttpResponseHeaders::AddChallengeHeaders(HeaderSet* result) { - for (size_t i = 0; i < std::size(kChallengeResponseHeaders); ++i) - result->insert(std::string(kChallengeResponseHeaders[i])); + for (const auto* header : kChallengeResponseHeaders) + result->insert(std::string(header)); } void HttpResponseHeaders::AddHopContentRangeHeaders(HeaderSet* result) { @@ -906,8 +906,8 @@ void HttpResponseHeaders::AddHopContentRangeHeaders(HeaderSet* result) { } void HttpResponseHeaders::AddSecurityStateHeaders(HeaderSet* result) { - for (size_t i = 0; i < std::size(kSecurityStateHeaders); ++i) - result->insert(std::string(kSecurityStateHeaders[i])); + for (const auto* header : kSecurityStateHeaders) + result->insert(std::string(header)); } void HttpResponseHeaders::GetMimeTypeAndCharset(std::string* mime_type, @@ -1373,8 +1373,8 @@ bool HttpResponseHeaders::GetContentRangeFor206( base::Value HttpResponseHeaders::NetLogParams( NetLogCaptureMode capture_mode) const { - base::Value dict(base::Value::Type::DICTIONARY); - base::Value headers(base::Value::Type::LIST); + base::Value::Dict dict; + base::Value::List headers; headers.Append(NetLogStringValue(GetStatusLine())); size_t iterator = 0; std::string name; @@ -1384,8 +1384,8 @@ base::Value HttpResponseHeaders::NetLogParams( ElideHeaderValueForNetLog(capture_mode, name, value); headers.Append(NetLogStringValue(base::StrCat({name, ": ", log_value}))); } - dict.SetKey("headers", std::move(headers)); - return dict; + dict.Set("headers", std::move(headers)); + return base::Value(std::move(dict)); } bool HttpResponseHeaders::IsChunkEncoded() const { diff --git a/chromium/net/http/http_response_headers.h b/chromium/net/http/http_response_headers.h index 469d5719f57..d49f1f66f36 100644 --- a/chromium/net/http/http_response_headers.h +++ b/chromium/net/http/http_response_headers.h @@ -64,6 +64,7 @@ class NET_EXPORT HttpResponseHeaders static const char kContentRange[]; static const char kLastModified[]; + static const char kVary[]; HttpResponseHeaders() = delete; diff --git a/chromium/net/http/http_response_headers_unittest.cc b/chromium/net/http/http_response_headers_unittest.cc index 79634446e54..0007e534e87 100644 --- a/chromium/net/http/http_response_headers_unittest.cc +++ b/chromium/net/http/http_response_headers_unittest.cc @@ -59,7 +59,7 @@ class HttpResponseHeadersCacheControlTest : public HttpResponseHeadersTest { raw_headers += cache_control; raw_headers += "\n"; HeadersToRaw(&raw_headers); - headers_ = new HttpResponseHeaders(raw_headers); + headers_ = base::MakeRefCounted<HttpResponseHeaders>(raw_headers); } const scoped_refptr<HttpResponseHeaders>& headers() { return headers_; } @@ -138,8 +138,7 @@ TEST_P(CommonHttpResponseHeadersTest, TestCommon) { HeadersToRaw(&raw_headers); std::string expected_headers(test.expected_headers); - scoped_refptr<HttpResponseHeaders> parsed( - new HttpResponseHeaders(raw_headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(raw_headers); std::string headers = ToSimpleString(parsed); // Transform to readable output format (so it's easier to see diffs). @@ -325,13 +324,13 @@ TEST_P(PersistenceTest, Persist) { std::string headers = test.raw_headers; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed1(new HttpResponseHeaders(headers)); + auto parsed1 = base::MakeRefCounted<HttpResponseHeaders>(headers); base::Pickle pickle; parsed1->Persist(&pickle, test.options); base::PickleIterator iter(pickle); - scoped_refptr<HttpResponseHeaders> parsed2(new HttpResponseHeaders(&iter)); + auto parsed2 = base::MakeRefCounted<HttpResponseHeaders>(&iter); EXPECT_EQ(std::string(test.expected_headers), ToSimpleString(parsed2)); } @@ -507,7 +506,7 @@ TEST(HttpResponseHeadersTest, EnumerateHeader_Coalesced) { "cache-Control: no-store\n" "cache-Control:\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); size_t iter = 0; std::string value; @@ -536,7 +535,7 @@ TEST(HttpResponseHeadersTest, EnumerateHeader_Challenge) { "WWW-Authenticate:Digest realm=foobar, nonce=x, domain=y\n" "WWW-Authenticate:Basic realm=quatar\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); size_t iter = 0; std::string value; @@ -555,7 +554,7 @@ TEST(HttpResponseHeadersTest, EnumerateHeader_DateValued) { "Date: Tue, 07 Aug 2007 23:10:55 GMT\n" "Last-Modified: Wed, 01 Aug 2007 23:23:45 GMT\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); std::string value; EXPECT_TRUE(parsed->EnumerateHeader(nullptr, "date", &value)); @@ -573,7 +572,7 @@ TEST(HttpResponseHeadersTest, DefaultDateToGMT) { "Last-Modified: Tue, 07 Aug 2007 19:10:55 EDT\n" "Expires: Tue, 07 Aug 2007 23:10:55 UTC\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); base::Time expected_value; ASSERT_TRUE(base::Time::FromString("Tue, 07 Aug 2007 23:10:55 GMT", &expected_value)); @@ -598,7 +597,7 @@ TEST(HttpResponseHeadersTest, GetAgeValue10) { "HTTP/1.1 200 OK\n" "Age: 10\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); base::TimeDelta age; ASSERT_TRUE(parsed->GetAgeValue(&age)); EXPECT_EQ(10, age.InSeconds()); @@ -609,7 +608,7 @@ TEST(HttpResponseHeadersTest, GetAgeValue0) { "HTTP/1.1 200 OK\n" "Age: 0\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); base::TimeDelta age; ASSERT_TRUE(parsed->GetAgeValue(&age)); EXPECT_EQ(0, age.InSeconds()); @@ -620,7 +619,7 @@ TEST(HttpResponseHeadersTest, GetAgeValueBogus) { "HTTP/1.1 200 OK\n" "Age: donkey\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); base::TimeDelta age; ASSERT_FALSE(parsed->GetAgeValue(&age)); } @@ -630,7 +629,7 @@ TEST(HttpResponseHeadersTest, GetAgeValueNegative) { "HTTP/1.1 200 OK\n" "Age: -10\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); base::TimeDelta age; ASSERT_FALSE(parsed->GetAgeValue(&age)); } @@ -640,7 +639,7 @@ TEST(HttpResponseHeadersTest, GetAgeValueLeadingPlus) { "HTTP/1.1 200 OK\n" "Age: +10\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); base::TimeDelta age; ASSERT_FALSE(parsed->GetAgeValue(&age)); } @@ -650,7 +649,7 @@ TEST(HttpResponseHeadersTest, GetAgeValueOverflow) { "HTTP/1.1 200 OK\n" "Age: 999999999999999999999999999999999999999999\n"; HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); base::TimeDelta age; ASSERT_TRUE(parsed->GetAgeValue(&age)); @@ -677,7 +676,7 @@ TEST_P(ContentTypeTest, GetMimeType) { std::string headers(test.raw_headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); std::string value; EXPECT_EQ(test.has_mimetype, parsed->GetMimeType(&value)); @@ -850,7 +849,7 @@ TEST_P(RequiresValidationTest, RequiresValidation) { std::string headers(test.headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); ValidationType validation_type = parsed->RequiresValidation(request_time, response_time, current_time); @@ -1041,13 +1040,11 @@ TEST_P(UpdateTest, Update) { std::string orig_headers(test.orig_headers); HeadersToRaw(&orig_headers); - scoped_refptr<HttpResponseHeaders> parsed( - new HttpResponseHeaders(orig_headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(orig_headers); std::string new_headers(test.new_headers); HeadersToRaw(&new_headers); - scoped_refptr<HttpResponseHeaders> new_parsed( - new HttpResponseHeaders(new_headers)); + auto new_parsed = base::MakeRefCounted<HttpResponseHeaders>(new_headers); parsed->Update(*new_parsed.get()); @@ -1177,7 +1174,7 @@ TEST_P(EnumerateHeaderLinesTest, EnumerateHeaderLines) { std::string headers(test.headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); std::string name, value, lines; @@ -1236,7 +1233,7 @@ TEST_P(IsRedirectTest, IsRedirect) { std::string headers(test.headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); std::string location; EXPECT_EQ(parsed->IsRedirect(&location), test.is_redirect); @@ -1322,7 +1319,7 @@ TEST_P(GetContentLengthTest, GetContentLength) { std::string headers(test.headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); EXPECT_EQ(test.expected_len, parsed->GetContentLength()); } @@ -1402,7 +1399,7 @@ TEST_P(ContentRangeTest, GetContentRangeFor206) { std::string headers(test.headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); int64_t first_byte_position; int64_t last_byte_position; @@ -1461,7 +1458,7 @@ TEST_P(IsKeepAliveTest, IsKeepAlive) { std::string headers(test.headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); EXPECT_EQ(test.expected_keep_alive, parsed->IsKeepAlive()); } @@ -1621,7 +1618,7 @@ TEST_P(HasStrongValidatorsTest, HasStrongValidators) { std::string headers(test.headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); EXPECT_EQ(test.expected_result, parsed->HasStrongValidators()); } @@ -1679,7 +1676,7 @@ INSTANTIATE_TEST_SUITE_P(HttpResponseHeaders, TEST(HttpResponseHeadersTest, HasValidatorsNone) { std::string headers("HTTP/1.1 200 OK"); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); EXPECT_FALSE(parsed->HasValidators()); } @@ -1688,7 +1685,7 @@ TEST(HttpResponseHeadersTest, HasValidatorsEtag) { "HTTP/1.1 200 OK\n" "etag: \"anything\""); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); EXPECT_TRUE(parsed->HasValidators()); } @@ -1697,7 +1694,7 @@ TEST(HttpResponseHeadersTest, HasValidatorsLastModified) { "HTTP/1.1 200 OK\n" "Last-Modified: Wed, 28 Nov 2007 00:40:10 GMT"); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); EXPECT_TRUE(parsed->HasValidators()); } @@ -1706,7 +1703,7 @@ TEST(HttpResponseHeadersTest, HasValidatorsWeakEtag) { "HTTP/1.1 200 OK\n" "etag: W/\"anything\""); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); EXPECT_TRUE(parsed->HasValidators()); } @@ -1853,8 +1850,7 @@ TEST_P(RemoveHeaderTest, RemoveHeader) { std::string orig_headers(test.orig_headers); HeadersToRaw(&orig_headers); - scoped_refptr<HttpResponseHeaders> parsed( - new HttpResponseHeaders(orig_headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(orig_headers); std::string name(test.to_remove); parsed->RemoveHeader(name); @@ -1906,8 +1902,7 @@ TEST_P(RemoveHeadersTest, RemoveHeaders) { std::string orig_headers(test.orig_headers); HeadersToRaw(&orig_headers); - scoped_refptr<HttpResponseHeaders> parsed( - new HttpResponseHeaders(orig_headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(orig_headers); std::unordered_set<std::string> to_remove; for (auto* header : test.to_remove) { @@ -1970,8 +1965,7 @@ TEST_P(RemoveIndividualHeaderTest, RemoveIndividualHeader) { std::string orig_headers(test.orig_headers); HeadersToRaw(&orig_headers); - scoped_refptr<HttpResponseHeaders> parsed( - new HttpResponseHeaders(orig_headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(orig_headers); std::string name(test.to_remove_name); std::string value(test.to_remove_value); @@ -2072,8 +2066,7 @@ TEST_P(ReplaceStatusTest, ReplaceStatus) { std::string orig_headers(test.orig_headers); HeadersToRaw(&orig_headers); - scoped_refptr<HttpResponseHeaders> parsed( - new HttpResponseHeaders(orig_headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(orig_headers); std::string name(test.new_status); parsed->ReplaceStatusLine(name); @@ -2138,8 +2131,7 @@ TEST_P(UpdateWithNewRangeTest, UpdateWithNewRange) { std::string orig_headers(test.orig_headers); std::replace(orig_headers.begin(), orig_headers.end(), '\n', '\0'); - scoped_refptr<HttpResponseHeaders> parsed( - new HttpResponseHeaders(orig_headers + '\0')); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(orig_headers + '\0'); int64_t content_size = parsed->GetContentLength(); // Update headers without replacing status line. @@ -2342,7 +2334,7 @@ TEST_P(GetCurrentAgeTest, GetCurrentAge) { std::string headers(test.headers); HeadersToRaw(&headers); - scoped_refptr<HttpResponseHeaders> parsed(new HttpResponseHeaders(headers)); + auto parsed = base::MakeRefCounted<HttpResponseHeaders>(headers); base::TimeDelta age = parsed->GetCurrentAge(request_time, response_time, current_time); diff --git a/chromium/net/http/http_response_info.cc b/chromium/net/http/http_response_info.cc index e96d6da97c1..d0b6fc231c3 100644 --- a/chromium/net/http/http_response_info.cc +++ b/chromium/net/http/http_response_info.cc @@ -121,8 +121,12 @@ enum { // unusable due to the checksum not matching. RESPONSE_INFO_SINGLE_KEYED_CACHE_ENTRY_UNUSABLE = 1 << 28, - // TODO(darin): Add other bits to indicate alternate request methods. - // For now, we don't support storing those. + // This bit is set if the response has `encrypted_client_hello` set. + RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO = 1 << 29, + + // This enum only has a few bits (`1 << 31` is the limit). If allocating the + // last flag, instead allocate it as `RESPONSE_INFO_HAS_EXTRA_FLAGS` to + // signal another flags word. }; HttpResponseInfo::ConnectionInfoCoarse HttpResponseInfo::ConnectionInfoToCoarse( @@ -224,7 +228,7 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle, response_time = Time::FromInternalValue(time_val); // Read response-headers - headers = new HttpResponseHeaders(&iter); + headers = base::MakeRefCounted<HttpResponseHeaders>(&iter); if (headers->response_code() == -1) return false; @@ -381,6 +385,9 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle, } } + ssl_info.encrypted_client_hello = + (flags & RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO) != 0; + return true; } @@ -426,6 +433,8 @@ void HttpResponseInfo::Persist(base::Pickle* pickle, flags |= RESPONSE_INFO_HAS_STALENESS; if (!dns_aliases.empty()) flags |= RESPONSE_INFO_HAS_DNS_ALIASES; + if (ssl_info.encrypted_client_hello) + flags |= RESPONSE_INFO_ENCRYPTED_CLIENT_HELLO; pickle->WriteInt(flags); pickle->WriteInt64(request_time.ToInternalValue()); diff --git a/chromium/net/http/http_response_info.h b/chromium/net/http/http_response_info.h index e09a96c4b5c..b96254383e8 100644 --- a/chromium/net/http/http_response_info.h +++ b/chromium/net/http/http_response_info.h @@ -252,6 +252,8 @@ class NET_EXPORT HttpResponseInfo { scoped_refptr<HttpResponseHeaders> headers; // The "Vary" header data for this response. + // Initialized and used by HttpCache::Transaction. May also be passed to an + // auxiliary in-memory cache in the network service. HttpVaryData vary_data; // Any DNS aliases for the remote endpoint. Includes all known aliases, e.g. diff --git a/chromium/net/http/http_response_info_unittest.cc b/chromium/net/http/http_response_info_unittest.cc index 43c8770a273..921c71ca66a 100644 --- a/chromium/net/http/http_response_info_unittest.cc +++ b/chromium/net/http/http_response_info_unittest.cc @@ -22,7 +22,7 @@ namespace { class HttpResponseInfoTest : public testing::Test { protected: void SetUp() override { - response_info_.headers = new HttpResponseHeaders(""); + response_info_.headers = base::MakeRefCounted<HttpResponseHeaders>(""); } void PickleAndRestore(const HttpResponseInfo& response_info, @@ -196,6 +196,24 @@ TEST_F(HttpResponseInfoTest, PeerSignatureAlgorithm) { EXPECT_EQ(0x0804, restored_response_info.ssl_info.peer_signature_algorithm); } +// Test that encrypted_client_hello is preserved. +TEST_F(HttpResponseInfoTest, EncryptedClientHello) { + response_info_.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); + { + net::HttpResponseInfo restored_response_info; + PickleAndRestore(response_info_, &restored_response_info); + EXPECT_FALSE(restored_response_info.ssl_info.encrypted_client_hello); + } + + response_info_.ssl_info.encrypted_client_hello = true; + { + net::HttpResponseInfo restored_response_info; + PickleAndRestore(response_info_, &restored_response_info); + EXPECT_TRUE(restored_response_info.ssl_info.encrypted_client_hello); + } +} + // Tests that cache entries loaded over SSLv3 (no longer supported) are dropped. TEST_F(HttpResponseInfoTest, FailsInitFromPickleWithSSLV3) { // A valid certificate is needed for ssl_info.is_valid() to be true. diff --git a/chromium/net/http/http_server_properties.cc b/chromium/net/http/http_server_properties.cc index 3adcc93fcbd..887ffee8148 100644 --- a/chromium/net/http/http_server_properties.cc +++ b/chromium/net/http/http_server_properties.cc @@ -378,11 +378,11 @@ void HttpServerProperties::OnDefaultNetworkChanged() { base::Value HttpServerProperties::GetAlternativeServiceInfoAsValue() const { const base::Time now = clock_->Now(); const base::TimeTicks now_ticks = tick_clock_->NowTicks(); - base::Value dict_list(base::Value::Type::LIST); + base::Value::List dict_list; for (const auto& server_info : server_info_map_) { if (!server_info.second.alternative_services.has_value()) continue; - base::Value alternative_service_list(base::Value::Type::LIST); + base::Value::List alternative_service_list; const ServerInfoMapKey& key = server_info.first; for (const AlternativeServiceInfo& alternative_service_info : server_info.second.alternative_services.value()) { @@ -415,16 +415,16 @@ base::Value HttpServerProperties::GetAlternativeServiceInfoAsValue() const { } alternative_service_list.Append(std::move(alternative_service_string)); } - if (alternative_service_list.GetListDeprecated().empty()) + if (alternative_service_list.empty()) continue; - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("server", key.server.Serialize()); - dict.SetStringKey("network_isolation_key", - key.network_isolation_key.ToDebugString()); - dict.SetKey("alternative_service", std::move(alternative_service_list)); + base::Value::Dict dict; + dict.Set("server", key.server.Serialize()); + dict.Set("network_isolation_key", + key.network_isolation_key.ToDebugString()); + dict.Set("alternative_service", std::move(alternative_service_list)); dict_list.Append(std::move(dict)); } - return dict_list; + return base::Value(std::move(dict_list)); } bool HttpServerProperties::WasLastLocalAddressWhenQuicWorked( @@ -1151,19 +1151,19 @@ void HttpServerProperties::OnServerInfoLoaded( // Attempt to find canonical servers. Canonical suffix only apply to HTTPS. const uint16_t kCanonicalPort = 443; const char* kCanonicalScheme = "https"; - for (auto it = server_info_map_.begin(); it != server_info_map_.end(); ++it) { - if (!it->second.alternative_services || - it->first.server.scheme() != kCanonicalScheme) { + for (const auto& it : server_info_map_) { + if (!it.second.alternative_services || + it.first.server.scheme() != kCanonicalScheme) { continue; } const std::string* canonical_suffix = - GetCanonicalSuffix(it->first.server.host()); + GetCanonicalSuffix(it.first.server.host()); if (!canonical_suffix) continue; ServerInfoMapKey key = CreateServerInfoKey( url::SchemeHostPort(kCanonicalScheme, *canonical_suffix, kCanonicalPort), - it->first.network_isolation_key); + it.first.network_isolation_key); // If we already have a valid canonical server, we're done. if (base::Contains(canonical_alt_svc_map_, key)) { auto key_it = server_info_map_.Peek(key); @@ -1172,7 +1172,7 @@ void HttpServerProperties::OnServerInfoLoaded( continue; } } - canonical_alt_svc_map_[key] = it->first.server; + canonical_alt_svc_map_[key] = it.first.server; } } diff --git a/chromium/net/http/http_server_properties.h b/chromium/net/http/http_server_properties.h index 94c1573e620..e262aad6098 100644 --- a/chromium/net/http/http_server_properties.h +++ b/chromium/net/http/http_server_properties.h @@ -234,10 +234,11 @@ class NET_EXPORT HttpServerProperties // // |clock| is used for converting base::TimeTicks to base::Time for // wherever base::Time is preferable. - HttpServerProperties(std::unique_ptr<PrefDelegate> pref_delegate = nullptr, - NetLog* net_log = nullptr, - const base::TickClock* tick_clock = nullptr, - base::Clock* clock = nullptr); + explicit HttpServerProperties( + std::unique_ptr<PrefDelegate> pref_delegate = nullptr, + NetLog* net_log = nullptr, + const base::TickClock* tick_clock = nullptr, + base::Clock* clock = nullptr); HttpServerProperties(const HttpServerProperties&) = delete; HttpServerProperties& operator=(const HttpServerProperties&) = delete; @@ -464,6 +465,15 @@ class NET_EXPORT HttpServerProperties return server_info_map_; } + const BrokenAlternativeServices& broken_alternative_services_for_testing() + const { + return broken_alternative_services_; + } + + const QuicServerInfoMap& quic_server_info_map_for_testing() const { + return quic_server_info_map_; + } + // TODO(mmenke): Look into removing this. HttpServerPropertiesManager* properties_manager_for_testing() { return properties_manager_.get(); diff --git a/chromium/net/http/http_server_properties_manager.cc b/chromium/net/http/http_server_properties_manager.cc index 7f7e696bea7..a383e1c7d79 100644 --- a/chromium/net/http/http_server_properties_manager.cc +++ b/chromium/net/http/http_server_properties_manager.cc @@ -4,6 +4,7 @@ #include "net/http/http_server_properties_manager.h" +#include <algorithm> #include <utility> #include "base/bind.h" @@ -246,9 +247,9 @@ void HttpServerPropertiesManager::ReadPrefs( } // For Version 5, data is stored in the following format. - // |servers| are saved in MRU order. |servers| are in the format flattened - // representation of (scheme/host/port) where port might be ignored if is - // default with scheme. + // `servers` are saved in LRU order (least-recently-used item is in the + // front). `servers` are in the format flattened representation of + // (scheme/host/port) where port might be ignored if is default with scheme. // // "http_server_properties": { // "servers": [ @@ -276,16 +277,14 @@ void HttpServerPropertiesManager::ReadPrefs( bool use_network_isolation_key = base::FeatureList::IsEnabled( features::kPartitionHttpServerPropertiesByNetworkIsolationKey); - // Iterate servers list in reverse MRU order so that entries are inserted - // into |spdy_servers_map|, |alternative_service_map|, and - // |server_network_stats_map| from oldest to newest. - for (auto it = servers_list->end(); it != servers_list->begin();) { - --it; - if (!it->is_dict()) { + // Iterate `servers_list` (least-recently-used item is in the front) so that + // entries are inserted into `server_info_map` from oldest to newest. + for (const auto& server_dict_value : *servers_list) { + if (!server_dict_value.is_dict()) { DVLOG(1) << "Malformed http_server_properties for servers dictionary."; continue; } - AddServerData(it->GetDict(), server_info_map->get(), + AddServerData(server_dict_value.GetDict(), server_info_map->get(), use_network_isolation_key); } @@ -303,16 +302,16 @@ void HttpServerPropertiesManager::ReadPrefs( std::make_unique<RecentlyBrokenAlternativeServices>( kMaxRecentlyBrokenAlternativeServiceEntries); - // Iterate list in reverse-MRU order - for (auto it = broken_alt_svc_list->end(); - it != broken_alt_svc_list->begin();) { - --it; - if (!it->is_dict()) { + // Iterate `broken_alt_svc_list` (least-recently-used item is in the front) + // so that entries are inserted into `recently_broken_alternative_services` + // from oldest to newest. + for (const auto& broken_alt_svc_entry_dict_value : *broken_alt_svc_list) { + if (!broken_alt_svc_entry_dict_value.is_dict()) { DVLOG(1) << "Malformed broken alterantive service entry."; continue; } AddToBrokenAlternativeServices( - it->GetDict(), use_network_isolation_key, + broken_alt_svc_entry_dict_value.GetDict(), use_network_isolation_key, broken_alternative_service_list->get(), recently_broken_alternative_services->get()); } @@ -710,14 +709,12 @@ void HttpServerPropertiesManager::WriteToPrefs( std::set<std::pair<std::string, NetworkIsolationKey>> persisted_canonical_suffix_set; const base::Time now = base::Time::Now(); - base::Value http_server_properties_value(base::Value::Type::DICTIONARY); - base::Value::Dict& http_server_properties_dict = - http_server_properties_value.GetDict(); + base::Value::Dict http_server_properties_dict; // Convert |server_info_map| to a list Value and add it to // |http_server_properties_dict|. base::Value::List servers_list; - for (const auto& [key, server_info] : base::Reversed(server_info_map)) { + for (const auto& [key, server_info] : server_info_map) { // If can't convert the NetworkIsolationKey to a value, don't save to disk. // Generally happens because the key is for a unique origin. base::Value network_isolation_key_value; @@ -752,6 +749,9 @@ void HttpServerPropertiesManager::WriteToPrefs( std::move(network_isolation_key_value)); servers_list.Append(std::move(server_dict)); } + // Reverse `servers_list`. The least recently used item will be in the front. + std::reverse(servers_list.begin(), servers_list.end()); + http_server_properties_dict.Set(kServersKey, std::move(servers_list)); http_server_properties_dict.Set(kVersionKey, kVersionNumber); @@ -766,11 +766,12 @@ void HttpServerPropertiesManager::WriteToPrefs( broken_alternative_service_list, kMaxBrokenAlternativeServicesToPersist, recently_broken_alternative_services, http_server_properties_dict); - pref_delegate_->SetServerProperties(http_server_properties_value, - std::move(callback)); + pref_delegate_->SetServerProperties( + base::Value(http_server_properties_dict.Clone()), std::move(callback)); - net_log_.AddEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_UPDATE_PREFS, - [&] { return http_server_properties_value.Clone(); }); + net_log_.AddEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_UPDATE_PREFS, [&] { + return base::Value(std::move(http_server_properties_dict)); + }); } void HttpServerPropertiesManager::SaveAlternativeServiceToServerPrefs( @@ -868,8 +869,8 @@ void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs( return; } - // JSON list will be in MRU order according to - // |recently_broken_alternative_services|. + // JSON list will be in LRU order (least-recently-used item is in the front) + // according to `recently_broken_alternative_services`. base::Value::List json_list; // Maps recently-broken alternative services to the index where it's stored diff --git a/chromium/net/http/http_server_properties_manager_unittest.cc b/chromium/net/http/http_server_properties_manager_unittest.cc index df6ed2e114e..3ba9c9b6249 100644 --- a/chromium/net/http/http_server_properties_manager_unittest.cc +++ b/chromium/net/http/http_server_properties_manager_unittest.cc @@ -225,11 +225,11 @@ class HttpServerPropertiesManagerTest : public testing::Test, void SetUp() override { one_day_from_now_ = base::Time::Now() + base::Days(1); advertised_versions_ = DefaultSupportedQuicVersions(); - pref_delegate_ = new MockPrefDelegate; + auto pref_delegate = std::make_unique<MockPrefDelegate>(); + pref_delegate_ = pref_delegate.get(); http_server_props_ = std::make_unique<HttpServerProperties>( - base::WrapUnique(pref_delegate_.get()), /*net_log=*/nullptr, - GetMockTickClock()); + std::move(pref_delegate), /*net_log=*/nullptr, GetMockTickClock()); EXPECT_FALSE(http_server_props_->IsInitialized()); EXPECT_EQ(0u, GetPendingMainThreadTaskCount()); @@ -2376,22 +2376,19 @@ TEST_F(HttpServerPropertiesManagerTest, std::move(pref_delegate), /*net_log=*/nullptr, GetMockTickClock()); unowned_pref_delegate->InitializePrefs(saved_value); - // Only the first of the values learned for kNetworkIsolationKey1 should have + // Only the last of the values learned for kNetworkIsolationKey1 should have // been saved, and the value for kNetworkIsolationKey2 as well. The canonical // suffix logic should still be respected. - // - // TODO(mmenke): Preferring the oldest value seems unexpected. - // https://crbug.com/994842. EXPECT_EQ( - 1u, + 2u, properties->GetAlternativeServiceInfos(kServer1, kNetworkIsolationKey1) .size()); EXPECT_EQ( - 1u, + 2u, properties->GetAlternativeServiceInfos(kServer2, kNetworkIsolationKey1) .size()); EXPECT_EQ( - 1u, + 2u, properties->GetAlternativeServiceInfos(kServer3, kNetworkIsolationKey1) .size()); EXPECT_EQ( @@ -3050,4 +3047,153 @@ TEST_F(HttpServerPropertiesManagerTest, AdvertisedVersionsRoundTrip) { } } +TEST_F(HttpServerPropertiesManagerTest, SameOrderAfterReload) { + const SchemefulSite kSite1(GURL("https://foo.test/")); + const SchemefulSite kSite2(GURL("https://bar.test/")); + const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1); + const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2); + + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + features::kPartitionHttpServerPropertiesByNetworkIsolationKey); + + // Create and initialize an HttpServerProperties with no state. + std::unique_ptr<MockPrefDelegate> pref_delegate = + std::make_unique<MockPrefDelegate>(); + MockPrefDelegate* unowned_pref_delegate = pref_delegate.get(); + std::unique_ptr<HttpServerProperties> properties = + std::make_unique<HttpServerProperties>(std::move(pref_delegate), + /*net_log=*/nullptr, + GetMockTickClock()); + unowned_pref_delegate->InitializePrefs( + base::Value(base::Value::Type::DICTIONARY)); + + // Set alternative_service info. + base::Time expiration = base::Time::Now() + base::Days(1); + AlternativeServiceInfo alt_service1 = + AlternativeServiceInfo::CreateQuicAlternativeServiceInfo( + AlternativeService(kProtoQUIC, "1.example", 1234), expiration, + DefaultSupportedQuicVersions()); + AlternativeServiceInfo alt_service2 = + AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo( + AlternativeService(kProtoHTTP2, "2.example", 443), expiration); + AlternativeServiceInfo alt_service3 = + AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo( + AlternativeService(kProtoHTTP2, "3.example", 443), expiration); + const url::SchemeHostPort kServer1("https", "1.example", 443); + const url::SchemeHostPort kServer2("https", "2.example", 443); + const url::SchemeHostPort kServer3("https", "3.example", 443); + properties->SetAlternativeServices(kServer1, kNetworkIsolationKey1, + {alt_service1}); + properties->SetAlternativeServices(kServer2, kNetworkIsolationKey1, + {alt_service2}); + properties->SetAlternativeServices(kServer3, kNetworkIsolationKey2, + {alt_service3}); + + // Set quic_server_info. + quic::QuicServerId quic_server_id1("quic1.example", 80, false); + quic::QuicServerId quic_server_id2("quic2.example", 80, false); + quic::QuicServerId quic_server_id3("quic3.example", 80, false); + properties->SetQuicServerInfo(quic_server_id1, kNetworkIsolationKey1, + "quic_server_info1"); + properties->SetQuicServerInfo(quic_server_id2, kNetworkIsolationKey1, + "quic_server_info2"); + properties->SetQuicServerInfo(quic_server_id3, kNetworkIsolationKey2, + "quic_server_info3"); + + // Set broken_alternative_service info. + AlternativeService broken_service1(kProtoQUIC, "broken1.example", 443); + AlternativeService broken_service2(kProtoQUIC, "broken2.example", 443); + AlternativeService broken_service3(kProtoQUIC, "broken3.example", 443); + properties->MarkAlternativeServiceBroken(broken_service1, + kNetworkIsolationKey1); + FastForwardBy(base::Milliseconds(1)); + properties->MarkAlternativeServiceBroken(broken_service2, + kNetworkIsolationKey1); + FastForwardBy(base::Milliseconds(1)); + properties->MarkAlternativeServiceBroken(broken_service3, + kNetworkIsolationKey2); + + // The first item of `server_info_map` must be the latest item. + EXPECT_EQ(3u, properties->server_info_map_for_testing().size()); + EXPECT_EQ( + properties->server_info_map_for_testing().begin()->first.server.host(), + "3.example"); + + // The first item of `recently_broken_alternative_services` must be the latest + // item. + EXPECT_EQ(3u, properties->broken_alternative_services_for_testing() + .recently_broken_alternative_services() + .size()); + EXPECT_EQ("broken3.example", + properties->broken_alternative_services_for_testing() + .recently_broken_alternative_services() + .begin() + ->first.alternative_service.host); + + // The first item of `quic_server_info_map` must be the latest item. + EXPECT_EQ(3u, properties->quic_server_info_map_for_testing().size()); + EXPECT_EQ("quic3.example", properties->quic_server_info_map_for_testing() + .begin() + ->first.server_id.host()); + + // The first item of `broken_alternative_service_list` must be the oldest + // item. + EXPECT_EQ(3u, properties->broken_alternative_services_for_testing() + .broken_alternative_service_list() + .size()); + EXPECT_EQ("broken1.example", + properties->broken_alternative_services_for_testing() + .broken_alternative_service_list() + .begin() + ->first.alternative_service.host); + + // Wait until the data's been written to prefs, and then tear down the + // HttpServerProperties. + FastForwardBy(HttpServerProperties::GetUpdatePrefsDelayForTesting()); + base::Value saved_value = + unowned_pref_delegate->GetServerProperties()->Clone(); + + // Create a new HttpServerProperties using the value saved to prefs above. + pref_delegate = std::make_unique<MockPrefDelegate>(); + unowned_pref_delegate = pref_delegate.get(); + properties = std::make_unique<HttpServerProperties>( + std::move(pref_delegate), /*net_log=*/nullptr, GetMockTickClock()); + unowned_pref_delegate->InitializePrefs(saved_value); + + // The first item of `server_info_map` must be the latest item. + EXPECT_EQ(3u, properties->server_info_map_for_testing().size()); + EXPECT_EQ( + properties->server_info_map_for_testing().begin()->first.server.host(), + "3.example"); + + // The first item of `recently_broken_alternative_services` must be the latest + // item. + EXPECT_EQ(3u, properties->broken_alternative_services_for_testing() + .recently_broken_alternative_services() + .size()); + EXPECT_EQ("broken3.example", + properties->broken_alternative_services_for_testing() + .recently_broken_alternative_services() + .begin() + ->first.alternative_service.host); + + // The first item of `quic_server_info_map` must be the latest item. + EXPECT_EQ(3u, properties->quic_server_info_map_for_testing().size()); + EXPECT_EQ("quic3.example", properties->quic_server_info_map_for_testing() + .begin() + ->first.server_id.host()); + + // The first item of `broken_alternative_service_list` must be the oldest + // item. + EXPECT_EQ(3u, properties->broken_alternative_services_for_testing() + .broken_alternative_service_list() + .size()); + EXPECT_EQ("broken1.example", + properties->broken_alternative_services_for_testing() + .broken_alternative_service_list() + .begin() + ->first.alternative_service.host); +} + } // namespace net diff --git a/chromium/net/http/http_status_code.cc b/chromium/net/http/http_status_code.cc index 84d8c23e36d..7ad16c916f5 100644 --- a/chromium/net/http/http_status_code.cc +++ b/chromium/net/http/http_status_code.cc @@ -12,10 +12,11 @@ namespace net { const char* GetHttpReasonPhrase(HttpStatusCode code) { switch (code) { - -#define HTTP_STATUS(label, code, reason) case HTTP_ ## label: return reason; +#define HTTP_STATUS_ENUM_VALUE(label, code, reason) \ + case HTTP_##label: \ + return reason; #include "net/http/http_status_code_list.h" -#undef HTTP_STATUS +#undef HTTP_STATUS_ENUM_VALUE default: NOTREACHED() << "unknown HTTP status code " << code; diff --git a/chromium/net/http/http_status_code.h b/chromium/net/http/http_status_code.h index a4b398b5038..37407e14c20 100644 --- a/chromium/net/http/http_status_code.h +++ b/chromium/net/http/http_status_code.h @@ -12,9 +12,9 @@ namespace net { // HTTP status codes. enum HttpStatusCode { -#define HTTP_STATUS(label, code, reason) HTTP_ ## label = code, +#define HTTP_STATUS_ENUM_VALUE(label, code, reason) HTTP_##label = code, #include "net/http/http_status_code_list.h" -#undef HTTP_STATUS +#undef HTTP_STATUS_ENUM_VALUE }; diff --git a/chromium/net/http/http_status_code_list.h b/chromium/net/http/http_status_code_list.h index 669b3724340..b690287b348 100644 --- a/chromium/net/http/http_status_code_list.h +++ b/chromium/net/http/http_status_code_list.h @@ -12,64 +12,71 @@ // Code Registry. // http://www.iana.org/assignments/http-status-codes/http-status-codes.xml -#ifndef HTTP_STATUS +#ifndef HTTP_STATUS_ENUM_VALUE #error "Do #include net/http/http_status_code.h instead of this file directly." #endif // Informational 1xx -HTTP_STATUS(CONTINUE, 100, "Continue") -HTTP_STATUS(SWITCHING_PROTOCOLS, 101, "Switching Protocols") -HTTP_STATUS(EARLY_HINTS, 103, "Early Hints") +HTTP_STATUS_ENUM_VALUE(CONTINUE, 100, "Continue") +HTTP_STATUS_ENUM_VALUE(SWITCHING_PROTOCOLS, 101, "Switching Protocols") +HTTP_STATUS_ENUM_VALUE(EARLY_HINTS, 103, "Early Hints") // Successful 2xx -HTTP_STATUS(OK, 200, "OK") -HTTP_STATUS(CREATED, 201, "Created") -HTTP_STATUS(ACCEPTED, 202, "Accepted") -HTTP_STATUS(NON_AUTHORITATIVE_INFORMATION, 203, "Non-Authoritative Information") -HTTP_STATUS(NO_CONTENT, 204, "No Content") -HTTP_STATUS(RESET_CONTENT, 205, "Reset Content") -HTTP_STATUS(PARTIAL_CONTENT, 206, "Partial Content") +HTTP_STATUS_ENUM_VALUE(OK, 200, "OK") +HTTP_STATUS_ENUM_VALUE(CREATED, 201, "Created") +HTTP_STATUS_ENUM_VALUE(ACCEPTED, 202, "Accepted") +HTTP_STATUS_ENUM_VALUE(NON_AUTHORITATIVE_INFORMATION, + 203, + "Non-Authoritative Information") +HTTP_STATUS_ENUM_VALUE(NO_CONTENT, 204, "No Content") +HTTP_STATUS_ENUM_VALUE(RESET_CONTENT, 205, "Reset Content") +HTTP_STATUS_ENUM_VALUE(PARTIAL_CONTENT, 206, "Partial Content") // Redirection 3xx -HTTP_STATUS(MULTIPLE_CHOICES, 300, "Multiple Choices") -HTTP_STATUS(MOVED_PERMANENTLY, 301, "Moved Permanently") -HTTP_STATUS(FOUND, 302, "Found") -HTTP_STATUS(SEE_OTHER, 303, "See Other") -HTTP_STATUS(NOT_MODIFIED, 304, "Not Modified") -HTTP_STATUS(USE_PROXY, 305, "Use Proxy") +HTTP_STATUS_ENUM_VALUE(MULTIPLE_CHOICES, 300, "Multiple Choices") +HTTP_STATUS_ENUM_VALUE(MOVED_PERMANENTLY, 301, "Moved Permanently") +HTTP_STATUS_ENUM_VALUE(FOUND, 302, "Found") +HTTP_STATUS_ENUM_VALUE(SEE_OTHER, 303, "See Other") +HTTP_STATUS_ENUM_VALUE(NOT_MODIFIED, 304, "Not Modified") +HTTP_STATUS_ENUM_VALUE(USE_PROXY, 305, "Use Proxy") // 306 is no longer used. -HTTP_STATUS(TEMPORARY_REDIRECT, 307, "Temporary Redirect") -HTTP_STATUS(PERMANENT_REDIRECT, 308, "Permanent Redirect") +HTTP_STATUS_ENUM_VALUE(TEMPORARY_REDIRECT, 307, "Temporary Redirect") +HTTP_STATUS_ENUM_VALUE(PERMANENT_REDIRECT, 308, "Permanent Redirect") // Client error 4xx -HTTP_STATUS(BAD_REQUEST, 400, "Bad Request") -HTTP_STATUS(UNAUTHORIZED, 401, "Unauthorized") -HTTP_STATUS(PAYMENT_REQUIRED, 402, "Payment Required") -HTTP_STATUS(FORBIDDEN, 403, "Forbidden") -HTTP_STATUS(NOT_FOUND, 404, "Not Found") -HTTP_STATUS(METHOD_NOT_ALLOWED, 405, "Method Not Allowed") -HTTP_STATUS(NOT_ACCEPTABLE, 406, "Not Acceptable") -HTTP_STATUS(PROXY_AUTHENTICATION_REQUIRED, 407, "Proxy Authentication Required") -HTTP_STATUS(REQUEST_TIMEOUT, 408, "Request Timeout") -HTTP_STATUS(CONFLICT, 409, "Conflict") -HTTP_STATUS(GONE, 410, "Gone") -HTTP_STATUS(LENGTH_REQUIRED, 411, "Length Required") -HTTP_STATUS(PRECONDITION_FAILED, 412, "Precondition Failed") -HTTP_STATUS(REQUEST_ENTITY_TOO_LARGE, 413, "Request Entity Too Large") -HTTP_STATUS(REQUEST_URI_TOO_LONG, 414, "Request-URI Too Long") -HTTP_STATUS(UNSUPPORTED_MEDIA_TYPE, 415, "Unsupported Media Type") -HTTP_STATUS(REQUESTED_RANGE_NOT_SATISFIABLE, 416, - "Requested Range Not Satisfiable") -HTTP_STATUS(EXPECTATION_FAILED, 417, "Expectation Failed") +HTTP_STATUS_ENUM_VALUE(BAD_REQUEST, 400, "Bad Request") +HTTP_STATUS_ENUM_VALUE(UNAUTHORIZED, 401, "Unauthorized") +HTTP_STATUS_ENUM_VALUE(PAYMENT_REQUIRED, 402, "Payment Required") +HTTP_STATUS_ENUM_VALUE(FORBIDDEN, 403, "Forbidden") +HTTP_STATUS_ENUM_VALUE(NOT_FOUND, 404, "Not Found") +HTTP_STATUS_ENUM_VALUE(METHOD_NOT_ALLOWED, 405, "Method Not Allowed") +HTTP_STATUS_ENUM_VALUE(NOT_ACCEPTABLE, 406, "Not Acceptable") +HTTP_STATUS_ENUM_VALUE(PROXY_AUTHENTICATION_REQUIRED, + 407, + "Proxy Authentication Required") +HTTP_STATUS_ENUM_VALUE(REQUEST_TIMEOUT, 408, "Request Timeout") +HTTP_STATUS_ENUM_VALUE(CONFLICT, 409, "Conflict") +HTTP_STATUS_ENUM_VALUE(GONE, 410, "Gone") +HTTP_STATUS_ENUM_VALUE(LENGTH_REQUIRED, 411, "Length Required") +HTTP_STATUS_ENUM_VALUE(PRECONDITION_FAILED, 412, "Precondition Failed") +HTTP_STATUS_ENUM_VALUE(REQUEST_ENTITY_TOO_LARGE, + 413, + "Request Entity Too Large") +HTTP_STATUS_ENUM_VALUE(REQUEST_URI_TOO_LONG, 414, "Request-URI Too Long") +HTTP_STATUS_ENUM_VALUE(UNSUPPORTED_MEDIA_TYPE, 415, "Unsupported Media Type") +HTTP_STATUS_ENUM_VALUE(REQUESTED_RANGE_NOT_SATISFIABLE, + 416, + "Requested Range Not Satisfiable") +HTTP_STATUS_ENUM_VALUE(EXPECTATION_FAILED, 417, "Expectation Failed") // 418 returned by Cloud Print. -HTTP_STATUS(INVALID_XPRIVET_TOKEN, 418, "Invalid XPrivet Token") -HTTP_STATUS(TOO_EARLY, 425, "Too Early") -HTTP_STATUS(TOO_MANY_REQUESTS, 429, "Too Many Requests") +HTTP_STATUS_ENUM_VALUE(INVALID_XPRIVET_TOKEN, 418, "Invalid XPrivet Token") +HTTP_STATUS_ENUM_VALUE(TOO_EARLY, 425, "Too Early") +HTTP_STATUS_ENUM_VALUE(TOO_MANY_REQUESTS, 429, "Too Many Requests") // Server error 5xx -HTTP_STATUS(INTERNAL_SERVER_ERROR, 500, "Internal Server Error") -HTTP_STATUS(NOT_IMPLEMENTED, 501, "Not Implemented") -HTTP_STATUS(BAD_GATEWAY, 502, "Bad Gateway") -HTTP_STATUS(SERVICE_UNAVAILABLE, 503, "Service Unavailable") -HTTP_STATUS(GATEWAY_TIMEOUT, 504, "Gateway Timeout") -HTTP_STATUS(VERSION_NOT_SUPPORTED, 505, "HTTP Version Not Supported") +HTTP_STATUS_ENUM_VALUE(INTERNAL_SERVER_ERROR, 500, "Internal Server Error") +HTTP_STATUS_ENUM_VALUE(NOT_IMPLEMENTED, 501, "Not Implemented") +HTTP_STATUS_ENUM_VALUE(BAD_GATEWAY, 502, "Bad Gateway") +HTTP_STATUS_ENUM_VALUE(SERVICE_UNAVAILABLE, 503, "Service Unavailable") +HTTP_STATUS_ENUM_VALUE(GATEWAY_TIMEOUT, 504, "Gateway Timeout") +HTTP_STATUS_ENUM_VALUE(VERSION_NOT_SUPPORTED, 505, "HTTP Version Not Supported") diff --git a/chromium/net/http/http_stream.h b/chromium/net/http/http_stream.h index 80712a613ff..2b35bca0f8f 100644 --- a/chromium/net/http/http_stream.h +++ b/chromium/net/http/http_stream.h @@ -41,12 +41,12 @@ class SSLInfo; class NET_EXPORT_PRIVATE HttpStream { public: - HttpStream() {} + HttpStream() = default; HttpStream(const HttpStream&) = delete; HttpStream& operator=(const HttpStream&) = delete; - virtual ~HttpStream() {} + virtual ~HttpStream() = default; // Registers the HTTP request for the stream. Must be called before calling // InitializeStream(). Separating the registration of the request from the @@ -194,7 +194,7 @@ class NET_EXPORT_PRIVATE HttpStream { // called on the old stream. The caller should ensure that the response body // from the previous request is drained before calling this method. If the // subclass does not support renewing the stream, NULL is returned. - virtual HttpStream* RenewStreamForAuth() = 0; + virtual std::unique_ptr<HttpStream> RenewStreamForAuth() = 0; virtual void SetRequestHeadersCallback(RequestHeadersCallback callback) = 0; diff --git a/chromium/net/http/http_stream_factory.cc b/chromium/net/http/http_stream_factory.cc index 4b3a3463c5a..010bbe37441 100644 --- a/chromium/net/http/http_stream_factory.cc +++ b/chromium/net/http/http_stream_factory.cc @@ -46,7 +46,7 @@ const char kAlternativeServiceHeader[] = "Alt-Svc"; HttpStreamFactory::HttpStreamFactory(HttpNetworkSession* session) : session_(session), job_factory_(std::make_unique<JobFactory>()) {} -HttpStreamFactory::~HttpStreamFactory() {} +HttpStreamFactory::~HttpStreamFactory() = default; void HttpStreamFactory::ProcessAlternativeServices( HttpNetworkSession* session, diff --git a/chromium/net/http/http_stream_factory.h b/chromium/net/http/http_stream_factory.h index 694d071b9b1..e22f5481c66 100644 --- a/chromium/net/http/http_stream_factory.h +++ b/chromium/net/http/http_stream_factory.h @@ -46,9 +46,21 @@ class NET_EXPORT HttpStreamFactory { class NET_EXPORT_PRIVATE JobFactory; enum JobType { + // Job that will connect via HTTP/1 or HTTP/2. This may be paused for a + // while when ALTERNATIVE or DNS_ALPN_H3 job was created. MAIN, + // Job that will connect via HTTP/3 iff Chrome has received an Alt-Svc + // header from the origin. ALTERNATIVE, + // Job that will connect via HTTP/3 iff an "h3" value was found in the ALPN + // list of an HTTPS DNS record. + DNS_ALPN_H3, + // Job that will preconnect. This uses HTTP/3 iff Chrome has received an + // Alt-Svc header from the origin. Otherwise, it use HTTP/1 or HTTP/2. PRECONNECT, + // Job that will preconnect via HTTP/3 iff an "h3" value was found in the + // ALPN list of an HTTPS DNS record. + PRECONNECT_DNS_ALPN_H3, }; explicit HttpStreamFactory(HttpNetworkSession* session); diff --git a/chromium/net/http/http_stream_factory_job.cc b/chromium/net/http/http_stream_factory_job.cc index f0a2edc34f1..aed8dbf53a9 100644 --- a/chromium/net/http/http_stream_factory_job.cc +++ b/chromium/net/http/http_stream_factory_job.cc @@ -71,31 +71,48 @@ const base::Feature kLimitEarlyPreconnectsExperiment{ } // namespace +const char* NetLogHttpStreamJobType(HttpStreamFactory::JobType job_type) { + switch (job_type) { + case HttpStreamFactory::MAIN: + return "main"; + case HttpStreamFactory::ALTERNATIVE: + return "alternative"; + case HttpStreamFactory::DNS_ALPN_H3: + return "dns_alpn_h3"; + case HttpStreamFactory::PRECONNECT: + return "preconnect"; + case HttpStreamFactory::PRECONNECT_DNS_ALPN_H3: + return "preconnect_dns_alpn_h3"; + } + return ""; +} + // Returns parameters associated with the start of a HTTP stream job. base::Value NetLogHttpStreamJobParams(const NetLogSource& source, const GURL& original_url, const GURL& url, bool expect_spdy, bool using_quic, + HttpStreamFactory::JobType job_type, RequestPriority priority) { - base::Value dict(base::Value::Type::DICTIONARY); + base::Value::Dict dict; if (source.IsValid()) - source.AddToEventParameters(&dict); - dict.SetStringKey("original_url", - original_url.DeprecatedGetOriginAsURL().spec()); - dict.SetStringKey("url", url.DeprecatedGetOriginAsURL().spec()); - dict.SetBoolKey("expect_spdy", expect_spdy); - dict.SetBoolKey("using_quic", using_quic); - dict.SetStringKey("priority", RequestPriorityToString(priority)); - return dict; + source.AddToEventParameters(dict); + dict.Set("original_url", original_url.DeprecatedGetOriginAsURL().spec()); + dict.Set("url", url.DeprecatedGetOriginAsURL().spec()); + dict.Set("expect_spdy", expect_spdy); + dict.Set("using_quic", using_quic); + dict.Set("priority", RequestPriorityToString(priority)); + dict.Set("type", NetLogHttpStreamJobType(job_type)); + return base::Value(std::move(dict)); } // Returns parameters associated with the ALPN protocol of a HTTP stream. base::Value NetLogHttpStreamProtoParams(NextProto negotiated_protocol) { - base::Value dict(base::Value::Type::DICTIONARY); + base::Value::Dict dict; - dict.SetStringKey("proto", NextProtoToString(negotiated_protocol)); - return dict; + dict.Set("proto", NextProtoToString(negotiated_protocol)); + return base::Value(std::move(dict)); } HttpStreamFactory::Job::Job(Delegate* delegate, @@ -122,7 +139,7 @@ HttpStreamFactory::Job::Job(Delegate* delegate, NetLogWithSource::Make(net_log, NetLogSourceType::HTTP_STREAM_JOB)), io_callback_( base::BindRepeating(&Job::OnIOComplete, base::Unretained(this))), - connection_(new ClientSocketHandle), + connection_(std::make_unique<ClientSocketHandle>()), session_(session), destination_(std::move(destination)), origin_url_(origin_url), @@ -143,7 +160,8 @@ HttpStreamFactory::Job::Job(Delegate* delegate, origin_url_.SchemeIs(url::kWssScheme)), using_quic_( alternative_protocol == kProtoQUIC || - (ShouldForceQuic(session, destination_, proxy_info, using_ssl_))), + (ShouldForceQuic(session, destination_, proxy_info, using_ssl_)) || + job_type == DNS_ALPN_H3 || job_type == PRECONNECT_DNS_ALPN_H3), quic_version_(quic_version), expect_spdy_(alternative_protocol == kProtoHTTP2 && !using_quic_), quic_request_(session_->quic_stream_factory()), @@ -180,8 +198,10 @@ HttpStreamFactory::Job::Job(Delegate* delegate, session->context().quic_context->params()->supported_versions[0]; } - if (using_quic_) - DCHECK_NE(quic_version_, quic::ParsedQuicVersion::Unsupported()); + if (using_quic_) { + DCHECK((quic_version_ != quic::ParsedQuicVersion::Unsupported()) || + (job_type_ == DNS_ALPN_H3) || (job_type_ == PRECONNECT_DNS_ALPN_H3)); + } DCHECK(session); if (alternative_protocol != kProtoUnknown) { @@ -275,7 +295,7 @@ void HttpStreamFactory::Job::Resume() { } void HttpStreamFactory::Job::Orphan() { - DCHECK_EQ(job_type_, ALTERNATIVE); + DCHECK(job_type_ == ALTERNATIVE || job_type_ == DNS_ALPN_H3); net_log_.AddEvent(NetLogEventType::HTTP_STREAM_JOB_ORPHANED); // Watching for SPDY sessions isn't supported on orphaned jobs. @@ -305,6 +325,28 @@ bool HttpStreamFactory::Job::HasAvailableSpdySession() const { is_websocket_); } +bool HttpStreamFactory::Job::HasAvailableQuicSession() const { + if (!using_quic_) + return false; + bool require_dns_https_alpn = (job_type_ == DNS_ALPN_H3); + return quic_request_.CanUseExistingSession( + origin_url_, request_info_.privacy_mode, request_info_.socket_tag, + request_info_.network_isolation_key, request_info_.secure_dns_policy, + require_dns_https_alpn, destination_); +} + +bool HttpStreamFactory::Job::TargettedSocketGroupHasActiveSocket() const { + DCHECK(!using_quic_); + DCHECK(!is_websocket_); + ClientSocketPool* pool = session_->GetSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL, proxy_info_.proxy_server()); + DCHECK(pool); + ClientSocketPool::GroupId connection_group( + destination_, request_info_.privacy_mode, + request_info_.network_isolation_key, request_info_.secure_dns_policy); + return pool->HasActiveSocket(connection_group); +} + bool HttpStreamFactory::Job::was_alpn_negotiated() const { return was_alpn_negotiated_; } @@ -405,6 +447,7 @@ bool HttpStreamFactory::Job::CanUseExistingSpdySession() const { void HttpStreamFactory::Job::OnStreamReadyCallback() { DCHECK(stream_.get()); DCHECK_NE(job_type_, PRECONNECT); + DCHECK_NE(job_type_, PRECONNECT_DNS_ALPN_H3); DCHECK(!is_websocket_ || try_websocket_over_http2_); MaybeCopyConnectionAttemptsFromHandle(); @@ -416,6 +459,7 @@ void HttpStreamFactory::Job::OnStreamReadyCallback() { void HttpStreamFactory::Job::OnWebSocketHandshakeStreamReadyCallback() { DCHECK(websocket_stream_); DCHECK_NE(job_type_, PRECONNECT); + DCHECK_NE(job_type_, PRECONNECT_DNS_ALPN_H3); DCHECK(is_websocket_); MaybeCopyConnectionAttemptsFromHandle(); @@ -437,6 +481,7 @@ void HttpStreamFactory::Job::OnBidirectionalStreamImplReadyCallback() { void HttpStreamFactory::Job::OnStreamFailedCallback(int result) { DCHECK_NE(job_type_, PRECONNECT); + DCHECK_NE(job_type_, PRECONNECT_DNS_ALPN_H3); MaybeCopyConnectionAttemptsFromHandle(); @@ -448,6 +493,7 @@ void HttpStreamFactory::Job::OnCertificateErrorCallback( int result, const SSLInfo& ssl_info) { DCHECK_NE(job_type_, PRECONNECT); + DCHECK_NE(job_type_, PRECONNECT_DNS_ALPN_H3); DCHECK(!spdy_session_request_); MaybeCopyConnectionAttemptsFromHandle(); @@ -461,6 +507,7 @@ void HttpStreamFactory::Job::OnNeedsProxyAuthCallback( HttpAuthController* auth_controller, base::OnceClosure restart_with_auth_callback) { DCHECK_NE(job_type_, PRECONNECT); + DCHECK_NE(job_type_, PRECONNECT_DNS_ALPN_H3); DCHECK(establishing_tunnel_); DCHECK(!restart_with_auth_callback_); @@ -478,14 +525,15 @@ void HttpStreamFactory::Job::OnNeedsProxyAuthCallback( void HttpStreamFactory::Job::OnNeedsClientAuthCallback( SSLCertRequestInfo* cert_info) { DCHECK_NE(job_type_, PRECONNECT); + DCHECK_NE(job_type_, PRECONNECT_DNS_ALPN_H3); DCHECK(!spdy_session_request_); delegate_->OnNeedsClientAuth(this, server_ssl_config_, cert_info); // |this| may be deleted after this call. } -void HttpStreamFactory::Job::OnPreconnectsComplete() { - delegate_->OnPreconnectsComplete(this); +void HttpStreamFactory::Job::OnPreconnectsComplete(int result) { + delegate_->OnPreconnectsComplete(this, result); // |this| may be deleted after this call. } @@ -505,11 +553,11 @@ void HttpStreamFactory::Job::RunLoop(int result) { // while doing anything other than waiting to establish a connection. spdy_session_request_.reset(); - if (job_type_ == PRECONNECT) { + if ((job_type_ == PRECONNECT) || (job_type_ == PRECONNECT_DNS_ALPN_H3)) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&HttpStreamFactory::Job::OnPreconnectsComplete, - ptr_factory_.GetWeakPtr())); + ptr_factory_.GetWeakPtr(), result)); return; } @@ -628,7 +676,7 @@ int HttpStreamFactory::Job::DoStart() { net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB, [&] { return NetLogHttpStreamJobParams(net_log->source(), request_info_.url, origin_url_, expect_spdy_, using_quic_, - priority_); + job_type_, priority_); }); net_log->AddEventReferencingSource( NetLogEventType::HTTP_STREAM_REQUEST_STARTED_JOB, net_log_.source()); @@ -880,13 +928,15 @@ int HttpStreamFactory::Job::DoInitConnectionImplQuic() { ssl_config = &server_ssl_config_; } DCHECK(url.SchemeIs(url::kHttpsScheme)); + bool require_dns_https_alpn = + (job_type_ == DNS_ALPN_H3) || (job_type_ == PRECONNECT_DNS_ALPN_H3); int rv = quic_request_.Request( std::move(destination), quic_version_, request_info_.privacy_mode, priority_, request_info_.socket_tag, request_info_.network_isolation_key, request_info_.secure_dns_policy, proxy_info_.is_direct(), - /*require_dns_https_alpn=*/false, ssl_config->GetCertVerifyFlags(), url, - net_log_, &net_error_details_, + require_dns_https_alpn, ssl_config->GetCertVerifyFlags(), url, net_log_, + &net_error_details_, base::BindOnce(&Job::OnFailedOnDefaultNetwork, ptr_factory_.GetWeakPtr()), io_callback_); if (rv == OK) { @@ -909,7 +959,7 @@ void HttpStreamFactory::Job::OnQuicHostResolution(int result) { } void HttpStreamFactory::Job::OnFailedOnDefaultNetwork(int result) { - DCHECK_EQ(job_type_, ALTERNATIVE); + DCHECK(job_type_ == ALTERNATIVE || job_type_ == DNS_ALPN_H3); DCHECK(using_quic_); delegate_->OnFailedOnDefaultNetwork(this); } @@ -921,7 +971,7 @@ int HttpStreamFactory::Job::DoInitConnectionComplete(int result) { // established. spdy_session_request_.reset(); - if (job_type_ == PRECONNECT) { + if ((job_type_ == PRECONNECT) || (job_type_ == PRECONNECT_DNS_ALPN_H3)) { if (using_quic_) return result; DCHECK_EQ(OK, result); @@ -1071,6 +1121,7 @@ int HttpStreamFactory::Job::SetSpdyHttpStreamOrBidirectionalStreamImpl( if (is_websocket_) { DCHECK_NE(job_type_, PRECONNECT); + DCHECK_NE(job_type_, PRECONNECT_DNS_ALPN_H3); DCHECK(delegate_->websocket_handshake_stream_create_helper()); if (!try_websocket_over_http2_) { @@ -1111,6 +1162,7 @@ int HttpStreamFactory::Job::DoCreateStream() { request_info_.url.SchemeIs(url::kHttpScheme); if (is_websocket_) { DCHECK_NE(job_type_, PRECONNECT); + DCHECK_NE(job_type_, PRECONNECT_DNS_ALPN_H3); DCHECK(delegate_->websocket_handshake_stream_create_helper()); websocket_stream_ = delegate_->websocket_handshake_stream_create_helper() @@ -1223,7 +1275,7 @@ void HttpStreamFactory::Job::OnSpdySessionAvailable( // If this is a preconnect, nothing left do to. if (job_type_ == PRECONNECT) { - OnPreconnectsComplete(); + OnPreconnectsComplete(OK); return; } @@ -1258,7 +1310,7 @@ HttpStreamFactory::JobFactory::JobFactory() = default; HttpStreamFactory::JobFactory::~JobFactory() = default; std::unique_ptr<HttpStreamFactory::Job> -HttpStreamFactory::JobFactory::CreateMainJob( +HttpStreamFactory::JobFactory::CreateJob( HttpStreamFactory::Job::Delegate* delegate, HttpStreamFactory::JobType job_type, HttpNetworkSession* session, @@ -1271,31 +1323,9 @@ HttpStreamFactory::JobFactory::CreateMainJob( GURL origin_url, bool is_websocket, bool enable_ip_based_pooling, - NetLog* net_log) { - return std::make_unique<HttpStreamFactory::Job>( - delegate, job_type, session, request_info, priority, proxy_info, - server_ssl_config, proxy_ssl_config, std::move(destination), origin_url, - kProtoUnknown, quic::ParsedQuicVersion::Unsupported(), is_websocket, - enable_ip_based_pooling, net_log); -} - -std::unique_ptr<HttpStreamFactory::Job> -HttpStreamFactory::JobFactory::CreateAltSvcJob( - HttpStreamFactory::Job::Delegate* delegate, - HttpStreamFactory::JobType job_type, - HttpNetworkSession* session, - const HttpRequestInfo& request_info, - RequestPriority priority, - const ProxyInfo& proxy_info, - const SSLConfig& server_ssl_config, - const SSLConfig& proxy_ssl_config, - url::SchemeHostPort destination, - GURL origin_url, + NetLog* net_log, NextProto alternative_protocol, - quic::ParsedQuicVersion quic_version, - bool is_websocket, - bool enable_ip_based_pooling, - NetLog* net_log) { + quic::ParsedQuicVersion quic_version) { return std::make_unique<HttpStreamFactory::Job>( delegate, job_type, session, request_info, priority, proxy_info, server_ssl_config, proxy_ssl_config, std::move(destination), origin_url, diff --git a/chromium/net/http/http_stream_factory_job.h b/chromium/net/http/http_stream_factory_job.h index 1a176b71a8f..c5a47f914bf 100644 --- a/chromium/net/http/http_stream_factory_job.h +++ b/chromium/net/http/http_stream_factory_job.h @@ -65,7 +65,7 @@ class HttpStreamFactory::Job // Delegate to report Job's status to HttpStreamRequest and HttpStreamFactory. class NET_EXPORT_PRIVATE Delegate { public: - virtual ~Delegate() {} + virtual ~Delegate() = default; // Invoked when |job| has an HttpStream ready. virtual void OnStreamReady(Job* job, const SSLConfig& used_ssl_config) = 0; @@ -110,7 +110,7 @@ class HttpStreamFactory::Job HttpAuthController* auth_controller) = 0; // Invoked when the |job| finishes pre-connecting sockets. - virtual void OnPreconnectsComplete(Job* job) = 0; + virtual void OnPreconnectsComplete(Job* job, int result) = 0; // Invoked to record connection attempts made by the socket layer to // HttpStreamRequest if |job| is associated with HttpStreamRequest. @@ -186,7 +186,7 @@ class HttpStreamFactory::Job virtual void Resume(); // Called when |this| is orphaned by Delegate. This is valid for - // ALTERNATIVE job only. + // ALTERNATIVE job and DNS_ALPN_H3 job. void Orphan(); void SetPriority(RequestPriority priority); @@ -195,6 +195,14 @@ class HttpStreamFactory::Job // spdy session. bool HasAvailableSpdySession() const; + // Returns true if the current request can be immediately sent on a existing + // QUIC session. + bool HasAvailableQuicSession() const; + + // Returns true if a connected (idle or handed out) or connecting socket + // exists for the job. This method is not supported for WebSocket and QUIC. + bool TargettedSocketGroupHasActiveSocket() const; + const GURL& origin_url() const { return origin_url_; } RequestPriority priority() const { return priority_; } bool was_alpn_negotiated() const; @@ -265,7 +273,7 @@ class HttpStreamFactory::Job HttpAuthController* auth_controller, base::OnceClosure restart_with_auth_callback); void OnNeedsClientAuthCallback(SSLCertRequestInfo* cert_info); - void OnPreconnectsComplete(); + void OnPreconnectsComplete(int result); void OnIOComplete(int result); // RunLoop() finishes asynchronously and invokes one of the On* methods (see @@ -475,22 +483,7 @@ class HttpStreamFactory::JobFactory { virtual ~JobFactory(); - virtual std::unique_ptr<HttpStreamFactory::Job> CreateMainJob( - HttpStreamFactory::Job::Delegate* delegate, - HttpStreamFactory::JobType job_type, - HttpNetworkSession* session, - const HttpRequestInfo& request_info, - RequestPriority priority, - const ProxyInfo& proxy_info, - const SSLConfig& server_ssl_config, - const SSLConfig& proxy_ssl_config, - url::SchemeHostPort destination, - GURL origin_url, - bool is_websocket, - bool enable_ip_based_pooling, - NetLog* net_log); - - virtual std::unique_ptr<HttpStreamFactory::Job> CreateAltSvcJob( + virtual std::unique_ptr<HttpStreamFactory::Job> CreateJob( HttpStreamFactory::Job::Delegate* delegate, HttpStreamFactory::JobType job_type, HttpNetworkSession* session, @@ -501,11 +494,12 @@ class HttpStreamFactory::JobFactory { const SSLConfig& proxy_ssl_config, url::SchemeHostPort destination, GURL origin_url, - NextProto alternative_protocol, - quic::ParsedQuicVersion quic_version, bool is_websocket, bool enable_ip_based_pooling, - NetLog* net_log); + NetLog* net_log, + NextProto alternative_protocol = kProtoUnknown, + quic::ParsedQuicVersion quic_version = + quic::ParsedQuicVersion::Unsupported()); }; } // namespace net diff --git a/chromium/net/http/http_stream_factory_job_controller.cc b/chromium/net/http/http_stream_factory_job_controller.cc index 19dd80b8150..46435687f15 100644 --- a/chromium/net/http/http_stream_factory_job_controller.cc +++ b/chromium/net/http/http_stream_factory_job_controller.cc @@ -16,8 +16,10 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/memory_usage_estimator.h" #include "base/values.h" +#include "net/base/features.h" #include "net/base/host_mapping_rules.h" #include "net/base/load_flags.h" +#include "net/base/net_errors.h" #include "net/base/privacy_mode.h" #include "net/base/proxy_server.h" #include "net/base/proxy_string_util.h" @@ -44,13 +46,12 @@ namespace { // Returns parameters associated with the proxy resolution. base::Value NetLogHttpStreamJobProxyServerResolved( const ProxyServer& proxy_server) { - base::Value dict(base::Value::Type::DICTIONARY); + base::Value::Dict dict; - dict.SetStringKey("proxy_server", - proxy_server.is_valid() - ? ProxyServerToPacResultElement(proxy_server) - : std::string()); - return dict; + dict.Set("proxy_server", proxy_server.is_valid() + ? ProxyServerToPacResultElement(proxy_server) + : std::string()); + return base::Value(std::move(dict)); } GURL CreateAltSvcUrl(const GURL& origin_url, @@ -95,6 +96,12 @@ void HistogramProxyUsed(const ProxyInfo& proxy_info, bool success) { } } +// Generate a AlternativeService for DNS alt job. Note: Chrome does not yet +// support different port DNS alpn. +AlternativeService GetAlternativeServiceForDnsJob(const GURL& url) { + return AlternativeService(kProtoQUIC, HostPortPair::FromURL(url)); +} + } // namespace // The maximum time to wait for the alternate job to complete before resuming @@ -103,21 +110,20 @@ const int kMaxDelayTimeForMainJobSecs = 3; base::Value NetLogJobControllerParams(const HttpRequestInfo& request_info, bool is_preconnect) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("url", request_info.url.possibly_invalid_spec()); - dict.SetBoolKey("is_preconnect", is_preconnect); - dict.SetStringKey("privacy_mode", - PrivacyModeToDebugString(request_info.privacy_mode)); + base::Value::Dict dict; + dict.Set("url", request_info.url.possibly_invalid_spec()); + dict.Set("is_preconnect", is_preconnect); + dict.Set("privacy_mode", PrivacyModeToDebugString(request_info.privacy_mode)); - return dict; + return base::Value(std::move(dict)); } base::Value NetLogAltSvcParams(const AlternativeServiceInfo* alt_svc_info, bool is_broken) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("alt_svc", alt_svc_info->ToString()); - dict.SetBoolKey("is_broken", is_broken); - return dict; + base::Value::Dict dict; + dict.Set("alt_svc", alt_svc_info->ToString()); + dict.Set("is_broken", is_broken); + return base::Value(std::move(dict)); } HttpStreamFactory::JobController::JobController( @@ -167,6 +173,7 @@ HttpStreamFactory::JobController::JobController( HttpStreamFactory::JobController::~JobController() { main_job_.reset(); alternative_job_.reset(); + dns_alpn_h3_job_.reset(); bound_job_ = nullptr; if (proxy_resolve_request_) { DCHECK_EQ(STATE_RESOLVE_PROXY_COMPLETE, next_state_); @@ -226,6 +233,9 @@ LoadState HttpStreamFactory::JobController::GetLoadState() const { return main_job_->GetLoadState(); if (alternative_job_) return alternative_job_->GetLoadState(); + if (dns_alpn_h3_job_) + return dns_alpn_h3_job_->GetLoadState(); + // When proxy resolution fails, there is no job created and // NotifyRequestFailed() is executed one message loop iteration later. return LOAD_STATE_IDLE; @@ -233,17 +243,24 @@ LoadState HttpStreamFactory::JobController::GetLoadState() const { void HttpStreamFactory::JobController::OnRequestComplete() { DCHECK(request_); - - CancelJobs(); request_ = nullptr; - if (bound_job_) { + + if (!job_bound_) { + alternative_job_.reset(); + main_job_.reset(); + dns_alpn_h3_job_.reset(); + } else { if (bound_job_->job_type() == MAIN) { + bound_job_ = nullptr; main_job_.reset(); - } else { - DCHECK(bound_job_->job_type() == ALTERNATIVE); + } else if (bound_job_->job_type() == ALTERNATIVE) { + bound_job_ = nullptr; alternative_job_.reset(); + } else { + DCHECK(bound_job_->job_type() == DNS_ALPN_H3); + bound_job_ = nullptr; + dns_alpn_h3_job_.reset(); } - bound_job_ = nullptr; } MaybeNotifyFactoryOfCompletion(); } @@ -260,6 +277,12 @@ void HttpStreamFactory::JobController::SetPriority(RequestPriority priority) { if (alternative_job_) { alternative_job_->SetPriority(priority); } + if (dns_alpn_h3_job_) { + dns_alpn_h3_job_->SetPriority(priority); + } + if (preconnect_backup_job_) { + preconnect_backup_job_->SetPriority(priority); + } } void HttpStreamFactory::JobController::OnStreamReady( @@ -350,12 +373,18 @@ void HttpStreamFactory::JobController::OnStreamFailed( Job* job, int status, const SSLConfig& used_ssl_config) { - if (job->job_type() == ALTERNATIVE) { - DCHECK_EQ(alternative_job_.get(), job); - OnAlternativeServiceJobFailed(status); - } else { + DCHECK_NE(OK, status); + if (job->job_type() == MAIN) { DCHECK_EQ(main_job_.get(), job); main_job_net_error_ = status; + } else if (job->job_type() == ALTERNATIVE) { + DCHECK_EQ(alternative_job_.get(), job); + DCHECK_NE(kProtoUnknown, alternative_service_info_.protocol()); + alternative_job_net_error_ = status; + } else { + DCHECK_EQ(job->job_type(), DNS_ALPN_H3); + DCHECK_EQ(dns_alpn_h3_job_.get(), job); + dns_alpn_h3_job_net_error_ = status; } MaybeResumeMainJob(job, base::TimeDelta()); @@ -373,14 +402,19 @@ void HttpStreamFactory::JobController::OnStreamFailed( DCHECK(job); if (!bound_job_) { - if (main_job_ && alternative_job_) { + if (GetJobCount() >= 2) { // Hey, we've got other jobs! Maybe one of them will succeed, let's just // ignore this failure. if (job->job_type() == MAIN) { + DCHECK_EQ(main_job_.get(), job); main_job_.reset(); - } else { - DCHECK(job->job_type() == ALTERNATIVE); + } else if (job->job_type() == ALTERNATIVE) { + DCHECK_EQ(alternative_job_.get(), job); alternative_job_.reset(); + } else { + DCHECK_EQ(job->job_type(), DNS_ALPN_H3); + DCHECK_EQ(dns_alpn_h3_job_.get(), job); + dns_alpn_h3_job_.reset(); } return; } else { @@ -403,8 +437,14 @@ void HttpStreamFactory::JobController::OnStreamFailed( } void HttpStreamFactory::JobController::OnFailedOnDefaultNetwork(Job* job) { - DCHECK_EQ(job->job_type(), ALTERNATIVE); - alternative_job_failed_on_default_network_ = true; + if (job->job_type() == ALTERNATIVE) { + DCHECK_EQ(alternative_job_.get(), job); + alternative_job_failed_on_default_network_ = true; + } else { + DCHECK_EQ(job->job_type(), DNS_ALPN_H3); + DCHECK_EQ(dns_alpn_h3_job_.get(), job); + dns_alpn_h3_job_failed_on_default_network_ = true; + } } void HttpStreamFactory::JobController::OnCertificateError( @@ -473,9 +513,23 @@ void HttpStreamFactory::JobController::OnNeedsProxyAuth( auth_controller); } -void HttpStreamFactory::JobController::OnPreconnectsComplete(Job* job) { +void HttpStreamFactory::JobController::OnPreconnectsComplete(Job* job, + int result) { DCHECK_EQ(main_job_.get(), job); + if (result == ERR_DNS_NO_MACHING_SUPPORTED_ALPN) { + DCHECK_EQ(job->job_type(), PRECONNECT_DNS_ALPN_H3); + DCHECK(preconnect_backup_job_); + GURL origin_url = request_info_.url; + RewriteUrlWithHostMappingRules(origin_url); + url::SchemeHostPort destination(origin_url); + DCHECK(destination.IsValid()); + ConvertWsToHttp(destination); + main_job_ = std::move(preconnect_backup_job_); + main_job_->Preconnect(num_streams_); + return; + } main_job_.reset(); + preconnect_backup_job_.reset(); ResetErrorStatusForJobs(); factory_->OnPreconnectsCompleteInternal(); MaybeNotifyFactoryOfCompletion(); @@ -485,9 +539,13 @@ void HttpStreamFactory::JobController::OnOrphanedJobComplete(const Job* job) { if (job->job_type() == MAIN) { DCHECK_EQ(main_job_.get(), job); main_job_.reset(); - } else { + } else if (job->job_type() == ALTERNATIVE) { DCHECK_EQ(alternative_job_.get(), job); alternative_job_.reset(); + } else { + DCHECK_EQ(job->job_type(), DNS_ALPN_H3); + DCHECK_EQ(dns_alpn_h3_job_.get(), job); + dns_alpn_h3_job_.reset(); } MaybeNotifyFactoryOfCompletion(); @@ -532,15 +590,23 @@ void HttpStreamFactory::JobController::ResetErrorStatusForJobs() { main_job_net_error_ = OK; alternative_job_net_error_ = OK; alternative_job_failed_on_default_network_ = false; + dns_alpn_h3_job_net_error_ = OK; + dns_alpn_h3_job_failed_on_default_network_ = false; } void HttpStreamFactory::JobController::MaybeResumeMainJob( Job* job, const base::TimeDelta& delay) { DCHECK(delay == base::TimeDelta() || delay == main_job_wait_time_); - DCHECK(job == main_job_.get() || job == alternative_job_.get()); + DCHECK(job == main_job_.get() || job == alternative_job_.get() || + job == dns_alpn_h3_job_.get()); - if (job != alternative_job_.get() || !main_job_) + if (job == main_job_.get()) + return; + if (job == dns_alpn_h3_job_.get() && alternative_job_) { + return; + } + if (!main_job_) return; main_job_is_blocked_ = false; @@ -570,9 +636,9 @@ void HttpStreamFactory::JobController::OnConnectionInitialized(Job* job, bool HttpStreamFactory::JobController::ShouldWait(Job* job) { // The alternative job never waits. - if (job == alternative_job_.get()) + if (job == alternative_job_.get() || job == dns_alpn_h3_job_.get()) return false; - + DCHECK_EQ(main_job_.get(), job); if (main_job_is_blocked_) return true; @@ -638,6 +704,7 @@ void HttpStreamFactory::JobController::RunLoop(int result) { // iteration later to avoid re-entrancy. DCHECK(!main_job_); DCHECK(!alternative_job_); + DCHECK(!dns_alpn_h3_job_); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&HttpStreamFactory::JobController::NotifyRequestFailed, @@ -749,6 +816,14 @@ int HttpStreamFactory::JobController::DoCreateJobs() { SelectQuicVersion(alternative_service_info_.advertised_versions()); DCHECK_NE(quic_version, quic::ParsedQuicVersion::Unsupported()); } + const bool dns_alpn_h3_job_enabled = + session_->params().use_dns_https_svcb_alpn && + base::EqualsCaseInsensitiveASCII(origin_url.scheme(), + url::kHttpsScheme) && + session_->IsQuicEnabled() && proxy_info_.is_direct() && + !session_->http_server_properties()->IsAlternativeServiceBroken( + GetAlternativeServiceForDnsJob(origin_url), + request_info_.network_isolation_key); if (is_preconnect_) { // Due to how the socket pools handle priorities and idle sockets, only IDLE @@ -764,30 +839,44 @@ int HttpStreamFactory::JobController::DoCreateJobs() { url::SchemeHostPort(alternative_url); ConvertWsToHttp(alternative_destination); - main_job_ = job_factory_->CreateAltSvcJob( + main_job_ = job_factory_->CreateJob( this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, server_ssl_config_, proxy_ssl_config_, - std::move(alternative_destination), origin_url, - alternative_service_info_.protocol(), quic_version, is_websocket_, - enable_ip_based_pooling_, session_->net_log()); + std::move(alternative_destination), origin_url, is_websocket_, + enable_ip_based_pooling_, session_->net_log(), + alternative_service_info_.protocol(), quic_version); } else { - main_job_ = job_factory_->CreateMainJob( - this, PRECONNECT, session_, request_info_, IDLE, proxy_info_, - server_ssl_config_, proxy_ssl_config_, std::move(destination), - origin_url, is_websocket_, enable_ip_based_pooling_, - session_->net_log()); + // Note: When `dns_alpn_h3_job_enabled` is true, we create a + // PRECONNECT_DNS_ALPN_H3 job. If no matching HTTPS DNS ALPN records are + // received, the PRECONNECT_DNS_ALPN_H3 job will fail with + // ERR_DNS_NO_MACHING_SUPPORTED_ALPN, and |preconnect_backup_job_| will be + // started in OnPreconnectsComplete(). + main_job_ = job_factory_->CreateJob( + this, dns_alpn_h3_job_enabled ? PRECONNECT_DNS_ALPN_H3 : PRECONNECT, + session_, request_info_, priority_, proxy_info_, server_ssl_config_, + proxy_ssl_config_, destination, origin_url, is_websocket_, + enable_ip_based_pooling_, net_log_.net_log()); + if (dns_alpn_h3_job_enabled) { + preconnect_backup_job_ = job_factory_->CreateJob( + this, PRECONNECT, session_, request_info_, priority_, proxy_info_, + server_ssl_config_, proxy_ssl_config_, std::move(destination), + origin_url, is_websocket_, enable_ip_based_pooling_, + net_log_.net_log()); + } } main_job_->Preconnect(num_streams_); return OK; } - main_job_ = job_factory_->CreateMainJob( + main_job_ = job_factory_->CreateJob( this, MAIN, session_, request_info_, priority_, proxy_info_, server_ssl_config_, proxy_ssl_config_, std::move(destination), origin_url, is_websocket_, enable_ip_based_pooling_, net_log_.net_log()); + // Alternative Service can only be set for HTTPS requests while Alternative // Proxy is set for HTTP requests. if (alternative_service_info_.protocol() != kProtoUnknown) { DCHECK(request_info_.url.SchemeIs(url::kHttpsScheme)); + DCHECK(!is_websocket_); DVLOG(1) << "Selected alternative service (host: " << alternative_service_info_.host_port_pair().host() << " port: " << alternative_service_info_.host_port_pair().port() @@ -801,28 +890,75 @@ int HttpStreamFactory::JobController::DoCreateJobs() { url::SchemeHostPort(alternative_url); ConvertWsToHttp(alternative_destination); - alternative_job_ = job_factory_->CreateAltSvcJob( + alternative_job_ = job_factory_->CreateJob( this, ALTERNATIVE, session_, request_info_, priority_, proxy_info_, server_ssl_config_, proxy_ssl_config_, - std::move(alternative_destination), origin_url, - alternative_service_info_.protocol(), quic_version, is_websocket_, + std::move(alternative_destination), origin_url, is_websocket_, + enable_ip_based_pooling_, net_log_.net_log(), + alternative_service_info_.protocol(), quic_version); + } + + if (dns_alpn_h3_job_enabled) { + DCHECK(!is_websocket_); + url::SchemeHostPort dns_alpn_h3_destination = + url::SchemeHostPort(origin_url); + dns_alpn_h3_job_ = job_factory_->CreateJob( + this, DNS_ALPN_H3, session_, request_info_, priority_, proxy_info_, + server_ssl_config_, proxy_ssl_config_, + std::move(dns_alpn_h3_destination), origin_url, is_websocket_, enable_ip_based_pooling_, net_log_.net_log()); + } + ClearInappropriateJobs(); + + if (main_job_ && (alternative_job_ || + (dns_alpn_h3_job_ && + (!main_job_->TargettedSocketGroupHasActiveSocket() && + !main_job_->HasAvailableSpdySession())))) { + // We don't block |main_job_| when |alternative_job_| doesn't exists and + // |dns_alpn_h3_job_| exists and an active socket is available for + // |main_job_|. This is intended to make the fallback logic faster. main_job_is_blocked_ = true; + } + + if (alternative_job_) { alternative_job_->Start(request_->stream_type()); } - // Even if |alternative_job| has already finished, it will not have notified - // the request yet, since we defer that to the next iteration of the - // MessageLoop, so starting |main_job_| is always safe. - main_job_->Start(request_->stream_type()); + if (dns_alpn_h3_job_) { + dns_alpn_h3_job_->Start(request_->stream_type()); + } + + if (main_job_) { + main_job_->Start(request_->stream_type()); + } return OK; } +void HttpStreamFactory::JobController::ClearInappropriateJobs() { + if (dns_alpn_h3_job_ && dns_alpn_h3_job_->HasAvailableQuicSession()) { + // Clear |main_job_| and |alternative_job_| here not to start them when + // there is an active session available for |dns_alpn_h3_job_|. + main_job_.reset(); + alternative_job_.reset(); + } + + if (alternative_job_ && dns_alpn_h3_job_ && + (alternative_job_->HasAvailableQuicSession() || + (alternative_service_info_.alternative_service() == + GetAlternativeServiceForDnsJob(request_info_.url)))) { + // Clear |dns_alpn_h3_job_|, when there is an active session available for + // |alternative_job_| or |alternative_job_| was created for the same + // destination. + dns_alpn_h3_job_.reset(); + } +} + void HttpStreamFactory::JobController::BindJob(Job* job) { DCHECK(request_); DCHECK(job); - DCHECK(job == alternative_job_.get() || job == main_job_.get()); + DCHECK(job == alternative_job_.get() || job == main_job_.get() || + job == dns_alpn_h3_job_.get()); DCHECK(!job_bound_); DCHECK(!bound_job_); @@ -839,54 +975,73 @@ void HttpStreamFactory::JobController::BindJob(Job* job) { OrphanUnboundJob(); } -void HttpStreamFactory::JobController::CancelJobs() { - DCHECK(request_); - if (job_bound_) - return; - if (alternative_job_) - alternative_job_.reset(); - if (main_job_) - main_job_.reset(); -} - void HttpStreamFactory::JobController::OrphanUnboundJob() { DCHECK(request_); DCHECK(bound_job_); - if (bound_job_->job_type() == MAIN && alternative_job_) { - DCHECK(!is_websocket_); - // Allow |alternative_job_| to run to completion, rather than resetting it - // to check if there is any broken alternative service to report. - // OnOrphanedJobComplete() will clean up |this| when the job completes. - alternative_job_->Orphan(); + if (bound_job_->job_type() == MAIN) { + // Allow |alternative_job_| and |dns_alpn_h3_job_| to run to completion, + // rather than resetting them to check if there is any broken alternative + // service to report. OnOrphanedJobComplete() will clean up |this| when the + // jobs complete. + if (alternative_job_) { + DCHECK(!is_websocket_); + alternative_job_->Orphan(); + } + if (dns_alpn_h3_job_) { + DCHECK(!is_websocket_); + dns_alpn_h3_job_->Orphan(); + } return; } - if (bound_job_->job_type() == ALTERNATIVE && main_job_ && - !alternative_job_failed_on_default_network_) { - // |request_| is bound to the alternative job and the alternative job - // succeeds on the default network. This means that the main job - // is no longer needed, so cancel it now. Pending ConnectJobs will return - // established sockets to socket pools if applicable. - // https://crbug.com/757548. - // The main job still needs to run if the alternative job succeeds on the - // alternate network in order to figure out whether QUIC should be marked as - // broken until the default network changes. - DCHECK_EQ(OK, alternative_job_net_error_); - main_job_.reset(); + if (bound_job_->job_type() == ALTERNATIVE) { + if (!alternative_job_failed_on_default_network_ && !dns_alpn_h3_job_) { + // |request_| is bound to the alternative job and the alternative job + // succeeds on the default network, and there is no DNS alt job. This + // means that the main job is no longer needed, so cancel it now. Pending + // ConnectJobs will return established sockets to socket pools if + // applicable. + // https://crbug.com/757548. + // The main job still needs to run if the alternative job succeeds on the + // alternate network in order to figure out whether QUIC should be marked + // as broken until the default network changes. And also the main job + // still needs to run if the DNS alt job exists to figure out whether + // the DNS alpn service is broken. + DCHECK(!main_job_ || (alternative_job_net_error_ == OK)); + main_job_.reset(); + } + // Allow |dns_alpn_h3_job_| to run to completion, rather than resetting + // it to check if there is any broken alternative service to report. + // OnOrphanedJobComplete() will clean up |this| when the job completes. + if (dns_alpn_h3_job_) { + DCHECK(!is_websocket_); + dns_alpn_h3_job_->Orphan(); + } + } + if (bound_job_->job_type() == DNS_ALPN_H3) { + if (!dns_alpn_h3_job_failed_on_default_network_ && !alternative_job_) { + DCHECK(!main_job_ || (dns_alpn_h3_job_net_error_ == OK)); + main_job_.reset(); + } + // Allow |alternative_job_| to run to completion, rather than resetting + // it to check if there is any broken alternative service to report. + // OnOrphanedJobComplete() will clean up |this| when the job completes. + if (alternative_job_) { + DCHECK(!is_websocket_); + alternative_job_->Orphan(); + } } } void HttpStreamFactory::JobController::OnJobSucceeded(Job* job) { DCHECK(job); - if (!bound_job_) { - if (main_job_ && alternative_job_) + if ((main_job_ && alternative_job_) || dns_alpn_h3_job_) ReportAlternateProtocolUsage(job); BindJob(job); return; } - DCHECK(bound_job_); } void HttpStreamFactory::JobController::MarkRequestComplete( @@ -897,77 +1052,75 @@ void HttpStreamFactory::JobController::MarkRequestComplete( request_->Complete(was_alpn_negotiated, negotiated_protocol, using_spdy); } -void HttpStreamFactory::JobController::OnAlternativeServiceJobFailed( - int net_error) { - DCHECK_EQ(alternative_job_->job_type(), ALTERNATIVE); - DCHECK_NE(OK, net_error); - DCHECK_NE(kProtoUnknown, alternative_service_info_.protocol()); - - alternative_job_net_error_ = net_error; -} - -void HttpStreamFactory::JobController::MaybeReportBrokenAlternativeService() { +void HttpStreamFactory::JobController::MaybeReportBrokenAlternativeService( + const AlternativeService& alt_service, + int alt_job_net_error, + bool alt_job_failed_on_default_network, + const std::string& histogram_name_for_failure) { // If alternative job succeeds on the default network, no brokenness to // report. - if (alternative_job_net_error_ == OK && - !alternative_job_failed_on_default_network_) + if (alt_job_net_error == OK && !alt_job_failed_on_default_network) return; // No brokenness to report if the main job fails. if (main_job_net_error_ != OK) return; - DCHECK(alternative_service_info_.protocol() != kProtoUnknown); + // No need to record DNS_NO_MACHING_SUPPORTED_ALPN error. + if (alt_job_net_error == ERR_DNS_NO_MACHING_SUPPORTED_ALPN) + return; - if (alternative_job_failed_on_default_network_ && - alternative_job_net_error_ == OK) { + if (alt_job_failed_on_default_network && alt_job_net_error == OK) { // Alternative job failed on the default network but succeeds on the // non-default network, mark alternative service broken until the default // network changes. session_->http_server_properties() ->MarkAlternativeServiceBrokenUntilDefaultNetworkChanges( - alternative_service_info_.alternative_service(), - request_info_.network_isolation_key); - // Reset error status for Jobs after reporting brokenness. - ResetErrorStatusForJobs(); + alt_service, request_info_.network_isolation_key); return; } - if (alternative_job_net_error_ == ERR_NETWORK_CHANGED || - alternative_job_net_error_ == ERR_INTERNET_DISCONNECTED || - (alternative_job_net_error_ == ERR_NAME_NOT_RESOLVED && - request_info_.url.host() == - alternative_service_info_.alternative_service().host)) { + if (alt_job_net_error == ERR_NETWORK_CHANGED || + alt_job_net_error == ERR_INTERNET_DISCONNECTED || + (alt_job_net_error == ERR_NAME_NOT_RESOLVED && + request_info_.url.host() == alt_service.host)) { // No need to mark alternative service as broken. - // Reset error status for Jobs. - ResetErrorStatusForJobs(); return; } // Report brokenness if alternative job failed. - base::UmaHistogramSparse("Net.AlternateServiceFailed", - -alternative_job_net_error_); + base::UmaHistogramSparse(histogram_name_for_failure, -alt_job_net_error); HistogramBrokenAlternateProtocolLocation( BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB_ALT); session_->http_server_properties()->MarkAlternativeServiceBroken( - alternative_service_info_.alternative_service(), - request_info_.network_isolation_key); - // Reset error status for Jobs after reporting brokenness. - ResetErrorStatusForJobs(); + alt_service, request_info_.network_isolation_key); } void HttpStreamFactory::JobController::MaybeNotifyFactoryOfCompletion() { - if (!main_job_ && !alternative_job_) { - // Both jobs are gone, report brokenness if apply. Error status for Jobs - // will be reset after reporting to avoid redundant reporting. - MaybeReportBrokenAlternativeService(); - } + if (main_job_ || alternative_job_ || dns_alpn_h3_job_) + return; - if (!request_ && !main_job_ && !alternative_job_) { - DCHECK(!bound_job_); - factory_->OnJobControllerComplete(this); - } + // All jobs are gone. + // Report brokenness for the alternate jobs if apply. + MaybeReportBrokenAlternativeService( + alternative_service_info_.alternative_service(), + alternative_job_net_error_, alternative_job_failed_on_default_network_, + "Net.AlternateServiceFailed"); + // Report for the DNS alt job if apply. + MaybeReportBrokenAlternativeService( + GetAlternativeServiceForDnsJob(request_info_.url), + dns_alpn_h3_job_net_error_, dns_alpn_h3_job_failed_on_default_network_, + "Net.AlternateServiceForDnsAlpnH3Failed"); + + // Reset error status for Jobs after reporting brokenness to avoid redundant + // reporting. + ResetErrorStatusForJobs(); + + if (request_) + return; + DCHECK(!bound_job_); + factory_->OnJobControllerComplete(this); } void HttpStreamFactory::JobController::NotifyRequestFailed(int rv) { @@ -1163,25 +1316,35 @@ quic::ParsedQuicVersion HttpStreamFactory::JobController::SelectQuicVersion( void HttpStreamFactory::JobController::ReportAlternateProtocolUsage( Job* job) const { - DCHECK(main_job_ && alternative_job_); + DCHECK((main_job_ && alternative_job_) || dns_alpn_h3_job_); bool is_google_host = HasGoogleHost(job->origin_url()); if (job == main_job_.get()) { - HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE, + HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE, is_google_host); return; } + if (job == alternative_job_.get()) { + if (job->using_existing_quic_session()) { + HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE, + is_google_host); + return; + } - DCHECK_EQ(alternative_job_.get(), job); - if (job->using_existing_quic_session()) { - HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE, + HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE, is_google_host); - return; } - - HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE, - is_google_host); + if (job == dns_alpn_h3_job_.get()) { + if (job->using_existing_quic_session()) { + HistogramAlternateProtocolUsage( + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_WITOUT_RACE, + is_google_host); + return; + } + HistogramAlternateProtocolUsage( + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, is_google_host); + } } bool HttpStreamFactory::JobController::IsJobOrphaned(Job* job) const { @@ -1191,7 +1354,7 @@ bool HttpStreamFactory::JobController::IsJobOrphaned(Job* job) const { int HttpStreamFactory::JobController::ReconsiderProxyAfterError(Job* job, int error) { // ReconsiderProxyAfterError() should only be called when the last job fails. - DCHECK(!(alternative_job_ && main_job_)); + DCHECK_EQ(1, GetJobCount()); DCHECK(!proxy_resolve_request_); DCHECK(session_); @@ -1215,6 +1378,7 @@ int HttpStreamFactory::JobController::ReconsiderProxyAfterError(Job* job, // Abandon all Jobs and start over. job_bound_ = false; bound_job_ = nullptr; + dns_alpn_h3_job_.reset(); alternative_job_.reset(); main_job_.reset(); ResetErrorStatusForJobs(); diff --git a/chromium/net/http/http_stream_factory_job_controller.h b/chromium/net/http/http_stream_factory_job_controller.h index e6149e3f076..2356e9bdce3 100644 --- a/chromium/net/http/http_stream_factory_job_controller.h +++ b/chromium/net/http/http_stream_factory_job_controller.h @@ -52,6 +52,7 @@ class HttpStreamFactory::JobController // Used in tests only for verification purpose. const Job* main_job() const { return main_job_.get(); } const Job* alternative_job() const { return alternative_job_.get(); } + const Job* dns_alpn_h3_job() const { return dns_alpn_h3_job_.get(); } void RewriteUrlWithHostMappingRules(GURL& url); @@ -128,7 +129,7 @@ class HttpStreamFactory::JobController HttpAuthController* auth_controller) override; // Invoked when the |job| finishes pre-connecting sockets. - void OnPreconnectsComplete(Job* job) override; + void OnPreconnectsComplete(Job* job, int result) override; // Invoked to record connection attempts made by the socket layer to // Request if |job| is associated with Request. @@ -185,10 +186,6 @@ class HttpStreamFactory::JobController // still associated with |request_|. void BindJob(Job* job); - // Called when |request_| is destructed. - // Job(s) associated with but not bound to |request_| will be deleted. - void CancelJobs(); - // Called after BindJob() to notify the unbound job that its result should be // ignored by JobController. The unbound job can be canceled or continue until // completion. @@ -200,15 +197,14 @@ class HttpStreamFactory::JobController // Called when a Job succeeds. void OnJobSucceeded(Job* job); + // Clears inappropriate jobs before starting them. + void ClearInappropriateJobs(); + // Marks completion of the |request_|. void MarkRequestComplete(bool was_alpn_negotiated, NextProto negotiated_protocol, bool using_spdy); - // Must be called when the alternative service job fails. |net_error| is the - // net error of the failed alternative service job. - void OnAlternativeServiceJobFailed(int net_error); - // Called when all Jobs complete. Reports alternative service brokenness to // HttpServerProperties if apply and resets net errors afterwards: // - report broken if the main job has no error and the alternative job has an @@ -216,7 +212,11 @@ class HttpStreamFactory::JobController // - report broken until default network change if the main job has no error, // the alternative job has no error, but the alternative job failed on the // default network. - void MaybeReportBrokenAlternativeService(); + void MaybeReportBrokenAlternativeService( + const AlternativeService& alt_service, + int alt_job_net_error, + bool alt_job_failed_on_default_network, + const std::string& histogram_name_for_failure); void MaybeNotifyFactoryOfCompletion(); @@ -233,8 +233,10 @@ class HttpStreamFactory::JobController void ResumeMainJob(); // Reset error status to default value for Jobs: - // - reset |main_job_net_error_| and |alternative_job_net_error_| to OK; - // - reset |alternative_job_failed_on_default_network_| to false. + // - reset |main_job_net_error_| and |alternative_job_net_error_| and + // |dns_alpn_h3_job_net_error_| to OK; + // - reset |alternative_job_failed_on_default_network_| and + // |dns_alpn_h3_job_failed_on_default_network_| to false. void ResetErrorStatusForJobs(); AlternativeServiceInfo GetAlternativeServiceInfoFor( @@ -272,6 +274,11 @@ class HttpStreamFactory::JobController // Returns true if QUIC is allowed for |host|. bool IsQuicAllowedForHost(const std::string& host); + int GetJobCount() const { + return (main_job_ ? 1 : 0) + (alternative_job_ ? 1 : 0) + + (dns_alpn_h3_job_ ? 1 : 0); + } + raw_ptr<HttpStreamFactory> factory_; raw_ptr<HttpNetworkSession> session_; raw_ptr<JobFactory> job_factory_; @@ -280,7 +287,7 @@ class HttpStreamFactory::JobController // reference and is safe as |request_| will notify |this| JobController // when it's destructed by calling OnRequestComplete(), which nulls // |request_|. - raw_ptr<HttpStreamRequest> request_ = nullptr; + raw_ptr<HttpStreamRequest, DanglingUntriaged> request_ = nullptr; const raw_ptr<HttpStreamRequest::Delegate> delegate_; @@ -297,11 +304,19 @@ class HttpStreamFactory::JobController // Enable using alternative services for the request. const bool enable_alternative_services_; - // |main_job_| is a job waiting to see if |alternative_job_| can reuse a - // connection. If |alternative_job_| is unable to do so, |this| will notify - // |main_job_| to proceed and then race the two jobs. + // For normal (non-preconnect) job, |main_job_| is a job waiting to see if + // |alternative_job_| or |dns_alpn_h3_job_| can reuse a connection. If both + // |alternative_job_| and |dns_alpn_h3_job_| are unable to do so, |this| will + // notify |main_job_| to proceed and then race the two jobs. + // For preconnect job, |main_job_| is started first, and if it fails with + // ERR_DNS_NO_MACHING_SUPPORTED_ALPN, |preconnect_backup_job_| will be + // started. std::unique_ptr<Job> main_job_; std::unique_ptr<Job> alternative_job_; + std::unique_ptr<Job> dns_alpn_h3_job_; + + std::unique_ptr<Job> preconnect_backup_job_; + // The alternative service used by |alternative_job_| // (or by |main_job_| if |is_preconnect_|.) AlternativeServiceInfo alternative_service_info_; @@ -313,6 +328,10 @@ class HttpStreamFactory::JobController int alternative_job_net_error_ = OK; // Set to true if the alternative job failed on the default network. bool alternative_job_failed_on_default_network_ = false; + // Net error code of the DNS HTTPS ALPN job. Set to OK by default. + int dns_alpn_h3_job_net_error_ = OK; + // Set to true if the DNS HTTPS ALPN job failed on the default network. + bool dns_alpn_h3_job_failed_on_default_network_ = false; // True if a Job has ever been bound to the |request_|. bool job_bound_ = false; diff --git a/chromium/net/http/http_stream_factory_job_controller_unittest.cc b/chromium/net/http/http_stream_factory_job_controller_unittest.cc index c401c7b4167..63097239951 100644 --- a/chromium/net/http/http_stream_factory_job_controller_unittest.cc +++ b/chromium/net/http/http_stream_factory_job_controller_unittest.cc @@ -16,6 +16,7 @@ #include "base/memory/scoped_refptr.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" @@ -30,6 +31,7 @@ #include "net/base/test_proxy_delegate.h" #include "net/dns/mock_host_resolver.h" #include "net/dns/public/secure_dns_policy.h" +#include "net/http/alternative_service.h" #include "net/http/http_basic_stream.h" #include "net/http/http_network_session_peer.h" #include "net/http/http_response_headers.h" @@ -46,9 +48,11 @@ #include "net/proxy_resolution/mock_proxy_resolver.h" #include "net/proxy_resolution/proxy_config_service_fixed.h" #include "net/proxy_resolution/proxy_info.h" +#include "net/quic/crypto/proof_verifier_chromium.h" #include "net/quic/mock_crypto_client_stream_factory.h" #include "net/quic/mock_quic_context.h" #include "net/quic/mock_quic_data.h" +#include "net/quic/quic_http_stream.h" #include "net/quic/quic_stream_factory.h" #include "net/quic/quic_stream_factory_peer.h" #include "net/quic/quic_test_packet_maker.h" @@ -73,14 +77,16 @@ using ::testing::IsEmpty; using ::testing::Key; using ::testing::SizeIs; -namespace net { - -namespace test { +namespace net::test { namespace { const char kServerHostname[] = "www.example.com"; +// The default delay for main job defined in QuicStreamFactory:: +// GetTimeDelayForWaitingJob(). +const int kDefaultDelayMilliSecsForWaitingJob = 300; + class FailingProxyResolverFactory : public ProxyResolverFactory { public: FailingProxyResolverFactory() : ProxyResolverFactory(false) {} @@ -175,13 +181,23 @@ class JobControllerPeer { HttpStreamFactoryJobPeer::SetQuicConnectionFailedOnDefaultNetwork( job_controller->alternative_job_.get()); } + static void SetDnsAlpnH3JobFailedOnDefaultNetwork( + HttpStreamFactory::JobController* job_controller) { + DCHECK(job_controller->dns_alpn_h3_job() != nullptr); + HttpStreamFactoryJobPeer::SetQuicConnectionFailedOnDefaultNetwork( + job_controller->dns_alpn_h3_job_.get()); + } }; -class HttpStreamFactoryJobControllerTest : public TestWithTaskEnvironment { +class HttpStreamFactoryJobControllerTestBase : public TestWithTaskEnvironment { public: - HttpStreamFactoryJobControllerTest() + explicit HttpStreamFactoryJobControllerTestBase(bool dns_https_alpn_enabled) : TestWithTaskEnvironment( - base::test::TaskEnvironment::TimeSource::MOCK_TIME) { + base::test::TaskEnvironment::TimeSource::MOCK_TIME), + dns_https_alpn_enabled_(dns_https_alpn_enabled) { + if (dns_https_alpn_enabled_) { + feature_list_.InitWithFeatures({features::kUseDnsHttpsSvcbAlpn}, {}); + } FLAGS_quic_enable_http3_grease_randomness = false; CreateSessionDeps(); } @@ -230,8 +246,12 @@ class HttpStreamFactoryJobControllerTest : public TestWithTaskEnvironment { if (quic_data_) quic_data_->AddSocketDataToFactory(session_deps_.socket_factory.get()); + if (quic_data2_) + quic_data2_->AddSocketDataToFactory(session_deps_.socket_factory.get()); if (tcp_data_) session_deps_.socket_factory->AddSocketDataProvider(tcp_data_.get()); + if (tcp_data2_) + session_deps_.socket_factory->AddSocketDataProvider(tcp_data2_.get()); session_deps_.proxy_resolution_service->SetProxyDelegate( test_proxy_delegate_.get()); @@ -248,13 +268,15 @@ class HttpStreamFactoryJobControllerTest : public TestWithTaskEnvironment { session_ = std::make_unique<HttpNetworkSession>(params, session_context); factory_ = static_cast<HttpStreamFactory*>(session_->http_stream_factory()); if (create_job_controller_) { - job_controller_ = new HttpStreamFactory::JobController( + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( factory_, &request_delegate_, session_.get(), &job_factory_, request_info, is_preconnect_, false /* is_websocket */, enable_ip_based_pooling_, enable_alternative_services_, delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller_); + job_controller_ = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); } } @@ -262,20 +284,28 @@ class HttpStreamFactoryJobControllerTest : public TestWithTaskEnvironment { return test_proxy_delegate_.get(); } - HttpStreamFactoryJobControllerTest( - const HttpStreamFactoryJobControllerTest&) = delete; - HttpStreamFactoryJobControllerTest& operator=( - const HttpStreamFactoryJobControllerTest&) = delete; + HttpStreamFactoryJobControllerTestBase( + const HttpStreamFactoryJobControllerTestBase&) = delete; + HttpStreamFactoryJobControllerTestBase& operator=( + const HttpStreamFactoryJobControllerTestBase&) = delete; - ~HttpStreamFactoryJobControllerTest() override { + ~HttpStreamFactoryJobControllerTestBase() override { if (quic_data_) { EXPECT_TRUE(quic_data_->AllReadDataConsumed()); EXPECT_TRUE(quic_data_->AllWriteDataConsumed()); } + if (quic_data2_) { + EXPECT_TRUE(quic_data2_->AllReadDataConsumed()); + EXPECT_TRUE(quic_data2_->AllWriteDataConsumed()); + } if (tcp_data_) { EXPECT_TRUE(tcp_data_->AllReadDataConsumed()); EXPECT_TRUE(tcp_data_->AllWriteDataConsumed()); } + if (tcp_data2_) { + EXPECT_TRUE(tcp_data2_->AllReadDataConsumed()); + EXPECT_TRUE(tcp_data2_->AllWriteDataConsumed()); + } } void SetAlternativeService(const HttpRequestInfo& request_info, @@ -327,6 +357,8 @@ class HttpStreamFactoryJobControllerTest : public TestWithTaskEnvironment { const quic::ParsedQuicVersion& expected_version, const quic::ParsedQuicVersionVector& supported_versions); + bool dns_https_alpn_enabled() const { return dns_https_alpn_enabled_; } + quic::ParsedQuicVersion version_ = DefaultSupportedQuicVersions().front(); RecordingNetLogObserver net_log_observer_; NetLogWithSource net_log_with_source_{ @@ -340,7 +372,9 @@ class HttpStreamFactoryJobControllerTest : public TestWithTaskEnvironment { raw_ptr<HttpStreamFactory::JobController> job_controller_ = nullptr; std::unique_ptr<HttpStreamRequest> request_; std::unique_ptr<SequencedSocketData> tcp_data_; + std::unique_ptr<SequencedSocketData> tcp_data2_; std::unique_ptr<MockQuicData> quic_data_; + std::unique_ptr<MockQuicData> quic_data2_; MockCryptoClientStreamFactory crypto_client_stream_factory_; QuicTestPacketMaker client_maker_{version_, quic::QuicUtils::CreateRandomConnectionId( @@ -357,11 +391,26 @@ class HttpStreamFactoryJobControllerTest : public TestWithTaskEnvironment { bool delay_main_job_with_available_spdy_session_ = true; private: + bool dns_https_alpn_enabled_; std::unique_ptr<TestProxyDelegate> test_proxy_delegate_; bool create_job_controller_ = true; + + base::test::ScopedFeatureList feature_list_; +}; + +class HttpStreamFactoryJobControllerTest + : public HttpStreamFactoryJobControllerTestBase, + public ::testing::WithParamInterface<bool> { + protected: + HttpStreamFactoryJobControllerTest() + : HttpStreamFactoryJobControllerTestBase(GetParam()) {} }; -TEST_F(HttpStreamFactoryJobControllerTest, ProxyResolutionFailsSync) { +INSTANTIATE_TEST_SUITE_P(All, + HttpStreamFactoryJobControllerTest, + testing::Bool()); + +TEST_P(HttpStreamFactoryJobControllerTest, ProxyResolutionFailsSync) { ProxyConfig proxy_config; proxy_config.set_pac_url(GURL("http://fooproxyurl")); proxy_config.set_pac_mandatory(true); @@ -398,19 +447,20 @@ TEST_F(HttpStreamFactoryJobControllerTest, ProxyResolutionFailsSync) { EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -TEST_F(HttpStreamFactoryJobControllerTest, ProxyResolutionFailsAsync) { +TEST_P(HttpStreamFactoryJobControllerTest, ProxyResolutionFailsAsync) { ProxyConfig proxy_config; proxy_config.set_pac_url(GURL("http://fooproxyurl")); proxy_config.set_pac_mandatory(true); - MockAsyncProxyResolverFactory* proxy_resolver_factory = - new MockAsyncProxyResolverFactory(false); + auto proxy_resolver_factory = + std::make_unique<MockAsyncProxyResolverFactory>(false); + auto* proxy_resolver_factory_ptr = proxy_resolver_factory.get(); MockAsyncProxyResolver resolver; session_deps_.proxy_resolution_service = std::make_unique<ConfiguredProxyResolutionService>( std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation( proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)), - base::WrapUnique(proxy_resolver_factory), nullptr, + std::move(proxy_resolver_factory), nullptr, /*quick_check_enabled=*/true); HttpRequestInfo request_info; request_info.method = "GET"; @@ -432,16 +482,16 @@ TEST_F(HttpStreamFactoryJobControllerTest, ProxyResolutionFailsAsync) { request_delegate_, OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _, _, _, _)) .Times(1); - proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( + proxy_resolver_factory_ptr->pending_requests()[0]->CompleteNowWithForwarder( ERR_FAILED, &resolver); base::RunLoop().RunUntilIdle(); request_.reset(); EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -TEST_F(HttpStreamFactoryJobControllerTest, NoSupportedProxies) { +TEST_P(HttpStreamFactoryJobControllerTest, NoSupportedProxies) { session_deps_.proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS); session_deps_.enable_quic = false; HttpRequestInfo request_info; @@ -466,8 +516,10 @@ TEST_F(HttpStreamFactoryJobControllerTest, NoSupportedProxies) { } class JobControllerReconsiderProxyAfterErrorTest - : public HttpStreamFactoryJobControllerTest { + : public HttpStreamFactoryJobControllerTestBase { public: + JobControllerReconsiderProxyAfterErrorTest() + : HttpStreamFactoryJobControllerTestBase(false) {} void Initialize( std::unique_ptr<ProxyResolutionService> proxy_resolution_service) { session_deps_.proxy_resolution_service = @@ -480,15 +532,15 @@ class JobControllerReconsiderProxyAfterErrorTest std::unique_ptr<HttpStreamRequest> CreateJobController( const HttpRequestInfo& request_info) { - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, &request_delegate_, session_.get(), &default_job_factory_, - request_info, is_preconnect_, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - return job_controller->Start( + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, &request_delegate_, session_.get(), &default_job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); + return job_controller_ptr->Start( &request_delegate_, nullptr, net_log_with_source_, HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); } @@ -546,7 +598,7 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest, std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "PROXY badproxy:99; PROXY badfallbackproxy:98; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); auto test_proxy_delegate = std::make_unique<TestProxyDelegate>(); @@ -732,12 +784,12 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest, std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); if (mock_error.triggers_ssl_connect_job_retry_logic) { proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS badproxy:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); } auto test_proxy_delegate = std::make_unique<TestProxyDelegate>(); @@ -931,7 +983,7 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest, CreateSessionDeps(); std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "SOCKS5 badproxy:99; SOCKS5 badfallbackproxy:98; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); auto test_proxy_delegate = std::make_unique<TestProxyDelegate>(); @@ -1044,7 +1096,7 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest, // Tests that ERR_MSG_TOO_BIG is retryable for QUIC proxy. TEST_F(JobControllerReconsiderProxyAfterErrorTest, ReconsiderErrMsgTooBig) { std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "QUIC badproxy:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); // Before starting the test, verify that there are no proxies marked as bad. @@ -1091,7 +1143,7 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest, ReconsiderErrMsgTooBig) { TEST_F(JobControllerReconsiderProxyAfterErrorTest, DoNotReconsiderErrMsgTooBig) { std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS badproxy:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); // Before starting the test, verify that there are no proxies marked as bad. @@ -1133,7 +1185,7 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest, EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -TEST_F(HttpStreamFactoryJobControllerTest, OnStreamFailedWithNoAlternativeJob) { +TEST_P(HttpStreamFactoryJobControllerTest, OnStreamFailedWithNoAlternativeJob) { tcp_data_ = std::make_unique<SequencedSocketData>(); tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); @@ -1157,7 +1209,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, OnStreamFailedWithNoAlternativeJob) { base::RunLoop().RunUntilIdle(); } -TEST_F(HttpStreamFactoryJobControllerTest, OnStreamReadyWithNoAlternativeJob) { +TEST_P(HttpStreamFactoryJobControllerTest, OnStreamReadyWithNoAlternativeJob) { tcp_data_ = std::make_unique<SequencedSocketData>(); tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); @@ -1181,7 +1233,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, OnStreamReadyWithNoAlternativeJob) { // Test we cancel Jobs correctly when the Request is explicitly canceled // before any Job is bound to Request. -TEST_F(HttpStreamFactoryJobControllerTest, CancelJobsBeforeBinding) { +TEST_P(HttpStreamFactoryJobControllerTest, CancelJobsBeforeBinding) { // Use COLD_START to make the alt job pending. crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::COLD_START); @@ -1216,7 +1268,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, CancelJobsBeforeBinding) { // Test that the controller does not create alternative job when the advertised // versions in AlternativeServiceInfo do not contain any version that is // supported. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, DoNotCreateAltJobIfQuicVersionsUnsupported) { tcp_data_ = std::make_unique<SequencedSocketData>(); tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); @@ -1243,7 +1295,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, DoNotDelayMainJobIfQuicWasRecentlyBroken) { crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::COLD_START); @@ -1301,7 +1353,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, DelayMainJobAfterRecentlyBrokenQuicWasConfirmed) { crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::COLD_START); @@ -1365,7 +1417,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -void HttpStreamFactoryJobControllerTest::TestOnStreamFailedForBothJobs( +void HttpStreamFactoryJobControllerTestBase::TestOnStreamFailedForBothJobs( bool alt_job_retried_on_non_default_network) { quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddConnect(ASYNC, ERR_FAILED); @@ -1404,20 +1456,21 @@ void HttpStreamFactoryJobControllerTest::TestOnStreamFailedForBothJobs( // This test verifies that the alternative service is not marked broken if both // jobs fail, and the alternative job is not retried on the alternate network. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, OnStreamFailedForBothJobsWithoutQuicRetry) { TestOnStreamFailedForBothJobs(false); } // This test verifies that the alternative service is not marked broken if both // jobs fail, and the alternative job is retried on the alternate network. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, OnStreamFailedForBothJobsWithQuicRetriedOnAlternateNetwork) { TestOnStreamFailedForBothJobs(true); } -void HttpStreamFactoryJobControllerTest::TestAltJobFailsAfterMainJobSucceeded( - bool alt_job_retried_on_non_default_network) { +void HttpStreamFactoryJobControllerTestBase:: + TestAltJobFailsAfterMainJobSucceeded( + bool alt_job_retried_on_non_default_network) { quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddRead(ASYNC, ERR_FAILED); crypto_client_stream_factory_.set_handshake_mode( @@ -1472,7 +1525,7 @@ void HttpStreamFactoryJobControllerTest::TestAltJobFailsAfterMainJobSucceeded( // This test verifies that the alternatvie service is marked broken when the // alternative job fails on default after the main job succeeded. The // brokenness should not be cleared when the default network changes. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltJobFailsOnDefaultNetworkAfterMainJobSucceeded) { TestAltJobFailsAfterMainJobSucceeded(false); } @@ -1480,13 +1533,13 @@ TEST_F(HttpStreamFactoryJobControllerTest, // This test verifies that the alternatvie service is marked broken when the // alternative job fails on both networks after the main job succeeded. The // brokenness should not be cleared when the default network changes. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltJobFailsOnBothNetworksAfterMainJobSucceeded) { TestAltJobFailsAfterMainJobSucceeded(true); } // Tests that when alt job succeeds, main job is destroyed. -TEST_F(HttpStreamFactoryJobControllerTest, AltJobSucceedsMainJobDestroyed) { +TEST_P(HttpStreamFactoryJobControllerTest, AltJobSucceedsMainJobDestroyed) { quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Use cold start and complete alt job manually. @@ -1533,7 +1586,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, AltJobSucceedsMainJobDestroyed) { // Tests that if alt job succeeds and main job is blocked, main job should be // cancelled immediately. |request_| completion will clean up the JobController. // Regression test for crbug.com/678768. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltJobSucceedsMainJobBlockedControllerDestroyed) { quic_data_ = std::make_unique<MockQuicData>(version_); if (version_.UsesHttp3()) { @@ -1574,7 +1627,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, SpdySessionKeyHasOriginHostPortPair) { session_deps_.enable_http2_alternative_service = true; @@ -1614,7 +1667,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Tests that if an orphaned job completes after |request_| is gone, // JobController will be cleaned up. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, OrphanedJobCompletesControllerDestroyed) { quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); @@ -1668,8 +1721,9 @@ TEST_F(HttpStreamFactoryJobControllerTest, EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -void HttpStreamFactoryJobControllerTest::TestAltJobSucceedsAfterMainJobFailed( - bool alt_job_retried_on_non_default_network) { +void HttpStreamFactoryJobControllerTestBase:: + TestAltJobSucceedsAfterMainJobFailed( + bool alt_job_retried_on_non_default_network) { quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Use cold start and complete alt job manually. @@ -1723,19 +1777,19 @@ void HttpStreamFactoryJobControllerTest::TestAltJobSucceedsAfterMainJobFailed( // This test verifies that the alternative service is not mark broken if the // alternative job succeeds on the default network after the main job failed. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltJobSucceedsOnDefaultNetworkAfterMainJobFailed) { TestAltJobSucceedsAfterMainJobFailed(false); } // This test verifies that the alternative service is not mark broken if the // alternative job succeeds on the alternate network after the main job failed. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltJobSucceedsOnAlternateNetwrokAfterMainJobFailed) { TestAltJobSucceedsAfterMainJobFailed(true); } -void HttpStreamFactoryJobControllerTest:: +void HttpStreamFactoryJobControllerTestBase:: TestAltJobSucceedsAfterMainJobSucceeded( bool alt_job_retried_on_non_default_network) { quic_data_ = std::make_unique<MockQuicData>(version_); @@ -1803,7 +1857,7 @@ void HttpStreamFactoryJobControllerTest:: // This test verifies that the alternative service is not marked broken if the // alternative job succeeds on the default network after the main job succeeded. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltJobSucceedsOnDefaultNetworkAfterMainJobSucceeded) { TestAltJobSucceedsAfterMainJobSucceeded(false); } @@ -1813,12 +1867,12 @@ TEST_F(HttpStreamFactoryJobControllerTest, // network, which failed on the default network previously, after the main job // succeeded. The brokenness should be cleared when the default network // changes. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltJobSucceedsOnAlternateNetworkAfterMainJobSucceeded) { TestAltJobSucceedsAfterMainJobSucceeded(true); } -void HttpStreamFactoryJobControllerTest:: +void HttpStreamFactoryJobControllerTestBase:: TestMainJobSucceedsAfterAltJobSucceeded( bool alt_job_retried_on_non_default_network) { quic_data_ = std::make_unique<MockQuicData>(version_); @@ -1880,7 +1934,7 @@ void HttpStreamFactoryJobControllerTest:: // This test verifies that the alternative service is not marked broken if the // main job succeeds after the alternative job succeeded on the default network. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterAltJobSucceededOnDefaultNetwork) { TestMainJobSucceedsAfterAltJobSucceeded(false); } @@ -1890,13 +1944,14 @@ TEST_F(HttpStreamFactoryJobControllerTest, // succeeded on the non-default network, i.e., failed on the default network // previously. The brokenness should be cleared when the default network // changes. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterAltJobSucceededOnAlternateNetwork) { TestMainJobSucceedsAfterAltJobSucceeded(true); } -void HttpStreamFactoryJobControllerTest::TestMainJobFailsAfterAltJobSucceeded( - bool alt_job_retried_on_non_default_network) { +void HttpStreamFactoryJobControllerTestBase:: + TestMainJobFailsAfterAltJobSucceeded( + bool alt_job_retried_on_non_default_network) { quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Use cold start and complete alt job manually. @@ -1945,7 +2000,7 @@ void HttpStreamFactoryJobControllerTest::TestMainJobFailsAfterAltJobSucceeded( // This test verifies that the alternative service is not marked broken if the // main job fails after the alternative job succeeded on the default network. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobFailsAfterAltJobSucceededOnDefaultNetwork) { TestMainJobFailsAfterAltJobSucceeded(false); } @@ -1953,13 +2008,14 @@ TEST_F(HttpStreamFactoryJobControllerTest, // This test verifies that the alternative service is not marked broken if the // main job fails after the alternative job succeeded on the non-default // network, i.e., failed on the default network previously. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobFailsAfterAltJobSucceededOnAlternateNetwork) { TestMainJobFailsAfterAltJobSucceeded(true); } -void HttpStreamFactoryJobControllerTest::TestMainJobSucceedsAfterAltJobFailed( - bool alt_job_retried_on_non_default_network) { +void HttpStreamFactoryJobControllerTestBase:: + TestMainJobSucceedsAfterAltJobFailed( + bool alt_job_retried_on_non_default_network) { quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED); @@ -2011,7 +2067,7 @@ void HttpStreamFactoryJobControllerTest::TestMainJobSucceedsAfterAltJobFailed( // This test verifies that the alternative service will be marked broken when // the alternative job fails on the default network and main job succeeds later. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterAltJobFailedOnDefaultNetwork) { TestMainJobSucceedsAfterAltJobFailed(false); } @@ -2019,15 +2075,15 @@ TEST_F(HttpStreamFactoryJobControllerTest, // This test verifies that the alternative service will be marked broken when // the alternative job fails on both default and alternate networks and main job // succeeds later. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterAltJobFailedOnBothNetworks) { TestMainJobSucceedsAfterAltJobFailed(true); } -void HttpStreamFactoryJobControllerTest::TestMainJobSucceedsAfterIgnoredError( - int net_error, - bool expect_broken, - std::string alternate_host) { +void HttpStreamFactoryJobControllerTestBase:: + TestMainJobSucceedsAfterIgnoredError(int net_error, + bool expect_broken, + std::string alternate_host) { quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddConnect(SYNCHRONOUS, net_error); tcp_data_ = std::make_unique<SequencedSocketData>(); @@ -2073,27 +2129,27 @@ void HttpStreamFactoryJobControllerTest::TestMainJobSucceedsAfterIgnoredError( // Verifies that if the alternative job fails due to a connection change event, // then the alternative service is not marked as broken. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterConnectionChanged) { TestMainJobSucceedsAfterIgnoredError(ERR_NETWORK_CHANGED); } // Verifies that if the alternative job fails due to a disconnected network, // then the alternative service is not marked as broken. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterInternetDisconnected) { TestMainJobSucceedsAfterIgnoredError(ERR_INTERNET_DISCONNECTED); } // Verifies that if the alternative job fails due to a DNS failure, // then the alternative service is not marked as broken. -TEST_F(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterDnsFailure) { +TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterDnsFailure) { TestMainJobSucceedsAfterIgnoredError(ERR_NAME_NOT_RESOLVED); } // Verifies that if the alternative job fails due to a DNS failure on a // different name, then the alternative service is marked as broken. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterDnsFailureWithAlternateName) { TestMainJobSucceedsAfterIgnoredError(ERR_NAME_NOT_RESOLVED, true, "alternate.google.com"); @@ -2101,7 +2157,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Regression test for crbug/621069. // Get load state after main job fails and before alternative job succeeds. -TEST_F(HttpStreamFactoryJobControllerTest, GetLoadStateAfterMainJobFailed) { +TEST_P(HttpStreamFactoryJobControllerTest, GetLoadStateAfterMainJobFailed) { // Use COLD_START to complete alt job manually. quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); @@ -2148,7 +2204,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, GetLoadStateAfterMainJobFailed) { EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } -TEST_F(HttpStreamFactoryJobControllerTest, ResumeMainJobWhenAltJobStalls) { +TEST_P(HttpStreamFactoryJobControllerTest, ResumeMainJobWhenAltJobStalls) { // Use COLD_START to stall alt job. quic_data_ = std::make_unique<MockQuicData>(version_); quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); @@ -2181,7 +2237,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, ResumeMainJobWhenAltJobStalls) { base::RunLoop().RunUntilIdle(); } -TEST_F(HttpStreamFactoryJobControllerTest, InvalidPortForQuic) { +TEST_P(HttpStreamFactoryJobControllerTest, InvalidPortForQuic) { HttpRequestInfo request_info; request_info.method = "GET"; request_info.url = GURL("https://www.google.com"); @@ -2207,7 +2263,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, InvalidPortForQuic) { // Verifies that the main job is not resumed until after the alt job completes // host resolution. -TEST_F(HttpStreamFactoryJobControllerTest, HostResolutionHang) { +TEST_P(HttpStreamFactoryJobControllerTest, HostResolutionHang) { auto hanging_resolver = std::make_unique<MockHostResolver>(); hanging_resolver->set_ondemand_mode(true); hanging_resolver->rules()->AddRule("www.google.com", "1.2.3.4"); @@ -2279,13 +2335,13 @@ TEST_F(HttpStreamFactoryJobControllerTest, HostResolutionHang) { // OnStreamFailed will post a task to resume the main job immediately but // won't call Resume() on the main job since it's been resumed already. EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); - quic_data.GetSequencedSocketData()->Resume(); + quic_data.Resume(); FastForwardUntilNoTasksRemain(); // Alt job should be cleaned up EXPECT_FALSE(job_controller_->alternative_job()); } -TEST_F(HttpStreamFactoryJobControllerTest, DelayedTCP) { +TEST_P(HttpStreamFactoryJobControllerTest, DelayedTCP) { HttpRequestInfo request_info; request_info.method = "GET"; request_info.url = GURL("https://www.google.com"); @@ -2340,13 +2396,13 @@ TEST_F(HttpStreamFactoryJobControllerTest, DelayedTCP) { // Unpause mock quic data and run all remaining tasks. Alt-job should fail // and be cleaned up. - quic_data.GetSequencedSocketData()->Resume(); + quic_data.Resume(); FastForwardUntilNoTasksRemain(); EXPECT_FALSE(job_controller_->alternative_job()); } // Regression test for crbug.com/789560. -TEST_F(HttpStreamFactoryJobControllerTest, ResumeMainJobLaterCanceled) { +TEST_P(HttpStreamFactoryJobControllerTest, ResumeMainJobLaterCanceled) { std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service = ConfiguredProxyResolutionService::CreateDirect(); ConfiguredProxyResolutionService* proxy_resolution_service_raw = @@ -2424,7 +2480,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, ResumeMainJobLaterCanceled) { // http_server_properties cached an inappropriate large srtt for the server, // which would potentially delay the main job for a extremely long time in // delayed tcp case. -TEST_F(HttpStreamFactoryJobControllerTest, DelayedTCPWithLargeSrtt) { +TEST_P(HttpStreamFactoryJobControllerTest, DelayedTCPWithLargeSrtt) { // The max delay time should be in sync with .cc file. base::TimeDelta kMaxDelayTimeForMainJob = base::Seconds(3); @@ -2481,14 +2537,14 @@ TEST_F(HttpStreamFactoryJobControllerTest, DelayedTCPWithLargeSrtt) { // Unpause mock quic data and run all remaining tasks. Alt-job should fail // and be cleaned up. - quic_data.GetSequencedSocketData()->Resume(); + quic_data.Resume(); FastForwardUntilNoTasksRemain(); EXPECT_FALSE(job_controller_->alternative_job()); } // TODO(https://crbug.com/1007502): Disabled because the pending task count does // not match expectations. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, DISABLED_ResumeMainJobImmediatelyOnStreamFailed) { HttpRequestInfo request_info; request_info.method = "GET"; @@ -2540,7 +2596,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Now unpause the mock quic data to fail the alt job. This should immediately // resume the main job. EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); - quic_data.GetSequencedSocketData()->Resume(); + quic_data.Resume(); FastForwardBy(base::TimeDelta()); EXPECT_TRUE(job_controller_->main_job()); @@ -2556,7 +2612,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, FastForwardUntilNoTasksRemain(); } -TEST_F(HttpStreamFactoryJobControllerTest, PreconnectToHostWithValidAltSvc) { +TEST_P(HttpStreamFactoryJobControllerTest, PreconnectToHostWithValidAltSvc) { quic_data_ = std::make_unique<MockQuicData>(version_); if (version_.UsesHttp3()) { quic_data_->AddWrite(SYNCHRONOUS, @@ -2586,7 +2642,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, PreconnectToHostWithValidAltSvc) { } // When preconnect to a H2 supported server, only 1 connection is opened. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, PreconnectMultipleStreamsToH2Server) { tcp_data_ = std::make_unique<SequencedSocketData>(); tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); @@ -2618,7 +2674,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Check that the logic to only preconnect a single socket to servers with H2 // support respects NetworkIsolationKeys. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, PreconnectMultipleStreamsToH2ServerWithNetworkIsolationKey) { base::test::ScopedFeatureList feature_list; // It's not strictly necessary to enable @@ -2684,29 +2740,29 @@ TEST_F(HttpStreamFactoryJobControllerTest, request_info.network_isolation_key = other_network_isolation_key; MockHttpStreamRequestDelegate request_delegate; - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, &request_delegate, session_.get(), &job_factory_, - request_info, is_preconnect_, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - job_controller->Preconnect(/*num_streams=*/5); + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, &request_delegate, session_.get(), &job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); + job_controller_ptr->Preconnect(/*num_streams=*/5); // Five jobs should be started. - EXPECT_TRUE(job_controller->main_job()); - EXPECT_FALSE(job_controller->alternative_job()); + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_FALSE(job_controller_ptr->alternative_job()); EXPECT_EQ(HttpStreamFactory::PRECONNECT, - job_controller->main_job()->job_type()); - EXPECT_EQ( - 5, HttpStreamFactoryJobPeer::GetNumStreams(job_controller->main_job())); + job_controller_ptr->main_job()->job_type()); + EXPECT_EQ(5, HttpStreamFactoryJobPeer::GetNumStreams( + job_controller_ptr->main_job())); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); } } -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, DonotDelayMainJobIfHasAvailableSpdySession) { SetNotDelayMainJobWithAvailableSpdySession(); HttpRequestInfo request_info; @@ -2760,7 +2816,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Check the case that while a preconnect is waiting in the H2 request queue, // and a SPDY session appears, the job completes successfully. -TEST_F(HttpStreamFactoryJobControllerTest, SpdySessionInterruptsPreconnect) { +TEST_P(HttpStreamFactoryJobControllerTest, SpdySessionInterruptsPreconnect) { // Make sure there is only one socket connect. MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 0)}; MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)}; @@ -2789,17 +2845,16 @@ TEST_F(HttpStreamFactoryJobControllerTest, SpdySessionInterruptsPreconnect) { // Create and start a preconnect request, which should start watching the // SpdySessionPool. MockHttpStreamRequestDelegate preconnect_request_delegate; - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, &preconnect_request_delegate, session_.get(), &job_factory_, - request_info, true /* is_preconnect */, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - job_controller->Preconnect(1); - EXPECT_TRUE(job_controller->main_job()); - EXPECT_FALSE(job_controller->alternative_job()); + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, &preconnect_request_delegate, session_.get(), &job_factory_, + request_info, true /* is_preconnect */, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, std::move(job_controller)); + job_controller_ptr->Preconnect(1); + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_FALSE(job_controller_ptr->alternative_job()); // The non-preconnect request should create an H2 session, which the // preconnect then sees, and the preconnect request should complete and be @@ -2834,16 +2889,14 @@ TEST_F(HttpStreamFactoryJobControllerTest, SpdySessionInterruptsPreconnect) { // OnConnectComplete() is called in the end of the test. // [3] Normal non-preconnect request to other.example.org. This request must // succeed even while the preconnect request [2] is paused. -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, PreconnectJobDoesntBlockIpBasedPooling) { // Make sure that both "www.example.org" and "other.example.org" are pointing // to the same IP address. - std::vector<HostResolverEndpointResult> endpoints; - HostResolverEndpointResult endpoint_result; - endpoint_result.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)}; - endpoints.push_back(endpoint_result); - session_deps_.host_resolver->rules()->AddRule("www.example.org", endpoints); - session_deps_.host_resolver->rules()->AddRule("other.example.org", endpoints); + session_deps_.host_resolver->rules()->AddRule( + "www.example.org", IPAddress::IPv4Localhost().ToString()); + session_deps_.host_resolver->rules()->AddRule( + "other.example.org", IPAddress::IPv4Localhost().ToString()); // Make |host_resolver| asynchronous to simulate the issue of // crbug.com/1320608. session_deps_.host_resolver->set_synchronous_mode(false); @@ -2881,6 +2934,11 @@ TEST_F(HttpStreamFactoryJobControllerTest, &request_delegate_, /*websocket_handshake_stream_create_helper=*/nullptr, NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); + if (dns_https_alpn_enabled()) { + EXPECT_CALL(*job_factory_.main_job(), Resume()) + .Times(1) + .WillOnce([this]() { job_factory_.main_job()->DoResume(); }); + } base::RunLoop run_loop; EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) .WillOnce([&run_loop]() { run_loop.Quit(); }); @@ -2908,16 +2966,18 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Create and start a preconnect request [2]. MockHttpStreamRequestDelegate preconnect_request_delegate; - HttpStreamFactory::JobController* preconnect_job_controller = - new HttpStreamFactory::JobController( + auto preconnect_job_controller = + std::make_unique<HttpStreamFactory::JobController>( factory_, &preconnect_request_delegate, session_.get(), &job_factory_, other_request_info, /*is_preconnect=*/true, /*is_websocket=*/false, /*enable_ip_based_pooling=*/true, enable_alternative_services_, delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, preconnect_job_controller); - preconnect_job_controller->Preconnect(1); + auto* preconnect_job_controller_ptr = preconnect_job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(preconnect_job_controller)); + preconnect_job_controller_ptr->Preconnect(1); base::RunLoop().RunUntilIdle(); // The SpdySession is available for IP based pooling when the host resolution @@ -2939,17 +2999,17 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Create and start a second non-preconnect request [3]. { MockHttpStreamRequestDelegate request_delegate; - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, &request_delegate, session_.get(), &job_factory_, - other_request_info, /*is_preconnect=*/false, - /*is_websocket=*/false, /*enable_ip_based_pooling=*/true, - enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, &request_delegate, session_.get(), &job_factory_, + other_request_info, /*is_preconnect=*/false, + /*is_websocket=*/false, /*enable_ip_based_pooling=*/true, + enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); std::unique_ptr<HttpStreamRequest> second_stream_request = - job_controller->Start( + job_controller_ptr->Start( &request_delegate, /*websocket_handshake_stream_create_helper=*/nullptr, NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, @@ -2972,8 +3032,10 @@ TEST_F(HttpStreamFactoryJobControllerTest, } class JobControllerLimitMultipleH2Requests - : public HttpStreamFactoryJobControllerTest { + : public HttpStreamFactoryJobControllerTestBase { protected: + JobControllerLimitMultipleH2Requests() + : HttpStreamFactoryJobControllerTestBase(false) {} const int kNumRequests = 5; void SetUp() override { SkipCreatingJobController(); } }; @@ -3004,19 +3066,19 @@ TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequests) { for (int i = 0; i < kNumRequests; ++i) { request_delegates.emplace_back( std::make_unique<MockHttpStreamRequestDelegate>()); - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, request_delegates[i].get(), session_.get(), &job_factory_, - request_info, is_preconnect_, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - auto request = job_controller->Start( + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, request_delegates[i].get(), session_.get(), &job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); + auto request = job_controller_ptr->Start( request_delegates[i].get(), nullptr, net_log_with_source_, HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); - EXPECT_TRUE(job_controller->main_job()); - EXPECT_FALSE(job_controller->alternative_job()); + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_FALSE(job_controller_ptr->alternative_job()); requests.push_back(std::move(request)); } @@ -3091,20 +3153,20 @@ TEST_F(JobControllerLimitMultipleH2Requests, } request_delegates.emplace_back( std::make_unique<MockHttpStreamRequestDelegate>()); - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, request_delegates[i].get(), session_.get(), - &job_factory_, request_info, is_preconnect_, - false /* is_websocket */, enable_ip_based_pooling_, - enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - auto request = job_controller->Start( + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, request_delegates[i].get(), session_.get(), &job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), + SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); + auto request = job_controller_ptr->Start( request_delegates[i].get(), nullptr, net_log_with_source_, HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); - EXPECT_TRUE(job_controller->main_job()); - EXPECT_FALSE(job_controller->alternative_job()); + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_FALSE(job_controller_ptr->alternative_job()); requests.push_back(std::move(request)); } } @@ -3169,19 +3231,19 @@ TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequestsFirstRequestHang) { for (int i = 0; i < kNumRequests; ++i) { request_delegates.push_back( std::make_unique<MockHttpStreamRequestDelegate>()); - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, request_delegates[i].get(), session_.get(), &job_factory_, - request_info, is_preconnect_, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - auto request = job_controller->Start( + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, request_delegates[i].get(), session_.get(), &job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); + auto request = job_controller_ptr->Start( request_delegates[i].get(), nullptr, net_log_with_source_, HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); - EXPECT_TRUE(job_controller->main_job()); - EXPECT_FALSE(job_controller->alternative_job()); + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_FALSE(job_controller_ptr->alternative_job()); requests.push_back(std::move(request)); } @@ -3243,19 +3305,19 @@ TEST_F(JobControllerLimitMultipleH2Requests, for (int i = 0; i < kNumRequests; ++i) { request_delegates.emplace_back( std::make_unique<MockHttpStreamRequestDelegate>()); - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, request_delegates[i].get(), session_.get(), &job_factory_, - request_info, is_preconnect_, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - auto request = job_controller->Start( + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, request_delegates[i].get(), session_.get(), &job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); + auto request = job_controller_ptr->Start( request_delegates[i].get(), nullptr, net_log_with_source_, HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); - EXPECT_TRUE(job_controller->main_job()); - EXPECT_FALSE(job_controller->alternative_job()); + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_FALSE(job_controller_ptr->alternative_job()); requests.push_back(std::move(request)); } // Cancel the first one. @@ -3299,17 +3361,17 @@ TEST_F(JobControllerLimitMultipleH2Requests, MultiplePreconnects) { for (int i = 0; i < kNumRequests; ++i) { request_delegates.emplace_back( std::make_unique<MockHttpStreamRequestDelegate>()); - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, request_delegates[i].get(), session_.get(), &job_factory_, - request_info, is_preconnect_, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - job_controller->Preconnect(1); - EXPECT_TRUE(job_controller->main_job()); - EXPECT_FALSE(job_controller->alternative_job()); + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, request_delegates[i].get(), session_.get(), &job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); + job_controller_ptr->Preconnect(1); + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_FALSE(job_controller_ptr->alternative_job()); } base::RunLoop().RunUntilIdle(); EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); @@ -3348,19 +3410,19 @@ TEST_F(JobControllerLimitMultipleH2Requests, H1NegotiatedForFirstRequest) { for (int i = 0; i < 2; ++i) { request_delegates.emplace_back( std::make_unique<MockHttpStreamRequestDelegate>()); - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, request_delegates[i].get(), session_.get(), &job_factory_, - request_info, is_preconnect_, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - auto request = job_controller->Start( + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, request_delegates[i].get(), session_.get(), &job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); + auto request = job_controller_ptr->Start( request_delegates[i].get(), nullptr, net_log_with_source_, HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); - EXPECT_TRUE(job_controller->main_job()); - EXPECT_FALSE(job_controller->alternative_job()); + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_FALSE(job_controller_ptr->alternative_job()); requests.push_back(std::move(request)); } @@ -3411,20 +3473,19 @@ TEST_F(JobControllerLimitMultipleH2Requests, QuicJobNotThrottled) { // Use default job factory so that Resume() is not mocked out. HttpStreamFactory::JobFactory default_job_factory; - HttpStreamFactory::JobController* job_controller = - new HttpStreamFactory::JobController( - factory_, &request_delegate_, session_.get(), &default_job_factory, - request_info, is_preconnect_, false /* is_websocket */, - enable_ip_based_pooling_, enable_alternative_services_, - delay_main_job_with_available_spdy_session_, SSLConfig(), - SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller); - request_ = - job_controller->Start(&request_delegate_, nullptr, net_log_with_source_, - HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); - - EXPECT_TRUE(job_controller->main_job()); - EXPECT_TRUE(job_controller->alternative_job()); + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, &request_delegate_, session_.get(), &default_job_factory, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + auto* job_controller_ptr = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, std::move(job_controller)); + request_ = job_controller_ptr->Start( + &request_delegate_, nullptr, net_log_with_source_, + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); + + EXPECT_TRUE(job_controller_ptr->main_job()); + EXPECT_TRUE(job_controller_ptr->alternative_job()); EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)); base::RunLoop().RunUntilIdle(); auto entries = net_log_observer_.GetEntries(); @@ -3434,8 +3495,12 @@ TEST_F(JobControllerLimitMultipleH2Requests, QuicJobNotThrottled) { } class HttpStreamFactoryJobControllerMisdirectedRequestRetry - : public HttpStreamFactoryJobControllerTest, - public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; + : public HttpStreamFactoryJobControllerTestBase, + public ::testing::WithParamInterface<::testing::tuple<bool, bool>> { + public: + HttpStreamFactoryJobControllerMisdirectedRequestRetry() + : HttpStreamFactoryJobControllerTestBase(false) {} +}; INSTANTIATE_TEST_SUITE_P( All, @@ -3491,9 +3556,12 @@ TEST_P(HttpStreamFactoryJobControllerMisdirectedRequestRetry, } class HttpStreamFactoryJobControllerPreconnectTest - : public HttpStreamFactoryJobControllerTest, + : public HttpStreamFactoryJobControllerTestBase, public ::testing::WithParamInterface<bool> { protected: + HttpStreamFactoryJobControllerPreconnectTest() + : HttpStreamFactoryJobControllerTestBase(false) {} + void SetUp() override { if (!GetParam()) { scoped_feature_list_.InitFromCommandLine(std::string(), @@ -3509,7 +3577,7 @@ class HttpStreamFactoryJobControllerPreconnectTest factory_ = session_->http_stream_factory(); request_info_.method = "GET"; request_info_.url = GURL("https://www.example.com"); - job_controller_ = new HttpStreamFactory::JobController( + auto job_controller = std::make_unique<HttpStreamFactory::JobController>( factory_, &request_delegate_, session_.get(), &job_factory_, request_info_, /* is_preconnect = */ true, /* is_websocket = */ false, @@ -3517,7 +3585,9 @@ class HttpStreamFactoryJobControllerPreconnectTest /* enable_alternative_services = */ true, /* delay_main_job_with_available_spdy_session = */ true, SSLConfig(), SSLConfig()); - HttpStreamFactoryPeer::AddJobController(factory_, job_controller_); + job_controller_ = job_controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, + std::move(job_controller)); } protected: @@ -3564,7 +3634,7 @@ TEST_P(HttpStreamFactoryJobControllerPreconnectTest, LimitEarlyPreconnects) { // Test that GetAlternativeServiceInfoFor will include a list of advertised // versions, which contains a version that is supported. Returns an empty list // if advertised versions are missing in HttpServerProperties. -TEST_F(HttpStreamFactoryJobControllerTest, GetAlternativeServiceInfoFor) { +TEST_P(HttpStreamFactoryJobControllerTest, GetAlternativeServiceInfoFor) { HttpRequestInfo request_info; request_info.method = "GET"; request_info.url = GURL("https://www.google.com"); @@ -3658,7 +3728,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, GetAlternativeServiceInfoFor) { EXPECT_EQ(0u, alt_svc_info.advertised_versions().size()); } -void HttpStreamFactoryJobControllerTest::TestAltSvcVersionSelection( +void HttpStreamFactoryJobControllerTestBase::TestAltSvcVersionSelection( const std::string& alt_svc_header, const quic::ParsedQuicVersion& expected_version, const quic::ParsedQuicVersionVector& supported_versions) { @@ -3672,8 +3742,7 @@ void HttpStreamFactoryJobControllerTest::TestAltSvcVersionSelection( request_info.network_isolation_key = network_isolation_key; Initialize(request_info); url::SchemeHostPort origin(request_info.url); - scoped_refptr<HttpResponseHeaders> headers( - base::MakeRefCounted<HttpResponseHeaders>("")); + auto headers = base::MakeRefCounted<HttpResponseHeaders>(""); headers->AddHeader("alt-svc", alt_svc_header); session_->http_stream_factory()->ProcessAlternativeServices( session_.get(), network_isolation_key, headers.get(), origin); @@ -3691,7 +3760,7 @@ void HttpStreamFactoryJobControllerTest::TestAltSvcVersionSelection( << quic::ParsedQuicVersionVectorToString(advertised_versions); } -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltSvcVersionSelectionFindsFirstMatch) { TestAltSvcVersionSelection( "h3-Q050=\":443\"; ma=2592000," @@ -3702,7 +3771,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, quic::ParsedQuicVersion::Q050(), quic::AllSupportedVersions()); } -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltSvcVersionSelectionFindsFirstMatchInverse) { TestAltSvcVersionSelection( "h3-Q043=\":443\"; ma=2592000," @@ -3712,7 +3781,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, quic::ParsedQuicVersion::Q043(), quic::AllSupportedVersions()); } -TEST_F(HttpStreamFactoryJobControllerTest, +TEST_P(HttpStreamFactoryJobControllerTest, AltSvcVersionSelectionWithInverseOrderingNewFormat) { // Server prefers Q043 but client prefers Q046. TestAltSvcVersionSelection( @@ -3726,7 +3795,7 @@ TEST_F(HttpStreamFactoryJobControllerTest, // Tests that if HttpNetworkSession has a non-empty QUIC host allowlist, // then GetAlternativeServiceFor() will not return any QUIC alternative service // that's not on the allowlist. -TEST_F(HttpStreamFactoryJobControllerTest, QuicHostAllowlist) { +TEST_P(HttpStreamFactoryJobControllerTest, QuicHostAllowlist) { HttpRequestInfo request_info; request_info.method = "GET"; request_info.url = GURL("https://www.google.com"); @@ -3781,6 +3850,1261 @@ TEST_F(HttpStreamFactoryJobControllerTest, QuicHostAllowlist) { EXPECT_EQ(0u, alt_svc_info.advertised_versions().size()); } -} // namespace test +// Tests specific to UseDnsHttpsAlpn feature. +class HttpStreamFactoryJobControllerDnsHttpsAlpnTest + : public HttpStreamFactoryJobControllerTestBase { + protected: + HttpStreamFactoryJobControllerDnsHttpsAlpnTest() + : HttpStreamFactoryJobControllerTestBase(true) {} + + void SetUp() override { SkipCreatingJobController(); } + + void EnableOndemandHostResolver() { + session_deps_.host_resolver->set_synchronous_mode(false); + session_deps_.host_resolver->set_ondemand_mode(true); + } + + HttpRequestInfo CreateTestHttpRequestInfo() { + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("https://www.example.org"); + return request_info; + } + + void RegisterMockHttpsRecord() { + HostResolverEndpointResult endpoint_result1; + endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)}; + endpoint_result1.metadata.supported_protocol_alpns = { + quic::QuicVersionLabelToString(quic::CreateQuicVersionLabel(version_))}; + + HostResolverEndpointResult endpoint_result2; + endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)}; + + std::vector<HostResolverEndpointResult> endpoints; + endpoints.push_back(endpoint_result1); + endpoints.push_back(endpoint_result2); + session_deps_.host_resolver->rules()->AddRule( + "www.example.org", + MockHostResolverBase::RuleResolver::RuleResult( + std::move(endpoints), + /*aliases=*/std::set<std::string>{"www.example.org"})); + } + + void CreateJobController(const HttpRequestInfo& request_info) { + CreateJobControllerImpl(&job_controller_, &request_delegate_, request_info); + } + + std::unique_ptr<HttpStreamRequest> CreateJobControllerAndStart( + const HttpRequestInfo& request_info) { + return CreateJobControllerAndStartImpl(&job_controller_, &request_delegate_, + request_info); + } + + std::unique_ptr<HttpStreamRequest> CreateSecondJobControllerAndStart( + const HttpRequestInfo& request_info) { + return CreateJobControllerAndStartImpl(&job_controller2_, + &request_delegate2_, request_info); + } + + void PrepareForMainJob() { PrepareForMainJobImpl(&tcp_data_, &ssl_data_); } + void PrepareForSecondMainJob() { + PrepareForMainJobImpl(&tcp_data2_, &ssl_data2_); + } + + void PrepareForFirstQuicJob() { PrepareForQuicJobImpl(&quic_data_); } + void PrepareForSecondQuicJob() { PrepareForQuicJobImpl(&quic_data2_); } + + void PrepareForFirstQuicJobFailure() { + PrepareForQuicJobFailureImpl(&quic_data_); + } + void PrepareForSecondQuicJobFailure() { + PrepareForQuicJobFailureImpl(&quic_data2_); + } + + void MakeMainJobSucceed(bool expect_stream_ready) { + MakeMainJobSucceedImpl(request_delegate_, tcp_data_.get(), + expect_stream_ready); + } + + void MakeSecondMainJobSucceed(bool expect_stream_ready) { + MakeMainJobSucceedImpl(request_delegate2_, tcp_data2_.get(), + expect_stream_ready); + } + + void MakeQuicJobScceed(size_t index, bool expect_stream_ready) { + ASSERT_GT(crypto_client_stream_factory_.streams().size(), index); + MockCryptoClientStream* stream = + crypto_client_stream_factory_.streams()[index].get(); + ASSERT_TRUE(stream); + + if (expect_stream_ready) { + base::RunLoop run_loop; + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + stream->NotifySessionOneRttKeyAvailable(); + run_loop.Run(); + } else { + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)).Times(0); + stream->NotifySessionOneRttKeyAvailable(); + base::RunLoop().RunUntilIdle(); + } + } + + void CheckJobsStatus(bool main_job_exists, + bool alternative_job_exists, + bool dns_alpn_h3_job_exists, + const std::string& scoped_trace_message = "") { + CheckJobsStatusImpl(job_controller_.get(), main_job_exists, + alternative_job_exists, dns_alpn_h3_job_exists, + scoped_trace_message); + } + + void CheckSecondJobsStatus(bool main_job_exists, + bool alternative_job_exists, + bool dns_alpn_h3_job_exists, + const std::string& scoped_trace_message = "") { + CheckJobsStatusImpl(job_controller2_.get(), main_job_exists, + alternative_job_exists, dns_alpn_h3_job_exists, + scoped_trace_message); + } + + std::unique_ptr<QuicHttpStream> ConnectQuicHttpStream( + bool alt_destination, + bool require_dns_https_alpn) { + NetErrorDetails net_error_details; + QuicStreamRequest quic_request(session_->quic_stream_factory()); + url::SchemeHostPort scheme_host_port( + url::kHttpsScheme, + alt_destination ? "alt.example.org" : "www.example.org", 443); + absl::optional<int> quic_request_result; + + CHECK_EQ(ERR_IO_PENDING, + quic_request.Request( + scheme_host_port, + require_dns_https_alpn ? quic::ParsedQuicVersion::Unsupported() + : version_, + PRIVACY_MODE_DISABLED, DEFAULT_PRIORITY, SocketTag(), + NetworkIsolationKey(), SecureDnsPolicy::kAllow, + /*use_dns_aliases=*/true, require_dns_https_alpn, + /*cert_verify_flags=*/0, GURL("https://www.example.org/"), + net_log_with_source_, &net_error_details, + base::BindLambdaForTesting([&](int result) {}), + base::BindLambdaForTesting([&quic_request_result](int result) { + quic_request_result = result; + }))); + CHECK_EQ(1u, crypto_client_stream_factory_.streams().size()); + CHECK(crypto_client_stream_factory_.streams()[0]); + crypto_client_stream_factory_.streams()[0] + ->NotifySessionOneRttKeyAvailable(); + base::RunLoop().RunUntilIdle(); + CHECK(quic_request_result); + CHECK_EQ(OK, *quic_request_result); + + std::unique_ptr<QuicChromiumClientSession::Handle> session = + quic_request.ReleaseSessionHandle(); + std::set<std::string> dns_aliases = + session->GetDnsAliasesForSessionKey(quic_request.session_key()); + auto stream = std::make_unique<QuicHttpStream>(std::move(session), + std::move(dns_aliases)); + return stream; + } + + bool IsAlternativeServiceBroken(GURL& url) { + return session_->http_server_properties()->IsAlternativeServiceBroken( + AlternativeService(kProtoQUIC, HostPortPair::FromURL(url)), + NetworkIsolationKey()); + } + + raw_ptr<HttpStreamFactory::JobController> job_controller2_ = nullptr; + + MockHttpStreamRequestDelegate request_delegate2_; + + private: + QuicTestPacketMaker CreateQuicTestPacketMakerForClient() { + return QuicTestPacketMaker(version_, + quic::QuicUtils::CreateRandomConnectionId( + quic_context_.random_generator()), + quic_context_.clock(), "www.example.org", + quic::Perspective::IS_CLIENT, false); + } + + void CreateJobControllerImpl( + raw_ptr<HttpStreamFactory::JobController>* job_controller, + MockHttpStreamRequestDelegate* request_delegate, + const HttpRequestInfo& request_info) { + auto controller = std::make_unique<HttpStreamFactory::JobController>( + factory_, request_delegate, session_.get(), &default_job_factory_, + request_info, is_preconnect_, false /* is_websocket */, + enable_ip_based_pooling_, enable_alternative_services_, + delay_main_job_with_available_spdy_session_, SSLConfig(), SSLConfig()); + *job_controller = controller.get(); + HttpStreamFactoryPeer::AddJobController(factory_, std::move(controller)); + } + + std::unique_ptr<HttpStreamRequest> CreateJobControllerAndStartImpl( + raw_ptr<HttpStreamFactory::JobController>* job_controller, + MockHttpStreamRequestDelegate* request_delegate, + const HttpRequestInfo& request_info) { + CreateJobControllerImpl(job_controller, request_delegate, request_info); + return (*job_controller) + ->Start(request_delegate, nullptr, net_log_with_source_, + HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); + } + + void PrepareForMainJobImpl(std::unique_ptr<SequencedSocketData>* tcp_data, + std::unique_ptr<SSLSocketDataProvider>* ssl_data) { + *tcp_data = std::make_unique<SequencedSocketData>(); + (*tcp_data)->set_connect_data( + MockConnect(ASYNC, ERR_IO_PENDING)); /* pause */ + (*ssl_data) = std::make_unique<SSLSocketDataProvider>(ASYNC, OK); + session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data->get()); + } + + void PrepareForQuicJobImpl(std::unique_ptr<MockQuicData>* quic_data) { + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::COLD_START); + *quic_data = std::make_unique<MockQuicData>(version_); + (*quic_data)->AddRead(SYNCHRONOUS, ERR_IO_PENDING); + if (version_.UsesHttp3()) { + (*quic_data) + ->AddWrite(SYNCHRONOUS, CreateQuicTestPacketMakerForClient() + .MakeInitialSettingsPacket(1)); + } + } + + void PrepareForQuicJobFailureImpl(std::unique_ptr<MockQuicData>* quic_data) { + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::COLD_START); + *quic_data = std::make_unique<MockQuicData>(version_); + (*quic_data)->AddRead(ASYNC, ERR_IO_PENDING); // Pause + (*quic_data)->AddRead(ASYNC, ERR_FAILED); + } + + void MakeMainJobSucceedImpl(MockHttpStreamRequestDelegate& request_delegate, + SequencedSocketData* tcp_data, + bool expect_stream_ready) { + if (expect_stream_ready) { + base::RunLoop run_loop; + EXPECT_CALL(request_delegate, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + tcp_data->socket()->OnConnectComplete(MockConnect()); + run_loop.Run(); + } else { + EXPECT_CALL(request_delegate, OnStreamReadyImpl(_, _, _)).Times(0); + tcp_data->socket()->OnConnectComplete(MockConnect()); + base::RunLoop().RunUntilIdle(); + } + } + + static void CheckJobsStatusImpl( + HttpStreamFactory::JobController* job_controller, + bool main_job_exists, + bool alternative_job_exists, + bool dns_alpn_h3_job_exists, + const std::string& scoped_trace_message) { + SCOPED_TRACE(scoped_trace_message); + EXPECT_EQ(main_job_exists, !!job_controller->main_job()); + EXPECT_EQ(alternative_job_exists, !!job_controller->alternative_job()); + EXPECT_EQ(dns_alpn_h3_job_exists, !!job_controller->dns_alpn_h3_job()); + } + + // Use real Jobs so that Job::Resume() is not mocked out. When main job is + // resumed it will use mock socket data. + HttpStreamFactory::JobFactory default_job_factory_; + + // Used for man job connection. + std::unique_ptr<SSLSocketDataProvider> ssl_data_; + std::unique_ptr<SSLSocketDataProvider> ssl_data2_; +}; + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + NoHttpsRecordSyncHostResolve) { + PrepareForMainJob(); + Initialize(HttpRequestInfo()); + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + // The main job should be synchronously resumed, as host is resolved + // synchronously. + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + base::RunLoop().RunUntilIdle(); + + // |dns_alpn_h3_job| must fail when there is no valid supported alpn. And + // must be deleted. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/false, + "DNS ALPN job must be deleted."); + + base::HistogramTester histogram_tester; + MakeMainJobSucceed(/*expect_stream_ready=*/true); + // Net.AlternateProtocolUsage must not record anything, when HTTPS record with + // alpn is not available. + histogram_tester.ExpectTotalCount("Net.AlternateProtocolUsage", 0); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + NoHttpsRecordAsyncHostResolveResumeMainWithoutDelay) { + EnableOndemandHostResolver(); + PrepareForMainJob(); + Initialize(HttpRequestInfo()); + + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + // The main job should be resumed quickly after resolving the host. + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + + // Resolve the host resolve request from |dns_alpn_h3_job|. + session_deps_.host_resolver->ResolveAllPending(); + base::RunLoop().RunUntilIdle(); + + // |dns_alpn_h3_job| must fail when there is no valid supported alpn. And + // must be deleted. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/false, + "DNS ALPN job must be deleted."); + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + // The host resolve request from the main job must be resolved using the + // cached result. + EXPECT_TRUE(tcp_data_->socket()); + + base::HistogramTester histogram_tester; + MakeMainJobSucceed(/*expect_stream_ready=*/true); + // Net.AlternateProtocolUsage must not record anything, when HTTPS record with + // alpn is not available. + histogram_tester.ExpectTotalCount("Net.AlternateProtocolUsage", 0); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + NoHttpsRecordAsyncHostResolveResumeMainWithoutDelayQuicWorkedNetwork) { + EnableOndemandHostResolver(); + PrepareForMainJob(); + Initialize(HttpRequestInfo()); + + QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); + quic_stream_factory->set_is_quic_known_to_work_on_current_network(true); + + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + // Main job must be waiting. + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + + // Resolve the host resolve request from |dns_alpn_h3_job|. + session_deps_.host_resolver->ResolveAllPending(); + base::RunLoop().RunUntilIdle(); + + // |dns_alpn_h3_job| must fail when there is no valid supported alpn. And + // must be deleted. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/false, + "DNS ALPN job must be deleted."); + // The main job should be resumed quickly after resolving the host. + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + // The host resolve request from the main job must be resolved using the + // cached result. + EXPECT_TRUE(tcp_data_->socket()); + + base::HistogramTester histogram_tester; + MakeMainJobSucceed(/*expect_stream_ready=*/true); + // Net.AlternateProtocolUsage must not record anything, when HTTPS record with + // alpn is not available. + histogram_tester.ExpectTotalCount("Net.AlternateProtocolUsage", 0); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + MainJobNoDelayOnQuicNotWorkedNetworkSyncHostResolve) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + // |main_job| is not blocked, because the hostname is resolved synchronously + // and |is_quic_known_to_work_on_current_network| is false for this test. + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + base::HistogramTester histogram_tester; + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1); + + // The success of |dns_alpn_h3_job| deletes |main_job|. + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + MainJobNoDelayOnQuicNotWorkedNetworkAsyncHostResolve) { + EnableOndemandHostResolver(); + PrepareForMainJob(); + PrepareForFirstQuicJob(); + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + // |main_job| is blocked until host resolves. + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + + // Resolve the host resolve request from |dns_alpn_h3_job|. + session_deps_.host_resolver->ResolveAllPending(); + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + base::RunLoop().RunUntilIdle(); + + // |main_job| should have been resumed quickly because + // |is_quic_known_to_work_on_current_network| is false for this test. + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + // |dns_alpn_h3_job| must not fail when there is a valid supported alpn. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Both main job and DNS ALPN job must be alive"); + + base::HistogramTester histogram_tester; + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1); + + // The success of |dns_alpn_h3_job| deletes |main_job|. + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + MainJobDelayOnQuicWorkedNetwork) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); + quic_stream_factory->set_is_quic_known_to_work_on_current_network(true); + + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + base::RunLoop().RunUntilIdle(); + // |dns_alpn_h3_job| must not fail when there is a valid supported alpn. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Both main job and DNS ALPN job must be alive"); + + // The main job should be waiting until kDefaultDelayMilliSecsForWaitingJob + // amount of time has passed. + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + FastForwardBy(base::Milliseconds(kDefaultDelayMilliSecsForWaitingJob - 1)); + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + FastForwardBy(base::Milliseconds(1)); + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + base::HistogramTester histogram_tester; + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1); + + // The success of |dns_alpn_h3_job| deletes |main_job|. + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + MainJobSucceedsDnsAlpnH3JobSucceeds) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + base::RunLoop().RunUntilIdle(); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + // |main_job| is not blocked, because the hostname is resolved synchronously + // and |is_quic_known_to_work_on_current_network| is false for this test. + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + base::HistogramTester histogram_tester; + // Make |main_job| succeed. + MakeMainJobSucceed(/*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE, + 1); + + // The success of |main_job| doesn't delete |dns_alpn_h3_job|. + EXPECT_TRUE(job_controller_->dns_alpn_h3_job()); + + // Make |dns_alpn_h3_job| complete. + MakeQuicJobScceed(0, /*expect_stream_ready=*/false); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + ActiveSessionAvailableForMainJob) { + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + PrepareForFirstQuicJob(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + // Set |is_quic_known_to_work_on_current_network| flag so that + // the delaying logic of main job would work when the main job is blocked. + // Note: In this test, we don't need this because the main job is not blocked. + // But we set here because we want to check that the main job is not blocked. + QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); + quic_stream_factory->set_is_quic_known_to_work_on_current_network(true); + + // Put a SpdySession in the pool. + SpdySessionKey key(HostPortPair::FromURL(request_info.url), + ProxyServer::Direct(), PRIVACY_MODE_DISABLED, + SpdySessionKey::IsProxySession::kFalse, SocketTag(), + NetworkIsolationKey(), SecureDnsPolicy::kAllow); + std::ignore = CreateFakeSpdySession(session_->spdy_session_pool(), key); + + request_ = CreateJobControllerAndStart(request_info); + // |dns_alpn_h3_job| must be created even when an active session is + // available for |main_job|. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + // Main job must not be waiting because an active session is available. + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + base::HistogramTester histogram_tester; + // Run the message loop to make |main_job| succeed and status will be + // reported to Request. + { + base::RunLoop run_loop; + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + run_loop.Run(); + } + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE, + 1); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "DNS ALPN job must be alive"); + + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/false); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/false, + "DNS ALPN job must be deleted"); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, MainJobHasActiveSocket) { + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + PrepareForMainJob(); + PrepareForSecondMainJob(); + + PrepareForFirstQuicJobFailure(); + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + // Set |is_quic_known_to_work_on_current_network| flag so that + // the delaying logic of main job would work when the main job is blocked. + QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); + quic_stream_factory->set_is_quic_known_to_work_on_current_network(true); + + request_ = CreateJobControllerAndStart(request_info); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + FastForwardBy(base::Milliseconds(kDefaultDelayMilliSecsForWaitingJob - 1)); + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + FastForwardBy(base::Milliseconds(1)); + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + auto request2 = CreateSecondJobControllerAndStart(request_info); + CheckSecondJobsStatus( + /*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created for the second request."); + + // When an active socket is available for the main job, the main job should + // not be blocked. + EXPECT_FALSE(job_controller2_->main_job()->is_waiting()); + + quic_data_->Resume(); + base::RunLoop().RunUntilIdle(); + + MakeMainJobSucceed(/*expect_stream_ready=*/true); + MakeSecondMainJobSucceed(/*expect_stream_ready=*/true); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + MainJobHasActiveSocketAltSvcRegistered) { + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + PrepareForMainJob(); + PrepareForSecondMainJob(); + + PrepareForFirstQuicJobFailure(); + PrepareForSecondQuicJobFailure(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + // Set |is_quic_known_to_work_on_current_network| flag so that + // the delaying logic of main job would work when the main job is blocked. + QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); + quic_stream_factory->set_is_quic_known_to_work_on_current_network(true); + + url::SchemeHostPort server(request_info.url); + AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443); + SetAlternativeService(request_info, alternative_service); + + request_ = CreateJobControllerAndStart(request_info); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/true, + "All types of jobs are created"); + + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + FastForwardBy(base::Milliseconds(kDefaultDelayMilliSecsForWaitingJob - 1)); + EXPECT_TRUE(job_controller_->main_job()->is_waiting()); + FastForwardBy(base::Milliseconds(1)); + EXPECT_FALSE(job_controller_->main_job()->is_waiting()); + + auto request2 = CreateSecondJobControllerAndStart(request_info); + CheckSecondJobsStatus( + /*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/true, + "All types of jobs must be created for the second request."); + + // The main job should be waiting until kDefaultDelayMilliSecsForWaitingJob + // amount of time has passed, when an alternative service was registered, + // even when an active socket is available for the main job. + // This is intended to switch to QUIC from TCP for the first connection + // when the server supports Alt-Svc but doesn't support HTTP DNS records with + // alpn. + // Note: When QuicParams.delay_main_job_with_available_spdy_session is false, + // main job is not blocked. + EXPECT_TRUE(job_controller2_->main_job()->is_waiting()); + FastForwardBy(base::Milliseconds(kDefaultDelayMilliSecsForWaitingJob - 1)); + EXPECT_TRUE(job_controller2_->main_job()->is_waiting()); + FastForwardBy(base::Milliseconds(1)); + EXPECT_FALSE(job_controller2_->main_job()->is_waiting()); + + quic_data_->Resume(); + quic_data2_->Resume(); + base::RunLoop().RunUntilIdle(); + + MakeMainJobSucceed(/*expect_stream_ready=*/true); + MakeSecondMainJobSucceed(/*expect_stream_ready=*/true); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + ActiveSessionAvailableForAltSvcJob) { + PrepareForMainJob(); + RegisterMockHttpsRecord(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + PrepareForFirstQuicJob(); + + Initialize(HttpRequestInfo()); + + auto stream = ConnectQuicHttpStream(/*alt_destination=*/true, + /*require_dns_https_alpn=*/false); + + url::SchemeHostPort server(request_info.url); + AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443); + SetAlternativeService(request_info, alternative_service); + + request_ = CreateJobControllerAndStart(request_info); + + // |dns_alpn_h3_job| must not be created when an active session is + // available for |alternative_job|. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/false, + "Main job and alternative job must be created."); + + base::HistogramTester histogram_tester; + // Run the message loop to make |alternative_job| succeed and status will be + // reported to Request. + { + base::RunLoop run_loop; + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + run_loop.Run(); + } + histogram_tester.ExpectUniqueSample("Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_NO_RACE, 1); + + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/false, + "Main job must be deleted."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + ActiveSessionAvailableForDnsAlpnH3Job) { + PrepareForFirstQuicJob(); + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + auto stream = ConnectQuicHttpStream(/*alt_destination=*/false, + /*require_dns_https_alpn=*/true); + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and alternative job must not be available."); + + base::HistogramTester histogram_tester; + // Run the message loop to make |dns_alpn_h3_job| succeed and status will be + // reported to Request. + { + base::RunLoop run_loop; + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + run_loop.Run(); + } + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_WITOUT_RACE, 1); + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "DNS alpn H3 job must exist."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + ActiveSessionAvailableForMainJobAndDnsAlpnH3Job) { + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + PrepareForFirstQuicJob(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + // Put a SpdySession in the pool. + SpdySessionKey key(HostPortPair::FromURL(request_info.url), + ProxyServer::Direct(), PRIVACY_MODE_DISABLED, + SpdySessionKey::IsProxySession::kFalse, SocketTag(), + NetworkIsolationKey(), SecureDnsPolicy::kAllow); + std::ignore = CreateFakeSpdySession(session_->spdy_session_pool(), key); + + auto stream = ConnectQuicHttpStream(/*alt_destination=*/false, + /*require_dns_https_alpn=*/true); + request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo()); + + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job must not be available."); + + base::HistogramTester histogram_tester; + // Run the message loop to make |dns_alpn_h3_job| succeed and status will be + // reported to Request. + { + base::RunLoop run_loop; + EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, _)) + .Times(1) + .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); })); + run_loop.Run(); + } + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_WITOUT_RACE, 1); + + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "DNS alpn H3 job must exist."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + DonotStartDnsAlpnH3JobWhenSameHostDefaultPortAltJobCreated) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + url::SchemeHostPort server(request_info.url); + AlternativeService alternative_service(kProtoQUIC, "www.example.org", 443); + SetAlternativeService(request_info, alternative_service); + + request_ = CreateJobControllerAndStart(request_info); + // |dns_alpn_h3_job| must be deleted when a same origin alt service + // was registered. + CheckJobsStatus( + true, true, false, + "All types of jobs are created, but DNS alpn job must be deleted"); + + base::HistogramTester histogram_tester; + // Make |main_job| succeed. + MakeMainJobSucceed(/*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE, + 1); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/false, + "Alternate job must not be deleted"); + + // Make |alternative_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/false); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + AllJobsCreatedMainJobSucceedAltJobSucceedDnsJobSucceed) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + PrepareForSecondQuicJob(); + + // Use cold start and complete `alternative_job` and `dns_alpn_h3_job` + // manually. + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::COLD_START); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + url::SchemeHostPort server(request_info.url); + AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443); + SetAlternativeService(request_info, alternative_service); + + request_ = CreateJobControllerAndStart(request_info); + // |dns_alpn_h3_job| must be created when a different origin alt service + // was registered. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/true, + "All types of jobs are created"); + + base::HistogramTester histogram_tester; + MakeMainJobSucceed(/*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE, + 1); + + // The success of |main_job| doesn't delete |alternative_job| and + // |dns_alpn_h3_job|. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted."); + + // Make |alternative_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/false); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Alternate job must be deleted."); + + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(1, /*expect_stream_ready=*/false); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/false, + "DNS alpn job must be deleted."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + AllJobsCreatedAltJobSucceedDnsJobSucceedMainJobSucceed) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + PrepareForSecondQuicJob(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + url::SchemeHostPort server(request_info.url); + AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443); + SetAlternativeService(request_info, alternative_service); + + request_ = CreateJobControllerAndStart(request_info); + // |dns_alpn_h3_job| must be created when a different origin alt service + // was registered. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/true, + "All types of jobs are created"); + + base::HistogramTester histogram_tester; + // Make |alternative_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample("Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_WON_RACE, 1); + + // The success of |alternative_job| doesn't delete |main_job| and + // |dns_alpn_h3_job|. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted."); + + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(1, /*expect_stream_ready=*/false); + + // The success of |dns_alpn_h3_job| doesn't delete |main_job| and + // |alternative_job|. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/false, + "DNS alpn job must be deleted."); + + // Make |main_job| succeed. + MakeMainJobSucceed(/*expect_stream_ready=*/false); + + // |main_job| should be cleared. + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/false, + "Alternate job must be deleted."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + AllJobsCreatedDnsJobSucceedAltJobSucceedMainJobSucceed) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + PrepareForSecondQuicJob(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + + url::SchemeHostPort server(request_info.url); + AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443); + SetAlternativeService(request_info, alternative_service); + + request_ = CreateJobControllerAndStart(request_info); + // |dns_alpn_h3_job| must be created when a different origin alt service + // was registered. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/true, + "All types of jobs are created"); + + base::HistogramTester histogram_tester; + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(1, /*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1); + + // The success of |dns_alpn_h3_job| doesn't delete |main_job| and + // |alternative_job|. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true, + /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted."); + + // Make |alternative_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/false); + + // The success of |alternative_job| doesn't delete |main_job| and + // |dns_alpn_h3_job|. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Alternate job must be deleted."); + + // Make |main_job| succeed. + MakeMainJobSucceed(/*expect_stream_ready=*/false); + + // |main_job| should be cleared. + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted."); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + DnsJobFailOnDefaultNetworkDnsJobFailMainJobSucceed) { + PrepareForMainJob(); + PrepareForFirstQuicJobFailure(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + request_ = CreateJobControllerAndStart(request_info); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + JobControllerPeer::SetDnsAlpnH3JobFailedOnDefaultNetwork(job_controller_); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted."); + + base::HistogramTester histogram_tester; + // Make |dns_alpn_h3_job| fail. + quic_data_->Resume(); + base::RunLoop().RunUntilIdle(); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/false, "DNS alpn job be deleted."); + + // Make |main_job| succeed. + MakeMainJobSucceed(/*expect_stream_ready=*/true); + // Net.AlternateProtocolUsage must not record anything, when DNS alpn job + // failed. + histogram_tester.ExpectTotalCount("Net.AlternateProtocolUsage", 0); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/false, + "DNS alpn job must be deleted."); + + request_.reset(); + EXPECT_TRUE(IsAlternativeServiceBroken(request_info.url)); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); + histogram_tester.ExpectUniqueSample("Net.AlternateServiceForDnsAlpnH3Failed", + -ERR_QUIC_PROTOCOL_ERROR, 1); + + // Verify the brokenness is not cleared when the default network changes. + session_->http_server_properties()->OnDefaultNetworkChanged(); + EXPECT_TRUE(IsAlternativeServiceBroken(request_info.url)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + DnsJobFailOnDefaultNetworkMainJobSucceedDnsJobSucceed) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + base::HistogramTester histogram_tester; + request_ = CreateJobControllerAndStart(request_info); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + JobControllerPeer::SetDnsAlpnH3JobFailedOnDefaultNetwork(job_controller_); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted."); + + // Make |main_job| succeed. + MakeMainJobSucceed(/*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE, + 1); + + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "DNS alpn job must not be deleted."); + + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/false); + + request_.reset(); + histogram_tester.ExpectTotalCount("Net.AlternateServiceForDnsAlpnH3Failed", + 0); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); + EXPECT_TRUE(IsAlternativeServiceBroken(request_info.url)); + + // Verify the brokenness is cleared when the default network changes. + session_->http_server_properties()->OnDefaultNetworkChanged(); + EXPECT_FALSE(IsAlternativeServiceBroken(request_info.url)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + DnsJobSucceedMainJobCanceled) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + request_ = CreateJobControllerAndStart(request_info); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + base::HistogramTester histogram_tester; + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1); + + // Main job is canceled. + CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted"); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, + DnsJobFailOnDefaultNetworkDnsJobSucceedMainJobSucceed) { + PrepareForMainJob(); + PrepareForFirstQuicJob(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + request_ = CreateJobControllerAndStart(request_info); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job and DNS ALPN job must be created."); + + JobControllerPeer::SetDnsAlpnH3JobFailedOnDefaultNetwork(job_controller_); + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted."); + + base::HistogramTester histogram_tester; + // Make |dns_alpn_h3_job| succeed. + MakeQuicJobScceed(0, /*expect_stream_ready=*/true); + histogram_tester.ExpectUniqueSample( + "Net.AlternateProtocolUsage", + ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1); + + // Main job is not canceled, because |dns_alpn_h3_job| has failed on the + // default network. + CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false, + /*dns_alpn_h3_job_exists=*/true, + "Main job must not be deleted."); + + // Make |main_job| succeed. + MakeMainJobSucceed(/*expect_stream_ready=*/false); + + request_.reset(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, PreconnectDnsAlpnH3) { + SetPreconnect(); + PrepareForFirstQuicJob(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + RegisterMockHttpsRecord(); + + Initialize(HttpRequestInfo()); + CreateJobController(request_info); + job_controller_->Preconnect(/*num_streams=*/5); + // Only one job is started. + EXPECT_TRUE(job_controller_->main_job()); + EXPECT_FALSE(job_controller_->alternative_job()); + EXPECT_EQ(HttpStreamFactory::PRECONNECT_DNS_ALPN_H3, + job_controller_->main_job()->job_type()); + + MakeQuicJobScceed(0, /*expect_stream_ready=*/false); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} + +TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, PreconnectNoDnsAlpnH3) { + EnableOndemandHostResolver(); + PrepareForMainJob(); + SetPreconnect(); + + HttpRequestInfo request_info = CreateTestHttpRequestInfo(); + + Initialize(HttpRequestInfo()); + CreateJobController(request_info); + job_controller_->Preconnect(/*num_streams=*/1); + // Only one job is started. + EXPECT_TRUE(job_controller_->main_job()); + EXPECT_FALSE(job_controller_->alternative_job()); + EXPECT_EQ(HttpStreamFactory::PRECONNECT_DNS_ALPN_H3, + job_controller_->main_job()->job_type()); + + // Resolve the host resolve request from |dns_alpn_h3_job|. + session_deps_.host_resolver->ResolveAllPending(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(HttpStreamFactory::PRECONNECT, + job_controller_->main_job()->job_type()); + + base::RunLoop().RunUntilIdle(); + + // Make |main_job| succeed. + MakeMainJobSucceed(/*expect_stream_ready=*/false); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_)); +} -} // namespace net +} // namespace net::test diff --git a/chromium/net/http/http_stream_factory_test_util.cc b/chromium/net/http/http_stream_factory_test_util.cc index 5b7a376b708..e3932b382a9 100644 --- a/chromium/net/http/http_stream_factory_test_util.cc +++ b/chromium/net/http/http_stream_factory_test_util.cc @@ -52,11 +52,15 @@ MockHttpStreamFactoryJob::MockHttpStreamFactoryJob( MockHttpStreamFactoryJob::~MockHttpStreamFactoryJob() = default; +void MockHttpStreamFactoryJob::DoResume() { + HttpStreamFactory::Job::Resume(); +} + TestJobFactory::TestJobFactory() = default; TestJobFactory::~TestJobFactory() = default; -std::unique_ptr<HttpStreamFactory::Job> TestJobFactory::CreateMainJob( +std::unique_ptr<HttpStreamFactory::Job> TestJobFactory::CreateJob( HttpStreamFactory::Job::Delegate* delegate, HttpStreamFactory::JobType job_type, HttpNetworkSession* session, @@ -69,48 +73,35 @@ std::unique_ptr<HttpStreamFactory::Job> TestJobFactory::CreateMainJob( GURL origin_url, bool is_websocket, bool enable_ip_based_pooling, - NetLog* net_log) { - if (override_main_job_url_) - origin_url = main_job_alternative_url_; - - auto main_job = std::make_unique<MockHttpStreamFactoryJob>( - delegate, job_type, session, request_info, priority, proxy_info, - SSLConfig(), SSLConfig(), std::move(destination), origin_url, - kProtoUnknown, quic::ParsedQuicVersion::Unsupported(), is_websocket, - enable_ip_based_pooling, net_log); - - // Keep raw pointer to Job but pass ownership. - main_job_ = main_job.get(); - - return std::move(main_job); -} - -std::unique_ptr<HttpStreamFactory::Job> TestJobFactory::CreateAltSvcJob( - HttpStreamFactory::Job::Delegate* delegate, - HttpStreamFactory::JobType job_type, - HttpNetworkSession* session, - const HttpRequestInfo& request_info, - RequestPriority priority, - const ProxyInfo& proxy_info, - const SSLConfig& server_ssl_config, - const SSLConfig& proxy_ssl_config, - url::SchemeHostPort destination, - GURL origin_url, - NextProto alternative_protocol, - quic::ParsedQuicVersion quic_version, - bool is_websocket, - bool enable_ip_based_pooling, - NetLog* net_log) { - auto alternative_job = std::make_unique<MockHttpStreamFactoryJob>( + NetLog* net_log, + NextProto alternative_protocol = kProtoUnknown, + quic::ParsedQuicVersion quic_version = + quic::ParsedQuicVersion::Unsupported()) { + auto job = std::make_unique<MockHttpStreamFactoryJob>( delegate, job_type, session, request_info, priority, proxy_info, SSLConfig(), SSLConfig(), std::move(destination), origin_url, alternative_protocol, quic_version, is_websocket, enable_ip_based_pooling, net_log); // Keep raw pointer to Job but pass ownership. - alternative_job_ = alternative_job.get(); - - return std::move(alternative_job); + switch (job_type) { + case HttpStreamFactory::MAIN: + main_job_ = job.get(); + break; + case HttpStreamFactory::ALTERNATIVE: + alternative_job_ = job.get(); + break; + case HttpStreamFactory::DNS_ALPN_H3: + dns_alpn_h3_job_ = job.get(); + break; + case HttpStreamFactory::PRECONNECT: + main_job_ = job.get(); + break; + case HttpStreamFactory::PRECONNECT_DNS_ALPN_H3: + main_job_ = job.get(); + break; + } + return job; } } // namespace net diff --git a/chromium/net/http/http_stream_factory_test_util.h b/chromium/net/http/http_stream_factory_test_util.h index ac89b431dba..72f75007348 100644 --- a/chromium/net/http/http_stream_factory_test_util.h +++ b/chromium/net/http/http_stream_factory_test_util.h @@ -28,8 +28,8 @@ class HttpStreamFactoryPeer { public: static void AddJobController( HttpStreamFactory* factory, - HttpStreamFactory::JobController* job_controller) { - factory->job_controller_set_.insert(base::WrapUnique(job_controller)); + std::unique_ptr<HttpStreamFactory::JobController> job_controller) { + factory->job_controller_set_.insert(std::move(job_controller)); } static bool IsJobControllerDeleted(HttpStreamFactory* factory) { @@ -125,6 +125,8 @@ class MockHttpStreamFactoryJob : public HttpStreamFactory::Job { MOCK_METHOD0(Resume, void()); MOCK_METHOD0(Orphan, void()); + + void DoResume(); }; // JobFactory for creating MockHttpStreamFactoryJobs. @@ -133,7 +135,7 @@ class TestJobFactory : public HttpStreamFactory::JobFactory { TestJobFactory(); ~TestJobFactory() override; - std::unique_ptr<HttpStreamFactory::Job> CreateMainJob( + std::unique_ptr<HttpStreamFactory::Job> CreateJob( HttpStreamFactory::Job::Delegate* delegate, HttpStreamFactory::JobType job_type, HttpNetworkSession* session, @@ -146,38 +148,18 @@ class TestJobFactory : public HttpStreamFactory::JobFactory { GURL origin_url, bool is_websocket, bool enable_ip_based_pooling, - NetLog* net_log) override; - - std::unique_ptr<HttpStreamFactory::Job> CreateAltSvcJob( - HttpStreamFactory::Job::Delegate* delegate, - HttpStreamFactory::JobType job_type, - HttpNetworkSession* session, - const HttpRequestInfo& request_info, - RequestPriority priority, - const ProxyInfo& proxy_info, - const SSLConfig& server_ssl_config, - const SSLConfig& proxy_ssl_config, - url::SchemeHostPort destination, - GURL origin_url, + NetLog* net_log, NextProto alternative_protocol, - quic::ParsedQuicVersion quic_version, - bool is_websocket, - bool enable_ip_based_pooling, - NetLog* net_log) override; + quic::ParsedQuicVersion quic_version) override; MockHttpStreamFactoryJob* main_job() const { return main_job_; } MockHttpStreamFactoryJob* alternative_job() const { return alternative_job_; } - - void UseDifferentURLForMainJob(GURL url) { - override_main_job_url_ = true; - main_job_alternative_url_ = url; - } + MockHttpStreamFactoryJob* dns_alpn_h3_job() const { return dns_alpn_h3_job_; } private: raw_ptr<MockHttpStreamFactoryJob> main_job_ = nullptr; raw_ptr<MockHttpStreamFactoryJob> alternative_job_ = nullptr; - bool override_main_job_url_ = false; - GURL main_job_alternative_url_; + raw_ptr<MockHttpStreamFactoryJob> dns_alpn_h3_job_ = nullptr; }; } // namespace net diff --git a/chromium/net/http/http_stream_factory_unittest.cc b/chromium/net/http/http_stream_factory_unittest.cc index e11997a6ae8..27b43aa80a5 100644 --- a/chromium/net/http/http_stream_factory_unittest.cc +++ b/chromium/net/http/http_stream_factory_unittest.cc @@ -170,7 +170,7 @@ class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase { void Drain(HttpNetworkSession* session) override {} void PopulateNetErrorDetails(NetErrorDetails* details) override { return; } void SetPriority(RequestPriority priority) override {} - HttpStream* RenewStreamForAuth() override { return nullptr; } + std::unique_ptr<HttpStream> RenewStreamForAuth() override { return nullptr; } const std::set<std::string>& GetDnsAliases() const override { static const base::NoDestructor<std::set<std::string>> nullset_result; return *nullset_result; @@ -377,9 +377,10 @@ void PreconnectHelperForURL(int num_streams, SecureDnsPolicy secure_dns_policy, HttpNetworkSession* session) { HttpNetworkSessionPeer peer(session); - MockHttpStreamFactoryForPreconnect* mock_factory = - new MockHttpStreamFactoryForPreconnect(session); - peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(mock_factory)); + auto mock_factory = + std::make_unique<MockHttpStreamFactoryForPreconnect>(session); + auto* mock_factory_ptr = mock_factory.get(); + peer.SetHttpStreamFactory(std::move(mock_factory)); HttpRequestInfo request; request.method = "GET"; @@ -391,7 +392,7 @@ void PreconnectHelperForURL(int num_streams, MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); session->http_stream_factory()->PreconnectStreams(num_streams, request); - mock_factory->WaitForPreconnects(); + mock_factory_ptr->WaitForPreconnects(); } void PreconnectHelper(const TestCase& test, HttpNetworkSession* session) { @@ -504,7 +505,7 @@ class CapturePreconnectsTransportSocketPool : public TransportClientSocketPool { using HttpStreamFactoryTest = TestWithTaskEnvironment; TEST_F(HttpStreamFactoryTest, PreconnectDirect) { - for (size_t i = 0; i < std::size(kTests); ++i) { + for (const auto& test : kTests) { SpdySessionDependencies session_deps( ConfiguredProxyResolutionService::CreateDirect()); std::unique_ptr<HttpNetworkSession> session( @@ -522,16 +523,16 @@ TEST_F(HttpStreamFactoryTest, PreconnectDirect) { mock_pool_manager->SetSocketPool(ProxyServer::Direct(), std::move(owned_transport_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); - PreconnectHelper(kTests[i], session.get()); - EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); - EXPECT_EQ(GetGroupId(kTests[i]), transport_conn_pool->last_group_id()); + PreconnectHelper(test, session.get()); + EXPECT_EQ(test.num_streams, transport_conn_pool->last_num_streams()); + EXPECT_EQ(GetGroupId(test), transport_conn_pool->last_group_id()); } } TEST_F(HttpStreamFactoryTest, PreconnectHttpProxy) { - for (size_t i = 0; i < std::size(kTests); ++i) { + for (const auto& test : kTests) { SpdySessionDependencies session_deps( - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "http_proxy", TRAFFIC_ANNOTATION_FOR_TESTS)); std::unique_ptr<HttpNetworkSession> session( SpdySessionDependencies::SpdyCreateSession(&session_deps)); @@ -540,22 +541,24 @@ TEST_F(HttpStreamFactoryTest, PreconnectHttpProxy) { HostPortPair("http_proxy", 80)); CommonConnectJobParams common_connect_job_params = session->CreateCommonConnectJobParams(); - CapturePreconnectsTransportSocketPool* http_proxy_pool = - new CapturePreconnectsTransportSocketPool(&common_connect_job_params); + + auto http_proxy_pool = + std::make_unique<CapturePreconnectsTransportSocketPool>( + &common_connect_job_params); + auto* http_proxy_pool_ptr = http_proxy_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPool(proxy_server, - base::WrapUnique(http_proxy_pool)); + mock_pool_manager->SetSocketPool(proxy_server, std::move(http_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); - PreconnectHelper(kTests[i], session.get()); - EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams()); - EXPECT_EQ(GetGroupId(kTests[i]), http_proxy_pool->last_group_id()); + PreconnectHelper(test, session.get()); + EXPECT_EQ(test.num_streams, http_proxy_pool_ptr->last_num_streams()); + EXPECT_EQ(GetGroupId(test), http_proxy_pool_ptr->last_group_id()); } } TEST_F(HttpStreamFactoryTest, PreconnectSocksProxy) { - for (size_t i = 0; i < std::size(kTests); ++i) { + for (const auto& test : kTests) { SpdySessionDependencies session_deps( - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "socks4://socks_proxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS)); std::unique_ptr<HttpNetworkSession> session( SpdySessionDependencies::SpdyCreateSession(&session_deps)); @@ -564,20 +567,21 @@ TEST_F(HttpStreamFactoryTest, PreconnectSocksProxy) { HostPortPair("socks_proxy", 1080)); CommonConnectJobParams common_connect_job_params = session->CreateCommonConnectJobParams(); - CapturePreconnectsTransportSocketPool* socks_proxy_pool = - new CapturePreconnectsTransportSocketPool(&common_connect_job_params); + auto socks_proxy_pool = + std::make_unique<CapturePreconnectsTransportSocketPool>( + &common_connect_job_params); + auto* socks_proxy_pool_ptr = socks_proxy_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPool(proxy_server, - base::WrapUnique(socks_proxy_pool)); + mock_pool_manager->SetSocketPool(proxy_server, std::move(socks_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); - PreconnectHelper(kTests[i], session.get()); - EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams()); - EXPECT_EQ(GetGroupId(kTests[i]), socks_proxy_pool->last_group_id()); + PreconnectHelper(test, session.get()); + EXPECT_EQ(test.num_streams, socks_proxy_pool_ptr->last_num_streams()); + EXPECT_EQ(GetGroupId(test), socks_proxy_pool_ptr->last_group_id()); } } TEST_F(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { - for (size_t i = 0; i < std::size(kTests); ++i) { + for (const auto& test : kTests) { SpdySessionDependencies session_deps( ConfiguredProxyResolutionService::CreateDirect()); std::unique_ptr<HttpNetworkSession> session( @@ -604,13 +608,13 @@ TEST_F(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { mock_pool_manager->SetSocketPool(ProxyServer::Direct(), std::move(owned_transport_conn_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); - PreconnectHelper(kTests[i], session.get()); + PreconnectHelper(test, session.get()); // We shouldn't be preconnecting if we have an existing session, which is // the case for https://www.google.com. - if (kTests[i].ssl) + if (test.ssl) EXPECT_EQ(-1, transport_conn_pool->last_num_streams()); else - EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); + EXPECT_EQ(test.num_streams, transport_conn_pool->last_num_streams()); } } @@ -724,7 +728,7 @@ TEST_F(HttpStreamFactoryTest, PreconnectDisableSecureDns) { TEST_F(HttpStreamFactoryTest, JobNotifiesProxy) { const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT"; SpdySessionDependencies session_deps( - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( kProxyString, TRAFFIC_ANNOTATION_FOR_TESTS)); // First connection attempt fails @@ -776,7 +780,7 @@ TEST_F(HttpStreamFactoryTest, JobNotifiesProxy) { TEST_F(HttpStreamFactoryTest, NoProxyFallbackOnTunnelFail) { const char* kProxyString = "PROXY bad:99; DIRECT"; SpdySessionDependencies session_deps( - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( kProxyString, TRAFFIC_ANNOTATION_FOR_TESTS)); // A 404 in response to a CONNECT will trigger @@ -844,7 +848,7 @@ const int quic_proxy_test_mock_errors[] = { TEST_F(HttpStreamFactoryTest, QuicProxyMarkedAsBad) { for (int quic_proxy_test_mock_error : quic_proxy_test_mock_errors) { std::unique_ptr<ProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "QUIC bad:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS); HttpNetworkSessionParams session_params; @@ -952,18 +956,18 @@ class MockQuicData { ~MockQuicData() = default; void AddRead(std::unique_ptr<quic::QuicEncryptedPacket> packet) { - reads_.push_back( - MockRead(ASYNC, packet->data(), packet->length(), packet_number_++)); + reads_.emplace_back(ASYNC, packet->data(), packet->length(), + packet_number_++); packets_.push_back(std::move(packet)); } void AddRead(IoMode mode, int rv) { - reads_.push_back(MockRead(mode, rv, packet_number_++)); + reads_.emplace_back(mode, rv, packet_number_++); } void AddWrite(std::unique_ptr<quic::QuicEncryptedPacket> packet) { - writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(), - packet_number_++)); + writes_.emplace_back(SYNCHRONOUS, packet->data(), packet->length(), + packet_number_++); packets_.push_back(std::move(packet)); } @@ -989,7 +993,7 @@ TEST_F(HttpStreamFactoryTest, UsePreConnectIfNoZeroRTT) { GURL url = GURL("https://www.google.com"); SpdySessionDependencies session_deps( - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "http_proxy", TRAFFIC_ANNOTATION_FOR_TESTS)); // Setup params to disable preconnect, but QUIC doesn't 0RTT. @@ -1020,15 +1024,16 @@ TEST_F(HttpStreamFactoryTest, UsePreConnectIfNoZeroRTT) { HostPortPair("http_proxy", 80)); CommonConnectJobParams common_connect_job_params = session->CreateCommonConnectJobParams(); - CapturePreconnectsTransportSocketPool* http_proxy_pool = - new CapturePreconnectsTransportSocketPool(&common_connect_job_params); + auto http_proxy_pool = + std::make_unique<CapturePreconnectsTransportSocketPool>( + &common_connect_job_params); + auto* http_proxy_pool_ptr = http_proxy_pool.get(); auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>(); - mock_pool_manager->SetSocketPool(proxy_server, - base::WrapUnique(http_proxy_pool)); + mock_pool_manager->SetSocketPool(proxy_server, std::move(http_proxy_pool)); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); PreconnectHelperForURL(num_streams, url, NetworkIsolationKey(), SecureDnsPolicy::kAllow, session.get()); - EXPECT_EQ(num_streams, http_proxy_pool->last_num_streams()); + EXPECT_EQ(num_streams, http_proxy_pool_ptr->last_num_streams()); } } @@ -1039,9 +1044,9 @@ int GetSocketPoolGroupCount(ClientSocketPool* pool) { int count = 0; base::Value dict = pool->GetInfoAsValue("", ""); EXPECT_TRUE(dict.is_dict()); - const base::Value* groups = dict.FindDictKey("groups"); + const base::Value::Dict* groups = dict.GetDict().FindDict("groups"); if (groups) { - count = groups->DictSize(); + count = groups->size(); } return count; } @@ -1052,14 +1057,14 @@ int GetSpdySessionCount(HttpNetworkSession* session) { session->spdy_session_pool()->SpdySessionPoolInfoToValue()); if (!value || !value->is_list()) return -1; - return value->GetListDeprecated().size(); + return value->GetList().size(); } // Return count of sockets handed out by a given socket pool. int GetHandedOutSocketCount(ClientSocketPool* pool) { base::Value dict = pool->GetInfoAsValue("", ""); EXPECT_TRUE(dict.is_dict()); - return dict.FindIntKey("handed_out_socket_count").value_or(-1); + return dict.GetDict().FindInt("handed_out_socket_count").value_or(-1); } // Return count of distinct QUIC sessions. @@ -1382,7 +1387,7 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverSSL) { TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxy) { SpdySessionDependencies session_deps( - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:8888", TRAFFIC_ANNOTATION_FOR_TESTS)); StaticSocketDataProvider socket_data; @@ -1519,7 +1524,7 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) { TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) { SpdySessionDependencies session_deps( - ConfiguredProxyResolutionService::CreateFixed( + ConfiguredProxyResolutionService::CreateFixedForTest( "myproxy:8888", TRAFFIC_ANNOTATION_FOR_TESTS)); MockRead reads[] = { @@ -1616,10 +1621,10 @@ TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpsURL) { TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpURL) { url::SchemeHostPort scheme_host_port("http", "myproxy.org", 443); auto session_deps = std::make_unique<SpdySessionDependencies>( - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS)); std::unique_ptr<ProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS); MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); @@ -1686,10 +1691,10 @@ TEST_F(HttpStreamFactoryTest, url::SchemeHostPort scheme_host_port("http", "myproxy.org", 443); auto session_deps = std::make_unique<SpdySessionDependencies>( - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS)); std::unique_ptr<ProxyResolutionService> proxy_resolution_service = - ConfiguredProxyResolutionService::CreateFixedFromPacResult( + ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest( "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS); MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); @@ -2000,7 +2005,7 @@ class HttpStreamFactoryBidirectionalQuicTest false), proxy_resolution_service_( ConfiguredProxyResolutionService::CreateDirect()), - ssl_config_service_(new SSLConfigServiceDefaults) { + ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()) { FLAGS_quic_enable_http3_grease_randomness = false; quic_context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20)); quic::QuicEnableVersion(version_); @@ -2390,9 +2395,9 @@ TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImplFailure) { // amongst streams with different socket tags). TEST_F(HttpStreamFactoryTest, Tag) { SpdySessionDependencies session_deps; - MockTaggingClientSocketFactory* socket_factory = - new MockTaggingClientSocketFactory(); - session_deps.socket_factory.reset(socket_factory); + auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>(); + auto* socket_factory_ptr = socket_factory.get(); + session_deps.socket_factory = std::move(socket_factory); // Prepare for two HTTPS connects. MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); @@ -2456,9 +2461,9 @@ TEST_F(HttpStreamFactoryTest, Tag) { 1, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify socket tagged appropriately. - EXPECT_TRUE(tag1 == socket_factory->GetLastProducedTCPSocket()->tag()); - EXPECT_TRUE( - socket_factory->GetLastProducedTCPSocket()->tagged_before_connected()); + EXPECT_TRUE(tag1 == socket_factory_ptr->GetLastProducedTCPSocket()->tag()); + EXPECT_TRUE(socket_factory_ptr->GetLastProducedTCPSocket() + ->tagged_before_connected()); // Verify one more stream with a different tag results in one more session and // socket. @@ -2481,9 +2486,9 @@ TEST_F(HttpStreamFactoryTest, Tag) { 2, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify socket tagged appropriately. - EXPECT_TRUE(tag2 == socket_factory->GetLastProducedTCPSocket()->tag()); - EXPECT_TRUE( - socket_factory->GetLastProducedTCPSocket()->tagged_before_connected()); + EXPECT_TRUE(tag2 == socket_factory_ptr->GetLastProducedTCPSocket()->tag()); + EXPECT_TRUE(socket_factory_ptr->GetLastProducedTCPSocket() + ->tagged_before_connected()); // Verify one more stream reusing a tag does not create new sessions, groups // or sockets. @@ -2644,9 +2649,9 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest, Tag) { TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { SpdySessionDependencies session_deps; - MockTaggingClientSocketFactory* socket_factory = - new MockTaggingClientSocketFactory(); - session_deps.socket_factory.reset(socket_factory); + auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>(); + auto* socket_factory_ptr = socket_factory.get(); + session_deps.socket_factory = std::move(socket_factory); // Prepare for two HTTPS connects. MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); @@ -2719,7 +2724,8 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { 1, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify socket tagged appropriately. - MockTaggingStreamSocket* socket = socket_factory->GetLastProducedTCPSocket(); + MockTaggingStreamSocket* socket = + socket_factory_ptr->GetLastProducedTCPSocket(); EXPECT_TRUE(tag1 == socket->tag()); EXPECT_TRUE(socket->tagged_before_connected()); @@ -2743,7 +2749,7 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { 1, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify no new sockets created. - EXPECT_EQ(socket, socket_factory->GetLastProducedTCPSocket()); + EXPECT_EQ(socket, socket_factory_ptr->GetLastProducedTCPSocket()); // Verify socket tag changed. EXPECT_TRUE(tag2 == socket->tag()); EXPECT_FALSE(socket->tagged_before_connected()); @@ -2777,7 +2783,7 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { 1, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify no new sockets created. - EXPECT_EQ(socket, socket_factory->GetLastProducedTCPSocket()); + EXPECT_EQ(socket, socket_factory_ptr->GetLastProducedTCPSocket()); // Verify socket tag changed. EXPECT_TRUE(tag1 == socket->tag()); EXPECT_FALSE(socket->tagged_before_connected()); @@ -2811,7 +2817,8 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { 2, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify a new socket was created. - MockTaggingStreamSocket* socket2 = socket_factory->GetLastProducedTCPSocket(); + MockTaggingStreamSocket* socket2 = + socket_factory_ptr->GetLastProducedTCPSocket(); EXPECT_NE(socket, socket2); // Verify tag set appropriately. EXPECT_TRUE(tag2 == socket2->tag()); @@ -2825,9 +2832,9 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) { // Regression test for https://crbug.com/954503. TEST_F(HttpStreamFactoryTest, ChangeSocketTagAvoidOverwrite) { SpdySessionDependencies session_deps; - MockTaggingClientSocketFactory* socket_factory = - new MockTaggingClientSocketFactory(); - session_deps.socket_factory.reset(socket_factory); + auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>(); + auto* socket_factory_ptr = socket_factory.get(); + session_deps.socket_factory = std::move(socket_factory); // Prepare for two HTTPS connects. MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); @@ -2901,7 +2908,8 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTagAvoidOverwrite) { 1, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify socket tagged appropriately. - MockTaggingStreamSocket* socket = socket_factory->GetLastProducedTCPSocket(); + MockTaggingStreamSocket* socket = + socket_factory_ptr->GetLastProducedTCPSocket(); EXPECT_TRUE(tag1 == socket->tag()); EXPECT_TRUE(socket->tagged_before_connected()); @@ -2933,7 +2941,8 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTagAvoidOverwrite) { 2, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify a new socket was created. - MockTaggingStreamSocket* socket2 = socket_factory->GetLastProducedTCPSocket(); + MockTaggingStreamSocket* socket2 = + socket_factory_ptr->GetLastProducedTCPSocket(); EXPECT_NE(socket, socket2); // Verify tag set appropriately. EXPECT_TRUE(tag2 == socket2->tag()); @@ -2972,7 +2981,7 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTagAvoidOverwrite) { 2, GetHandedOutSocketCount(session->GetSocketPool( HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()))); // Verify no new sockets created. - EXPECT_EQ(socket2, socket_factory->GetLastProducedTCPSocket()); + EXPECT_EQ(socket2, socket_factory_ptr->GetLastProducedTCPSocket()); // Verify socket tag changed. EXPECT_TRUE(tag3 == socket->tag()); EXPECT_FALSE(socket->tagged_before_connected()); @@ -2993,7 +3002,7 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTagAvoidOverwrite) { EXPECT_FALSE(waiter4.websocket_stream()); ASSERT_TRUE(waiter4.stream()); // Verify no new sockets created. - EXPECT_EQ(socket2, socket_factory->GetLastProducedTCPSocket()); + EXPECT_EQ(socket2, socket_factory_ptr->GetLastProducedTCPSocket()); } #endif @@ -3552,8 +3561,8 @@ TEST_F(ProcessAlternativeServicesTest, ProcessEmptyAltSvc) { url::SchemeHostPort origin; NetworkIsolationKey network_isolation_key; - scoped_refptr<HttpResponseHeaders> headers( - base::MakeRefCounted<HttpResponseHeaders>("")); + auto headers = base::MakeRefCounted<HttpResponseHeaders>(""); + session_->http_stream_factory()->ProcessAlternativeServices( session_.get(), network_isolation_key, headers.get(), origin); @@ -3582,8 +3591,7 @@ TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcClear) { .GetAlternativeServiceInfos(origin, network_isolation_key) .empty()); - scoped_refptr<HttpResponseHeaders> headers( - base::MakeRefCounted<HttpResponseHeaders>("")); + auto headers = base::MakeRefCounted<HttpResponseHeaders>(""); headers->AddHeader("alt-svc", "clear"); session_->http_stream_factory()->ProcessAlternativeServices( @@ -3605,8 +3613,7 @@ TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuicIetf) { SchemefulSite(GURL("https://example.com")), SchemefulSite(GURL("https://example.com"))); - scoped_refptr<HttpResponseHeaders> headers( - base::MakeRefCounted<HttpResponseHeaders>("")); + auto headers = base::MakeRefCounted<HttpResponseHeaders>(""); headers->AddHeader("alt-svc", "h3-29=\":443\"," "h3-Q050=\":443\"," @@ -3643,8 +3650,7 @@ TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcHttp2) { SchemefulSite(GURL("https://example.com")), SchemefulSite(GURL("https://example.com"))); - scoped_refptr<HttpResponseHeaders> headers( - base::MakeRefCounted<HttpResponseHeaders>("")); + auto headers = base::MakeRefCounted<HttpResponseHeaders>(""); headers->AddHeader("alt-svc", "h2=\"other.example.com:443\""); session_->http_stream_factory()->ProcessAlternativeServices( diff --git a/chromium/net/http/http_stream_parser.cc b/chromium/net/http/http_stream_parser.cc index 7a0e8f0e4ca..8609f3d3a47 100644 --- a/chromium/net/http/http_stream_parser.cc +++ b/chromium/net/http/http_stream_parser.cc @@ -57,11 +57,11 @@ std::string GetResponseHeaderLines(const HttpResponseHeaders& headers) { base::Value NetLogSendRequestBodyParams(uint64_t length, bool is_chunked, bool did_merge) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetIntKey("length", static_cast<int>(length)); - dict.SetBoolKey("is_chunked", is_chunked); - dict.SetBoolKey("did_merge", did_merge); - return dict; + base::Value::Dict dict; + dict.Set("length", static_cast<int>(length)); + dict.Set("is_chunked", is_chunked); + dict.Set("did_merge", did_merge); + return base::Value(std::move(dict)); } void NetLogSendRequestBody(const NetLogWithSource& net_log, @@ -1007,7 +1007,8 @@ int HttpStreamParser::ParseResponseHeaders(int end_offset) { } } - headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK")); + headers = base::MakeRefCounted<HttpResponseHeaders>( + std::string("HTTP/0.9 200 OK")); } // Check for multiple Content-Length headers when the response is not @@ -1035,7 +1036,6 @@ int HttpStreamParser::ParseResponseHeaders(int end_offset) { } else if (headers->GetHttpVersion() == HttpVersion(1, 1)) { response_->connection_info = HttpResponseInfo::CONNECTION_INFO_HTTP1_1; } - response_->vary_data.Init(*request_, *response_->headers); DVLOG(1) << __func__ << "() content_length = \"" << response_->headers->GetContentLength() << "\n\"" << " headers = \"" << GetResponseHeaderLines(*response_->headers) @@ -1129,6 +1129,12 @@ bool HttpStreamParser::CanReuseConnection() const { return stream_socket_->IsConnected(); } +void HttpStreamParser::OnConnectionClose() { + // This is to ensure `stream_socket_` doesn't get dangling on connection + // close. + stream_socket_ = nullptr; +} + void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) { if (!request_->url.SchemeIsCryptographic() || !stream_socket_->GetSSLInfo(ssl_info)) { diff --git a/chromium/net/http/http_stream_parser.h b/chromium/net/http/http_stream_parser.h index 73a4bc560ea..b9287d07343 100644 --- a/chromium/net/http/http_stream_parser.h +++ b/chromium/net/http/http_stream_parser.h @@ -95,6 +95,9 @@ class NET_EXPORT_PRIVATE HttpStreamParser { // false. bool CanReuseConnection() const; + // Called when stream is closed. + void OnConnectionClose(); + int64_t received_bytes() const { return received_bytes_; } int64_t sent_bytes() const { return sent_bytes_; } @@ -301,7 +304,7 @@ class NET_EXPORT_PRIVATE HttpStreamParser { // The underlying socket, owned by the caller. The HttpStreamParser must be // destroyed before the caller destroys the socket, or relinquishes ownership // of it. - const raw_ptr<StreamSocket> stream_socket_; + raw_ptr<StreamSocket> stream_socket_; // Whether the socket has already been used. Only used in HTTP/0.9 detection // logic. diff --git a/chromium/net/http/http_stream_parser_unittest.cc b/chromium/net/http/http_stream_parser_unittest.cc index d870cd1c398..981df1366ac 100644 --- a/chromium/net/http/http_stream_parser_unittest.cc +++ b/chromium/net/http/http_stream_parser_unittest.cc @@ -58,8 +58,8 @@ const size_t kMaxPayloadSize = std::unique_ptr<StreamSocket> CreateConnectedSocket(SequencedSocketData* data) { data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); - std::unique_ptr<MockTCPClientSocket> socket( - new MockTCPClientSocket(net::AddressList(), nullptr, data)); + auto socket = + std::make_unique<MockTCPClientSocket>(net::AddressList(), nullptr, data); TestCompletionCallback callback; EXPECT_THAT(socket->Connect(callback.callback()), IsOk()); @@ -363,7 +363,7 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_EmptyBody) { TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_ChunkedBody) { const std::string payload = "123"; - std::unique_ptr<ChunkedUploadDataStream> body(new ChunkedUploadDataStream(0)); + auto body = std::make_unique<ChunkedUploadDataStream>(0); body->AppendData(payload.data(), payload.size(), true); ASSERT_THAT( body->Init(TestCompletionCallback().callback(), NetLogWithSource()), @@ -392,7 +392,8 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_FileBody) { base::Time())); std::unique_ptr<UploadDataStream> body( - new ElementsUploadDataStream(std::move(element_readers), 0)); + std::make_unique<ElementsUploadDataStream>(std::move(element_readers), + 0)); TestCompletionCallback callback; ASSERT_THAT(body->Init(callback.callback(), NetLogWithSource()), IsError(ERR_IO_PENDING)); @@ -413,7 +414,8 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_SmallBodyInMemory) { payload.data(), payload.size())); std::unique_ptr<UploadDataStream> body( - new ElementsUploadDataStream(std::move(element_readers), 0)); + std::make_unique<ElementsUploadDataStream>(std::move(element_readers), + 0)); ASSERT_THAT(body->Init(CompletionOnceCallback(), NetLogWithSource()), IsOk()); // Yes, should be merged if the in-memory body is small here. ASSERT_TRUE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( @@ -427,7 +429,8 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_LargeBodyInMemory) { payload.data(), payload.size())); std::unique_ptr<UploadDataStream> body( - new ElementsUploadDataStream(std::move(element_readers), 0)); + std::make_unique<ElementsUploadDataStream>(std::move(element_readers), + 0)); ASSERT_THAT(body->Init(CompletionOnceCallback(), NetLogWithSource()), IsOk()); // Shouldn't be merged if the in-memory body is large here. ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody( @@ -1249,12 +1252,12 @@ class SimpleGetRunner { // The data used to back |string_piece| must stay alive until all mock data // has been read. void AddRead(base::StringPiece string_piece) { - reads_.push_back(MockRead(SYNCHRONOUS, string_piece.data(), - string_piece.length(), sequence_number_++)); + reads_.emplace_back(SYNCHRONOUS, string_piece.data(), string_piece.length(), + sequence_number_++); } void SetupParserAndSendRequest() { - reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF + reads_.emplace_back(SYNCHRONOUS, 0, sequence_number_++); // EOF data_ = std::make_unique<SequencedSocketData>(reads_, writes_); stream_socket_ = CreateConnectedSocket(data_.get()); @@ -1663,8 +1666,8 @@ TEST(HttpStreamParser, ReceivedBytesMultipleReads) { } SimpleGetRunner get_runner; - for (std::vector<std::string>::size_type i = 0; i < blocks.size(); ++i) - get_runner.AddRead(blocks[i]); + for (const auto& block : blocks) + get_runner.AddRead(block); get_runner.SetupParserAndSendRequest(); get_runner.ReadHeaders(); int64_t headers_size = headers.size(); @@ -2158,7 +2161,7 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) { SequencedSocketData data(reads, writes); std::unique_ptr<StreamSocket> stream_socket = CreateConnectedSocket(&data); - std::unique_ptr<HttpRequestInfo> request_info(new HttpRequestInfo()); + auto request_info = std::make_unique<HttpRequestInfo>(); request_info->method = "GET"; request_info->url = GURL("http://somewhere/foo.html"); @@ -2168,8 +2171,8 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) { request_info.get(), read_buffer.get(), NetLogWithSource()); - std::unique_ptr<HttpRequestHeaders> request_headers(new HttpRequestHeaders()); - std::unique_ptr<HttpResponseInfo> response_info(new HttpResponseInfo()); + auto request_headers = std::make_unique<HttpRequestHeaders>(); + auto response_info = std::make_unique<HttpResponseInfo>(); TestCompletionCallback callback; ASSERT_EQ( OK, parser.SendRequest("GET /foo.html HTTP/1.1\r\n", *request_headers, diff --git a/chromium/net/http/http_stream_request.cc b/chromium/net/http/http_stream_request.cc index c2446311e23..a938d5dcc53 100644 --- a/chromium/net/http/http_stream_request.cc +++ b/chromium/net/http/http_stream_request.cc @@ -35,7 +35,7 @@ HttpStreamRequest::HttpStreamRequest( HttpStreamRequest::~HttpStreamRequest() { net_log_.EndEvent(NetLogEventType::HTTP_STREAM_REQUEST); - helper_->OnRequestComplete(); + helper_.ExtractAsDangling()->OnRequestComplete(); // May delete `*helper_`; } void HttpStreamRequest::Complete(bool was_alpn_negotiated, diff --git a/chromium/net/http/http_stream_request.h b/chromium/net/http/http_stream_request.h index 8b8eb41dfdf..9f4b3ada44b 100644 --- a/chromium/net/http/http_stream_request.h +++ b/chromium/net/http/http_stream_request.h @@ -50,7 +50,7 @@ class NET_EXPORT_PRIVATE HttpStreamRequest { // called as a result of a stream request. class NET_EXPORT_PRIVATE Delegate { public: - virtual ~Delegate() {} + virtual ~Delegate() = default; // This is the success case for RequestStream. // |stream| is now owned by the delegate. @@ -137,7 +137,7 @@ class NET_EXPORT_PRIVATE HttpStreamRequest { class NET_EXPORT_PRIVATE Helper { public: - virtual ~Helper() {} + virtual ~Helper() = default; // Returns the LoadState for Request. virtual LoadState GetLoadState() const = 0; @@ -219,7 +219,7 @@ class NET_EXPORT_PRIVATE HttpStreamRequest { private: const GURL url_; - // Unowned. The helper must outlive this request. + // Unowned. The helper must not be destroyed before this object is. raw_ptr<Helper> helper_; const raw_ptr<WebSocketHandshakeStreamBase::CreateHelper> diff --git a/chromium/net/http/http_transaction.h b/chromium/net/http/http_transaction.h index 58e46c5123e..0d28e304e82 100644 --- a/chromium/net/http/http_transaction.h +++ b/chromium/net/http/http_transaction.h @@ -61,7 +61,7 @@ class NET_EXPORT_PRIVATE HttpTransaction { CompletionOnceCallback callback)>; // Stops any pending IO and destroys the transaction object. - virtual ~HttpTransaction() {} + virtual ~HttpTransaction() = default; // Starts the HTTP transaction (i.e., sends the HTTP request). // diff --git a/chromium/net/http/http_transaction_factory.h b/chromium/net/http/http_transaction_factory.h index d787c69b8f0..b04d1d32421 100644 --- a/chromium/net/http/http_transaction_factory.h +++ b/chromium/net/http/http_transaction_factory.h @@ -19,7 +19,7 @@ class HttpTransaction; // An interface to a class that can create HttpTransaction objects. class NET_EXPORT HttpTransactionFactory { public: - virtual ~HttpTransactionFactory() {} + virtual ~HttpTransactionFactory() = default; // Creates a HttpTransaction object. On success, saves the new // transaction to |*trans| and returns OK. diff --git a/chromium/net/http/http_transaction_test_util.cc b/chromium/net/http/http_transaction_test_util.cc index 254263aba71..865099933cd 100644 --- a/chromium/net/http/http_transaction_test_util.cc +++ b/chromium/net/http/http_transaction_test_util.cc @@ -179,9 +179,9 @@ const MockTransaction* FindMockTransaction(const GURL& url) { return it->second; // look for builtins: - for (size_t i = 0; i < std::size(kBuiltinMockTransactions); ++i) { - if (url == GURL(kBuiltinMockTransactions[i]->url)) - return kBuiltinMockTransactions[i]; + for (const auto* transaction : kBuiltinMockTransactions) { + if (url == GURL(transaction->url)) + return transaction; } return nullptr; } @@ -204,7 +204,7 @@ MockHttpRequest::MockHttpRequest(const MockTransaction& t) { } std::string MockHttpRequest::CacheKey() { - return HttpCache::GenerateCacheKeyForTest(this); + return *HttpCache::GenerateCacheKeyForRequest(this); } //----------------------------------------------------------------------------- @@ -506,8 +506,7 @@ int MockNetworkTransaction::StartInternal(const HttpRequestInfo* request, if (!t->response_time.is_null()) response_.response_time = t->response_time; - response_.headers = new HttpResponseHeaders(header_data); - response_.vary_data.Init(*request, *response_.headers.get()); + response_.headers = base::MakeRefCounted<HttpResponseHeaders>(header_data); response_.ssl_info.cert = t->cert; response_.ssl_info.cert_status = t->cert_status; response_.ssl_info.connection_status = t->ssl_connection_status; @@ -608,8 +607,8 @@ int MockNetworkLayer::CreateTransaction( std::unique_ptr<HttpTransaction>* trans) { transaction_count_++; last_create_transaction_priority_ = priority; - std::unique_ptr<MockNetworkTransaction> mock_transaction( - new MockNetworkTransaction(priority, this)); + auto mock_transaction = + std::make_unique<MockNetworkTransaction>(priority, this); last_transaction_ = mock_transaction->AsWeakPtr(); *trans = std::move(mock_transaction); return OK; diff --git a/chromium/net/http/http_util.cc b/chromium/net/http/http_util.cc index 96a6e2943e8..7aa436ea73c 100644 --- a/chromium/net/http/http_util.cc +++ b/chromium/net/http/http_util.cc @@ -335,6 +335,12 @@ bool HttpUtil::IsSafeHeader(base::StringPiece name) { if (base::EqualsCaseInsensitiveASCII(name, field)) return false; } + + if (base::FeatureList::IsEnabled(features::kBlockSetCookieHeader) && + base::EqualsCaseInsensitiveASCII(name, "set-cookie")) { + return false; + } + return true; } diff --git a/chromium/net/http/http_util_unittest.cc b/chromium/net/http/http_util_unittest.cc index b2eb2332b54..c5c278f9890 100644 --- a/chromium/net/http/http_util_unittest.cc +++ b/chromium/net/http/http_util_unittest.cc @@ -38,6 +38,7 @@ TEST(HttpUtilTest, IsSafeHeader) { "keep-alive", "origin", "referer", + "set-cookie", "te", "trailer", "transfer-encoding", @@ -45,11 +46,10 @@ TEST(HttpUtilTest, IsSafeHeader) { "user-agent", "via", }; - for (size_t i = 0; i < std::size(unsafe_headers); ++i) { - EXPECT_FALSE(HttpUtil::IsSafeHeader(unsafe_headers[i])) - << unsafe_headers[i]; - EXPECT_FALSE(HttpUtil::IsSafeHeader(base::ToUpperASCII(unsafe_headers[i]))) - << unsafe_headers[i]; + for (const auto* unsafe_header : unsafe_headers) { + EXPECT_FALSE(HttpUtil::IsSafeHeader(unsafe_header)) << unsafe_header; + EXPECT_FALSE(HttpUtil::IsSafeHeader(base::ToUpperASCII(unsafe_header))) + << unsafe_header; } static const char* const safe_headers[] = { "foo", @@ -92,10 +92,10 @@ TEST(HttpUtilTest, IsSafeHeader) { "user_agent", "viaa", }; - for (size_t i = 0; i < std::size(safe_headers); ++i) { - EXPECT_TRUE(HttpUtil::IsSafeHeader(safe_headers[i])) << safe_headers[i]; - EXPECT_TRUE(HttpUtil::IsSafeHeader(base::ToUpperASCII(safe_headers[i]))) - << safe_headers[i]; + for (const auto* safe_header : safe_headers) { + EXPECT_TRUE(HttpUtil::IsSafeHeader(safe_header)) << safe_header; + EXPECT_TRUE(HttpUtil::IsSafeHeader(base::ToUpperASCII(safe_header))) + << safe_header; } } @@ -339,10 +339,10 @@ TEST(HttpUtilTest, LocateEndOfHeaders) { {"foo\nbar\n\r\njunk", 10}, {"foo\nbar\r\n\njunk", 10}, }; - for (size_t i = 0; i < std::size(tests); ++i) { - size_t input_len = strlen(tests[i].input); - size_t eoh = HttpUtil::LocateEndOfHeaders(tests[i].input, input_len); - EXPECT_EQ(tests[i].expected_result, eoh); + for (const auto& test : tests) { + size_t input_len = strlen(test.input); + size_t eoh = HttpUtil::LocateEndOfHeaders(test.input, input_len); + EXPECT_EQ(test.expected_result, eoh); } } @@ -363,11 +363,10 @@ TEST(HttpUtilTest, LocateEndOfAdditionalHeaders) { {"foo\nbar\n\r\njunk", 10}, {"foo\nbar\r\n\njunk", 10}, }; - for (size_t i = 0; i < std::size(tests); ++i) { - size_t input_len = strlen(tests[i].input); - size_t eoh = - HttpUtil::LocateEndOfAdditionalHeaders(tests[i].input, input_len); - EXPECT_EQ(tests[i].expected_result, eoh); + for (const auto& test : tests) { + size_t input_len = strlen(test.input); + size_t eoh = HttpUtil::LocateEndOfAdditionalHeaders(test.input, input_len); + EXPECT_EQ(test.expected_result, eoh); } } TEST(HttpUtilTest, AssembleRawHeaders) { @@ -686,12 +685,12 @@ TEST(HttpUtilTest, AssembleRawHeaders) { }, }; // clang-format on - for (size_t i = 0; i < std::size(tests); ++i) { - std::string input = tests[i].input; + for (const auto& test : tests) { + std::string input = test.input; std::replace(input.begin(), input.end(), '|', '\0'); std::string raw = HttpUtil::AssembleRawHeaders(input); std::replace(raw.begin(), raw.end(), '\0', '|'); - EXPECT_EQ(tests[i].expected_result, raw); + EXPECT_EQ(test.expected_result, raw); } } @@ -992,21 +991,21 @@ TEST(HttpUtilTest, ParseContentType) { // TODO(abarth): Add more interesting test cases. }; // clang-format on - for (size_t i = 0; i < std::size(tests); ++i) { + for (const auto& test : tests) { std::string mime_type; std::string charset; bool had_charset = false; std::string boundary; - HttpUtil::ParseContentType(tests[i].content_type, &mime_type, &charset, + HttpUtil::ParseContentType(test.content_type, &mime_type, &charset, &had_charset, &boundary); - EXPECT_EQ(tests[i].expected_mime_type, mime_type) - << "content_type=" << tests[i].content_type; - EXPECT_EQ(tests[i].expected_charset, charset) - << "content_type=" << tests[i].content_type; - EXPECT_EQ(tests[i].expected_had_charset, had_charset) - << "content_type=" << tests[i].content_type; - EXPECT_EQ(tests[i].expected_boundary, boundary) - << "content_type=" << tests[i].content_type; + EXPECT_EQ(test.expected_mime_type, mime_type) + << "content_type=" << test.content_type; + EXPECT_EQ(test.expected_charset, charset) + << "content_type=" << test.content_type; + EXPECT_EQ(test.expected_had_charset, had_charset) + << "content_type=" << test.content_type; + EXPECT_EQ(test.expected_boundary, boundary) + << "content_type=" << test.content_type; } } @@ -1632,8 +1631,8 @@ TEST(HttpUtilTest, ParseAcceptEncoding) { {"foo,\"bar\"", "INVALID"}, }; - for (size_t i = 0; i < std::size(tests); ++i) { - std::string value(tests[i].value); + for (const auto& test : tests) { + std::string value(test.value); std::string reformatted; std::set<std::string> allowed_encodings; if (!HttpUtil::ParseAcceptEncoding(value, &allowed_encodings)) { @@ -1644,7 +1643,7 @@ TEST(HttpUtilTest, ParseAcceptEncoding) { encodings_list.push_back(encoding); reformatted = base::JoinString(encodings_list, "|"); } - EXPECT_STREQ(tests[i].expected, reformatted.c_str()) + EXPECT_STREQ(test.expected, reformatted.c_str()) << "value=\"" << value << "\""; } } @@ -1662,8 +1661,8 @@ TEST(HttpUtilTest, ParseContentEncoding) { {"foo,\"bar\"", "INVALID"}, }; - for (size_t i = 0; i < std::size(tests); ++i) { - std::string value(tests[i].value); + for (const auto& test : tests) { + std::string value(test.value); std::string reformatted; std::set<std::string> used_encodings; if (!HttpUtil::ParseContentEncoding(value, &used_encodings)) { @@ -1674,7 +1673,7 @@ TEST(HttpUtilTest, ParseContentEncoding) { encodings_list.push_back(encoding); reformatted = base::JoinString(encodings_list, "|"); } - EXPECT_STREQ(tests[i].expected, reformatted.c_str()) + EXPECT_STREQ(test.expected, reformatted.c_str()) << "value=\"" << value << "\""; } } diff --git a/chromium/net/http/http_vary_data_unittest.cc b/chromium/net/http/http_vary_data_unittest.cc index 0b11adf91f6..b4b3d4c5dfb 100644 --- a/chromium/net/http/http_vary_data_unittest.cc +++ b/chromium/net/http/http_vary_data_unittest.cc @@ -25,7 +25,7 @@ struct TestTransaction { const std::string& response_headers) { std::string temp(response_headers); std::replace(temp.begin(), temp.end(), '\n', '\0'); - response = new HttpResponseHeaders(temp); + response = base::MakeRefCounted<HttpResponseHeaders>(temp); request.extra_headers.Clear(); for (const auto& [key, value] : request_headers) diff --git a/chromium/net/http/http_version.h b/chromium/net/http/http_version.h index 13864a65c60..29cbf81b254 100644 --- a/chromium/net/http/http_version.h +++ b/chromium/net/http/http_version.h @@ -16,7 +16,8 @@ class HttpVersion { HttpVersion() : value_(0) { } // Build from unsigned major/minor pair. - HttpVersion(uint16_t major, uint16_t minor) : value_(major << 16 | minor) {} + HttpVersion(uint16_t major, uint16_t minor) + : value_(static_cast<uint32_t>(major << 16) | minor) {} // Major version number. uint16_t major_value() const { return value_ >> 16; } diff --git a/chromium/net/http/mock_http_cache.cc b/chromium/net/http/mock_http_cache.cc index 790d31af772..a96faaaf05a 100644 --- a/chromium/net/http/mock_http_cache.cc +++ b/chromium/net/http/mock_http_cache.cc @@ -368,9 +368,8 @@ void MockDiskEntry::StoreAndDeliverCallbacks(bool store, CallbackInfo c = {entry, std::move(callback)}; callback_list.push_back(std::move(c)); } else { - for (size_t i = 0; i < callback_list.size(); i++) { - CallbackInfo& c = callback_list[i]; - c.entry->CallbackLater(std::move(c.callback)); + for (auto& callback_info : callback_list) { + callback_info.entry->CallbackLater(std::move(callback_info.callback)); } callback_list.clear(); } @@ -582,7 +581,7 @@ class MockDiskCache::NotImplementedIterator : public Iterator { }; std::unique_ptr<disk_cache::Backend::Iterator> MockDiskCache::CreateIterator() { - return std::unique_ptr<Iterator>(new NotImplementedIterator()); + return std::make_unique<NotImplementedIterator>(); } void MockDiskCache::GetStats(base::StringPairs* stats) { @@ -649,12 +648,10 @@ const std::vector<std::string>& MockDiskCache::GetExternalCacheHits() const { //----------------------------------------------------------------------------- -int MockBackendFactory::CreateBackend( +disk_cache::BackendResult MockBackendFactory::CreateBackend( NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) { - *backend = std::make_unique<MockDiskCache>(); - return OK; + disk_cache::BackendResultCallback callback) { + return disk_cache::BackendResult::Make(std::make_unique<MockDiskCache>()); } //----------------------------------------------------------------------------- @@ -811,43 +808,41 @@ disk_cache::EntryResult MockDiskCacheNoCB::CreateEntry( //----------------------------------------------------------------------------- -int MockBackendNoCbFactory::CreateBackend( +disk_cache::BackendResult MockBackendNoCbFactory::CreateBackend( NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) { - *backend = std::make_unique<MockDiskCacheNoCB>(); - return OK; + disk_cache::BackendResultCallback callback) { + return disk_cache::BackendResult::Make(std::make_unique<MockDiskCacheNoCB>()); } //----------------------------------------------------------------------------- MockBlockingBackendFactory::MockBlockingBackendFactory() = default; - MockBlockingBackendFactory::~MockBlockingBackendFactory() = default; -int MockBlockingBackendFactory::CreateBackend( +disk_cache::BackendResult MockBlockingBackendFactory::CreateBackend( NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) { + disk_cache::BackendResultCallback callback) { if (!block_) { - if (!fail_) - *backend = std::make_unique<MockDiskCache>(); - return Result(); + return MakeResult(); } - backend_ = backend; callback_ = std::move(callback); - return ERR_IO_PENDING; + return disk_cache::BackendResult::MakeError(ERR_IO_PENDING); } void MockBlockingBackendFactory::FinishCreation() { block_ = false; if (!callback_.is_null()) { - if (!fail_) - *backend_ = std::make_unique<MockDiskCache>(); // Running the callback might delete |this|. - std::move(callback_).Run(Result()); + std::move(callback_).Run(MakeResult()); } } +disk_cache::BackendResult MockBlockingBackendFactory::MakeResult() { + if (fail_) + return disk_cache::BackendResult::MakeError(ERR_FAILED); + else + return disk_cache::BackendResult::Make(std::make_unique<MockDiskCache>()); +} + } // namespace net diff --git a/chromium/net/http/mock_http_cache.h b/chromium/net/http/mock_http_cache.h index 9068a3d8456..2c95830c666 100644 --- a/chromium/net/http/mock_http_cache.h +++ b/chromium/net/http/mock_http_cache.h @@ -280,9 +280,9 @@ class MockDiskCache : public disk_cache::Backend { class MockBackendFactory : public HttpCache::BackendFactory { public: - int CreateBackend(NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) override; + disk_cache::BackendResult CreateBackend( + NetLog* net_log, + disk_cache::BackendResultCallback callback) override; }; class MockHttpCache { @@ -358,9 +358,9 @@ class MockDiskCacheNoCB : public MockDiskCache { class MockBackendNoCbFactory : public HttpCache::BackendFactory { public: - int CreateBackend(NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) override; + disk_cache::BackendResult CreateBackend( + NetLog* net_log, + disk_cache::BackendResultCallback callback) override; }; // This backend factory allows us to control the backend instantiation. @@ -369,24 +369,24 @@ class MockBlockingBackendFactory : public HttpCache::BackendFactory { MockBlockingBackendFactory(); ~MockBlockingBackendFactory() override; - int CreateBackend(NetLog* net_log, - std::unique_ptr<disk_cache::Backend>* backend, - CompletionOnceCallback callback) override; + disk_cache::BackendResult CreateBackend( + NetLog* net_log, + disk_cache::BackendResultCallback callback) override; // Completes the backend creation. Any blocked call will be notified via the // provided callback. void FinishCreation(); - std::unique_ptr<disk_cache::Backend>* backend() { return backend_; } void set_fail(bool fail) { fail_ = fail; } - CompletionOnceCallback ReleaseCallback() { return std::move(callback_); } + disk_cache::BackendResultCallback ReleaseCallback() { + return std::move(callback_); + } private: - int Result() { return fail_ ? ERR_FAILED : OK; } + disk_cache::BackendResult MakeResult(); - raw_ptr<std::unique_ptr<disk_cache::Backend>> backend_ = nullptr; - CompletionOnceCallback callback_; + disk_cache::BackendResultCallback callback_; bool block_ = true; bool fail_ = false; }; diff --git a/chromium/net/http/proxy_client_socket.h b/chromium/net/http/proxy_client_socket.h index db9900ffdea..09319659f2a 100644 --- a/chromium/net/http/proxy_client_socket.h +++ b/chromium/net/http/proxy_client_socket.h @@ -26,12 +26,12 @@ class NetLogWithSource; // A common base class for a stream socket tunneled through a proxy. class NET_EXPORT_PRIVATE ProxyClientSocket : public StreamSocket { public: - ProxyClientSocket() {} + ProxyClientSocket() = default; ProxyClientSocket(const ProxyClientSocket&) = delete; ProxyClientSocket& operator=(const ProxyClientSocket&) = delete; - ~ProxyClientSocket() override {} + ~ProxyClientSocket() override = default; // Returns the HttpResponseInfo (including HTTP Headers) from // the response to the CONNECT request. diff --git a/chromium/net/http/structured_headers.h b/chromium/net/http/structured_headers.h index 97a1da5cf01..73b7e616eec 100644 --- a/chromium/net/http/structured_headers.h +++ b/chromium/net/http/structured_headers.h @@ -12,8 +12,7 @@ #include "net/third_party/quiche/src/quiche/common/structured_headers.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace net { -namespace structured_headers { +namespace net::structured_headers { using Item = quiche::structured_headers::Item; using ParameterisedIdentifier = @@ -69,7 +68,6 @@ inline absl::optional<std::string> SerializeDictionary( return quiche::structured_headers::SerializeDictionary(value); } -} // namespace structured_headers -} // namespace net +} // namespace net::structured_headers #endif // NET_HTTP_STRUCTURED_HEADERS_H_ diff --git a/chromium/net/http/transport_security_persister.cc b/chromium/net/http/transport_security_persister.cc index 2b3d0dc57d5..95053920611 100644 --- a/chromium/net/http/transport_security_persister.cc +++ b/chromium/net/http/transport_security_persister.cc @@ -102,27 +102,27 @@ bool IsDynamicExpectCTEnabled() { } // Serializes STS data from |state| to a Value. -base::Value SerializeSTSData(const TransportSecurityState* state) { - base::Value sts_list(base::Value::Type::LIST); +base::Value::List SerializeSTSData(const TransportSecurityState* state) { + base::Value::List sts_list; TransportSecurityState::STSStateIterator sts_iterator(*state); for (; sts_iterator.HasNext(); sts_iterator.Advance()) { const TransportSecurityState::STSState& sts_state = sts_iterator.domain_state(); - base::Value serialized(base::Value::Type::DICTIONARY); - serialized.SetStringKey( - kHostname, HashedDomainToExternalString(sts_iterator.hostname())); - serialized.SetBoolKey(kStsIncludeSubdomains, sts_state.include_subdomains); - serialized.SetDoubleKey(kStsObserved, sts_state.last_observed.ToDoubleT()); - serialized.SetDoubleKey(kExpiry, sts_state.expiry.ToDoubleT()); + base::Value::Dict serialized; + serialized.Set(kHostname, + HashedDomainToExternalString(sts_iterator.hostname())); + serialized.Set(kStsIncludeSubdomains, sts_state.include_subdomains); + serialized.Set(kStsObserved, sts_state.last_observed.ToDoubleT()); + serialized.Set(kExpiry, sts_state.expiry.ToDoubleT()); switch (sts_state.upgrade_mode) { case TransportSecurityState::STSState::MODE_FORCE_HTTPS: - serialized.SetStringKey(kMode, kForceHTTPS); + serialized.Set(kMode, kForceHTTPS); break; case TransportSecurityState::STSState::MODE_DEFAULT: - serialized.SetStringKey(kMode, kDefault); + serialized.Set(kMode, kDefault); break; } @@ -139,16 +139,17 @@ void DeserializeSTSData(const base::Value& sts_list, base::Time current_time(base::Time::Now()); - for (const base::Value& sts_entry : sts_list.GetListDeprecated()) { - if (!sts_entry.is_dict()) + for (const base::Value& sts_entry : sts_list.GetList()) { + const base::Value::Dict* sts_dict = sts_entry.GetIfDict(); + if (!sts_dict) continue; - const std::string* hostname = sts_entry.FindStringKey(kHostname); + const std::string* hostname = sts_dict->FindString(kHostname); absl::optional<bool> sts_include_subdomains = - sts_entry.FindBoolKey(kStsIncludeSubdomains); - absl::optional<double> sts_observed = sts_entry.FindDoubleKey(kStsObserved); - absl::optional<double> expiry = sts_entry.FindDoubleKey(kExpiry); - const std::string* mode = sts_entry.FindStringKey(kMode); + sts_dict->FindBool(kStsIncludeSubdomains); + absl::optional<double> sts_observed = sts_dict->FindDouble(kStsObserved); + absl::optional<double> expiry = sts_dict->FindDouble(kExpiry); + const std::string* mode = sts_dict->FindString(kMode); if (!hostname || !sts_include_subdomains.has_value() || !sts_observed.has_value() || !expiry.has_value() || !mode) { @@ -181,8 +182,8 @@ void DeserializeSTSData(const base::Value& sts_list, } // Serializes Expect-CT data from |state| to a Value. -base::Value SerializeExpectCTData(TransportSecurityState* state) { - base::Value ct_list(base::Value::Type::LIST); +base::Value::List SerializeExpectCTData(TransportSecurityState* state) { + base::Value::List ct_list; if (!IsDynamicExpectCTEnabled()) return ct_list; @@ -192,7 +193,7 @@ base::Value SerializeExpectCTData(TransportSecurityState* state) { const TransportSecurityState::ExpectCTState& expect_ct_state = expect_ct_iterator.domain_state(); - base::Value ct_entry(base::Value::Type::DICTIONARY); + base::Value::Dict ct_entry; base::Value network_isolation_key_value; // Don't serialize entries with transient NetworkIsolationKeys. @@ -200,17 +201,14 @@ base::Value SerializeExpectCTData(TransportSecurityState* state) { &network_isolation_key_value)) { continue; } - ct_entry.SetKey(kNetworkIsolationKey, - std::move(network_isolation_key_value)); - - ct_entry.SetStringKey( - kHostname, HashedDomainToExternalString(expect_ct_iterator.hostname())); - ct_entry.SetDoubleKey(kExpectCTObserved, - expect_ct_state.last_observed.ToDoubleT()); - ct_entry.SetDoubleKey(kExpectCTExpiry, expect_ct_state.expiry.ToDoubleT()); - ct_entry.SetBoolKey(kExpectCTEnforce, expect_ct_state.enforce); - ct_entry.SetStringKey(kExpectCTReportUri, - expect_ct_state.report_uri.spec()); + ct_entry.Set(kNetworkIsolationKey, std::move(network_isolation_key_value)); + + ct_entry.Set(kHostname, + HashedDomainToExternalString(expect_ct_iterator.hostname())); + ct_entry.Set(kExpectCTObserved, expect_ct_state.last_observed.ToDoubleT()); + ct_entry.Set(kExpectCTExpiry, expect_ct_state.expiry.ToDoubleT()); + ct_entry.Set(kExpectCTEnforce, expect_ct_state.enforce); + ct_entry.Set(kExpectCTReportUri, expect_ct_state.report_uri.spec()); ct_list.Append(std::move(ct_entry)); } @@ -228,21 +226,22 @@ void DeserializeExpectCTData(const base::Value& ct_list, const base::Time current_time(base::Time::Now()); - for (const base::Value& ct_entry : ct_list.GetListDeprecated()) { - if (!ct_entry.is_dict()) + for (const base::Value& ct_entry : ct_list.GetList()) { + const base::Value::Dict* ct_dict = ct_entry.GetIfDict(); + if (!ct_dict) continue; - const std::string* hostname = ct_entry.FindStringKey(kHostname); + const std::string* hostname = ct_dict->FindString(kHostname); const base::Value* network_isolation_key_value = - ct_entry.FindKey(kNetworkIsolationKey); + ct_dict->Find(kNetworkIsolationKey); absl::optional<double> expect_ct_last_observed = - ct_entry.FindDoubleKey(kExpectCTObserved); + ct_dict->FindDouble(kExpectCTObserved); absl::optional<double> expect_ct_expiry = - ct_entry.FindDoubleKey(kExpectCTExpiry); + ct_dict->FindDouble(kExpectCTExpiry); absl::optional<bool> expect_ct_enforce = - ct_entry.FindBoolKey(kExpectCTEnforce); + ct_dict->FindBool(kExpectCTEnforce); const std::string* expect_ct_report_uri = - ct_entry.FindStringKey(kExpectCTReportUri); + ct_dict->FindString(kExpectCTReportUri); if (!hostname || !network_isolation_key_value || !expect_ct_last_observed.has_value() || !expect_ct_expiry.has_value() || @@ -351,11 +350,10 @@ void TransportSecurityPersister::OnWriteFinished(base::OnceClosure callback) { bool TransportSecurityPersister::SerializeData(std::string* output) { DCHECK(foreground_runner_->RunsTasksInCurrentSequence()); - base::Value toplevel(base::Value::Type::DICTIONARY); - toplevel.SetIntKey(kVersionKey, kCurrentVersionValue); - toplevel.SetKey(kSTSKey, SerializeSTSData(transport_security_state_)); - toplevel.SetKey(kExpectCTKey, - SerializeExpectCTData(transport_security_state_)); + base::Value::Dict toplevel; + toplevel.Set(kVersionKey, kCurrentVersionValue); + toplevel.Set(kSTSKey, SerializeSTSData(transport_security_state_)); + toplevel.Set(kExpectCTKey, SerializeExpectCTData(transport_security_state_)); base::JSONWriter::Write(toplevel, output); return true; @@ -374,18 +372,19 @@ void TransportSecurityPersister::Deserialize(const std::string& serialized, if (!value || !value->is_dict()) return; - absl::optional<int> version = value->FindIntKey(kVersionKey); + base::Value::Dict& dict = value->GetDict(); + absl::optional<int> version = dict.FindInt(kVersionKey); // Stop if the data is out of date (or in the previous format that didn't have // a version number). if (!version || *version != kCurrentVersionValue) return; - base::Value* sts_value = value->FindKey(kSTSKey); + base::Value* sts_value = dict.Find(kSTSKey); if (sts_value) DeserializeSTSData(*sts_value, state); - base::Value* expect_ct_value = value->FindKey(kExpectCTKey); + base::Value* expect_ct_value = dict.Find(kExpectCTKey); if (expect_ct_value) DeserializeExpectCTData(*expect_ct_value, state); } diff --git a/chromium/net/http/transport_security_persister_unittest.cc b/chromium/net/http/transport_security_persister_unittest.cc index 0789ae4e8ab..a45a44f407e 100644 --- a/chromium/net/http/transport_security_persister_unittest.cc +++ b/chromium/net/http/transport_security_persister_unittest.cc @@ -41,6 +41,14 @@ class TransportSecurityPersisterTest : public ::testing::TestWithParam<bool>, TransportSecurityPersisterTest() : WithTaskEnvironment( base::test::TaskEnvironment::TimeSource::MOCK_TIME) { + // This feature is used in initializing |state_|. + if (partition_expect_ct_state()) { + feature_list_.InitAndEnableFeature( + features::kPartitionExpectCTStateByNetworkIsolationKey); + } else { + feature_list_.InitAndDisableFeature( + features::kPartitionExpectCTStateByNetworkIsolationKey); + } // Mock out time so that entries with hard-coded json data can be // successfully loaded. Use a large enough value that dynamically created // entries have at least somewhat interesting expiration times. @@ -61,14 +69,6 @@ class TransportSecurityPersisterTest : public ::testing::TestWithParam<bool>, base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::BLOCK_SHUTDOWN})); - // This feature is used in initializing |state_|. - if (partition_expect_ct_state()) { - feature_list_.InitAndEnableFeature( - features::kPartitionExpectCTStateByNetworkIsolationKey); - } else { - feature_list_.InitAndDisableFeature( - features::kPartitionExpectCTStateByNetworkIsolationKey); - } state_ = std::make_unique<TransportSecurityState>(); persister_ = std::make_unique<TransportSecurityPersister>( state_.get(), std::move(background_runner), diff --git a/chromium/net/http/transport_security_state.cc b/chromium/net/http/transport_security_state.cc index 25c3764df23..cbe5d84732f 100644 --- a/chromium/net/http/transport_security_state.cc +++ b/chromium/net/http/transport_security_state.cc @@ -79,16 +79,16 @@ base::Value GetPEMEncodedChainAsList(const net::X509Certificate* cert_chain) { if (!cert_chain) return base::Value(base::Value::Type::LIST); - base::Value result(base::Value::Type::LIST); + base::Value::List result; std::vector<std::string> pem_encoded_chain; cert_chain->GetPEMEncodedChain(&pem_encoded_chain); for (const std::string& cert : pem_encoded_chain) result.Append(cert); - return result; + return base::Value(std::move(result)); } -bool HashReportForCache(const base::Value& report, +bool HashReportForCache(const base::Value::Dict& report, const GURL& report_uri, std::string* cache_key) { char hashed[crypto::kSHA256Length]; @@ -112,23 +112,23 @@ bool GetHPKPReport(const HostPortPair& host_port_pair, if (pkp_state.report_uri.is_empty()) return false; - base::Value report(base::Value::Type::DICTIONARY); + base::Value::Dict report; base::Time now = base::Time::Now(); - report.SetStringKey("hostname", host_port_pair.host()); - report.SetIntKey("port", host_port_pair.port()); - report.SetBoolKey("include-subdomains", pkp_state.include_subdomains); - report.SetStringKey("noted-hostname", pkp_state.domain); + report.Set("hostname", host_port_pair.host()); + report.Set("port", host_port_pair.port()); + report.Set("include-subdomains", pkp_state.include_subdomains); + report.Set("noted-hostname", pkp_state.domain); auto served_certificate_chain_list = GetPEMEncodedChainAsList(served_certificate_chain); auto validated_certificate_chain_list = GetPEMEncodedChainAsList(validated_certificate_chain); - report.SetKey("served-certificate-chain", - std::move(served_certificate_chain_list)); - report.SetKey("validated-certificate-chain", - std::move(validated_certificate_chain_list)); + report.Set("served-certificate-chain", + std::move(served_certificate_chain_list)); + report.Set("validated-certificate-chain", + std::move(validated_certificate_chain_list)); - base::Value known_pin_list(base::Value::Type::LIST); + base::Value::List known_pin_list; for (const auto& hash_value : pkp_state.spki_hashes) { std::string known_pin; @@ -152,7 +152,7 @@ bool GetHPKPReport(const HostPortPair& host_port_pair, known_pin_list.Append(known_pin); } - report.SetKey("known-pins", std::move(known_pin_list)); + report.Set("known-pins", std::move(known_pin_list)); // For the sent reports cache, do not include the effective expiration // date. The expiration date will likely change every time the user @@ -163,9 +163,9 @@ bool GetHPKPReport(const HostPortPair& host_port_pair, return false; } - report.SetStringKey("date-time", base::TimeToISO8601(now)); - report.SetStringKey("effective-expiration-date", - base::TimeToISO8601(pkp_state.expiry)); + report.Set("date-time", base::TimeToISO8601(now)); + report.Set("effective-expiration-date", + base::TimeToISO8601(pkp_state.expiry)); if (!base::JSONWriter::Write(report, serialized_report)) { LOG(ERROR) << "Failed to serialize HPKP violation report."; return false; @@ -433,14 +433,13 @@ bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host) { base::Value TransportSecurityState::NetLogUpgradeToSSLParam( const std::string& host) { STSState sts_state; - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetStringKey("host", host); - dict.SetBoolKey("get_sts_state_result", GetSTSState(host, &sts_state)); - dict.SetBoolKey("should_upgrade_to_ssl", sts_state.ShouldUpgradeToSSL()); - dict.SetBoolKey( - "host_found_in_hsts_bypass_list", - hsts_host_bypass_list_.find(host) != hsts_host_bypass_list_.end()); - return dict; + base::Value::Dict dict; + dict.Set("host", host); + dict.Set("get_sts_state_result", GetSTSState(host, &sts_state)); + dict.Set("should_upgrade_to_ssl", sts_state.ShouldUpgradeToSSL()); + dict.Set("host_found_in_hsts_bypass_list", + hsts_host_bypass_list_.find(host) != hsts_host_bypass_list_.end()); + return base::Value(std::move(dict)); } bool TransportSecurityState::ShouldUpgradeToSSL( diff --git a/chromium/net/http/transport_security_state.h b/chromium/net/http/transport_security_state.h index f8b68821c48..99899b7c5c2 100644 --- a/chromium/net/http/transport_security_state.h +++ b/chromium/net/http/transport_security_state.h @@ -63,7 +63,7 @@ class NET_EXPORT TransportSecurityState { base::OnceClosure callback) = 0; protected: - virtual ~Delegate() {} + virtual ~Delegate() = default; }; class NET_EXPORT RequireCTDelegate { @@ -310,7 +310,7 @@ class NET_EXPORT TransportSecurityState { error_callback) = 0; protected: - virtual ~ReportSenderInterface() {} + virtual ~ReportSenderInterface() = default; }; // An interface for building and asynchronously sending reports when a @@ -332,7 +332,7 @@ class NET_EXPORT TransportSecurityState { const NetworkIsolationKey& network_isolation_key) = 0; protected: - virtual ~ExpectCTReporter() {} + virtual ~ExpectCTReporter() = default; }; class NET_EXPORT PinSet { @@ -660,10 +660,7 @@ class NET_EXPORT TransportSecurityState { typedef std::map<std::string, STSState> STSStateMap; typedef std::map<std::string, PKPState> PKPStateMap; typedef std::map<ExpectCTStateIndex, ExpectCTState> ExpectCTStateMap; - typedef ExpiringCache<std::string, - bool, - base::TimeTicks, - std::less<base::TimeTicks>> + typedef ExpiringCache<std::string, bool, base::TimeTicks, std::less<>> ReportCache; base::Value NetLogUpgradeToSSLParam(const std::string& host); diff --git a/chromium/net/http/transport_security_state_static.json.gz b/chromium/net/http/transport_security_state_static.json.gz Binary files differindex 67961946223..92182cb59b8 100644 --- a/chromium/net/http/transport_security_state_static.json.gz +++ b/chromium/net/http/transport_security_state_static.json.gz diff --git a/chromium/net/http/transport_security_state_static.pins b/chromium/net/http/transport_security_state_static.pins index 42af336fbf1..5dda8457382 100644 --- a/chromium/net/http/transport_security_state_static.pins +++ b/chromium/net/http/transport_security_state_static.pins @@ -43,9 +43,9 @@ # hash function for preloaded entries again (we have already done so once). # -# Last updated: 2022-08-31 12:54 UTC +# Last updated: 2022-09-19 12:54 UTC PinsListTimestamp -1661950496 +1663592078 TestSPKI sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= diff --git a/chromium/net/http/transport_security_state_unittest.cc b/chromium/net/http/transport_security_state_unittest.cc index 72ea47ef65b..e6a28e588b3 100644 --- a/chromium/net/http/transport_security_state_unittest.cc +++ b/chromium/net/http/transport_security_state_unittest.cc @@ -107,8 +107,7 @@ void MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::Origin origin, const base::Time& timestamp, ct::SCTVerifyStatus status, SignedCertificateTimestampAndStatusList* sct_list) { - scoped_refptr<net::ct::SignedCertificateTimestamp> sct( - new net::ct::SignedCertificateTimestamp()); + auto sct = base::MakeRefCounted<net::ct::SignedCertificateTimestamp>(); sct->version = net::ct::SignedCertificateTimestamp::V1; sct->log_id = log_id; sct->extensions = extensions; @@ -255,11 +254,10 @@ void CompareCertificateChainWithList( ASSERT_TRUE(cert_list->is_list()); std::vector<std::string> pem_encoded_chain; cert_chain->GetPEMEncodedChain(&pem_encoded_chain); - ASSERT_EQ(pem_encoded_chain.size(), cert_list->GetListDeprecated().size()); + ASSERT_EQ(pem_encoded_chain.size(), cert_list->GetList().size()); for (size_t i = 0; i < pem_encoded_chain.size(); i++) { - const std::string& list_cert = - cert_list->GetListDeprecated()[i].GetString(); + const std::string& list_cert = cert_list->GetList()[i].GetString(); EXPECT_EQ(pem_encoded_chain[i], list_cert); } } @@ -274,46 +272,46 @@ void CheckHPKPReport( const HashValueVector& known_pins) { absl::optional<base::Value> value = base::JSONReader::Read(report); ASSERT_TRUE(value.has_value()); - const base::Value& report_dict = value.value(); - ASSERT_TRUE(report_dict.is_dict()); + const base::Value::Dict* report_dict = value.value().GetIfDict(); + ASSERT_TRUE(report_dict); - const std::string* report_hostname = report_dict.FindStringKey("hostname"); + const std::string* report_hostname = report_dict->FindString("hostname"); ASSERT_TRUE(report_hostname); EXPECT_EQ(host_port_pair.host(), *report_hostname); - absl::optional<int> report_port = report_dict.FindIntKey("port"); + absl::optional<int> report_port = report_dict->FindInt("port"); ASSERT_TRUE(report_port.has_value()); EXPECT_EQ(host_port_pair.port(), report_port.value()); absl::optional<bool> report_include_subdomains = - report_dict.FindBoolKey("include-subdomains"); + report_dict->FindBool("include-subdomains"); ASSERT_TRUE(report_include_subdomains.has_value()); EXPECT_EQ(include_subdomains, report_include_subdomains.value()); const std::string* report_noted_hostname = - report_dict.FindStringKey("noted-hostname"); + report_dict->FindString("noted-hostname"); ASSERT_TRUE(report_noted_hostname); EXPECT_EQ(noted_hostname, *report_noted_hostname); // TODO(estark): check times in RFC3339 format. const std::string* report_expiration = - report_dict.FindStringKey("effective-expiration-date"); + report_dict->FindString("effective-expiration-date"); ASSERT_TRUE(report_expiration); EXPECT_FALSE(report_expiration->empty()); - const std::string* report_date = report_dict.FindStringKey("date-time"); + const std::string* report_date = report_dict->FindString("date-time"); ASSERT_TRUE(report_date); EXPECT_FALSE(report_date->empty()); const base::Value* report_served_certificate_chain = - report_dict.FindKey("served-certificate-chain"); + report_dict->Find("served-certificate-chain"); ASSERT_TRUE(report_served_certificate_chain); ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList( served_certificate_chain, report_served_certificate_chain)); const base::Value* report_validated_certificate_chain = - report_dict.FindKey("validated-certificate-chain"); + report_dict->Find("validated-certificate-chain"); ASSERT_TRUE(report_validated_certificate_chain); ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList( validated_certificate_chain, report_validated_certificate_chain)); @@ -1776,17 +1774,23 @@ class CTEmergencyDisableTest : public TransportSecurityStateTest, public testing::WithParamInterface<CTEmergencyDisableSwitchKind> { public: - void SetUp() override { + CTEmergencyDisableTest() { if (GetParam() == CTEmergencyDisableSwitchKind::kComponentUpdaterDrivenSwitch) { - state_.SetCTEmergencyDisabled(true); scoped_feature_list_.Init(); } else { - ASSERT_EQ(GetParam(), CTEmergencyDisableSwitchKind::kFinchDrivenFeature); scoped_feature_list_.InitAndDisableFeature( TransportSecurityState::kCertificateTransparencyEnforcement); } } + void SetUp() override { + if (GetParam() == + CTEmergencyDisableSwitchKind::kComponentUpdaterDrivenSwitch) { + state_.SetCTEmergencyDisabled(true); + } else { + ASSERT_EQ(GetParam(), CTEmergencyDisableSwitchKind::kFinchDrivenFeature); + } + } protected: base::test::ScopedFeatureList scoped_feature_list_; @@ -4175,10 +4179,9 @@ TEST_F(TransportSecurityStateTest, UpdateKeyPinsListTimestamp) { class TransportSecurityStatePinningKillswitchTest : public TransportSecurityStateTest { public: - void SetUp() override { + TransportSecurityStatePinningKillswitchTest() { scoped_feature_list_.InitAndDisableFeature( features::kStaticKeyPinningEnforcement); - TransportSecurityStateTest::SetUp(); } protected: diff --git a/chromium/net/http/url_security_manager.h b/chromium/net/http/url_security_manager.h index 85dfba3559d..764aceb7c47 100644 --- a/chromium/net/http/url_security_manager.h +++ b/chromium/net/http/url_security_manager.h @@ -21,12 +21,12 @@ class HttpAuthFilter; // regarding URL actions (e.g., sending the default credentials to a server). class NET_EXPORT_PRIVATE URLSecurityManager { public: - URLSecurityManager() {} + URLSecurityManager() = default; URLSecurityManager(const URLSecurityManager&) = delete; URLSecurityManager& operator=(const URLSecurityManager&) = delete; - virtual ~URLSecurityManager() {} + virtual ~URLSecurityManager() = default; // Creates a platform-dependent instance of URLSecurityManager. // diff --git a/chromium/net/http/url_security_manager_unittest.cc b/chromium/net/http/url_security_manager_unittest.cc index 672425027c3..0d59ffbd548 100644 --- a/chromium/net/http/url_security_manager_unittest.cc +++ b/chromium/net/http/url_security_manager_unittest.cc @@ -46,8 +46,8 @@ const TestData kTestDataList[] = { } // namespace TEST(URLSecurityManager, UseDefaultCredentials) { - std::unique_ptr<HttpAuthFilter> auth_filter( - new HttpAuthFilterAllowlist(kTestAuthAllowlist)); + auto auth_filter = + std::make_unique<HttpAuthFilterAllowlist>(kTestAuthAllowlist); ASSERT_TRUE(auth_filter); // The URL security manager takes ownership of |auth_filter|. std::unique_ptr<URLSecurityManager> url_security_manager( @@ -68,8 +68,8 @@ TEST(URLSecurityManager, UseDefaultCredentials) { } TEST(URLSecurityManager, CanDelegate) { - std::unique_ptr<HttpAuthFilter> auth_filter( - new HttpAuthFilterAllowlist(kTestAuthAllowlist)); + auto auth_filter = + std::make_unique<HttpAuthFilterAllowlist>(kTestAuthAllowlist); ASSERT_TRUE(auth_filter); // The URL security manager takes ownership of |auth_filter|. std::unique_ptr<URLSecurityManager> url_security_manager( @@ -93,9 +93,8 @@ TEST(URLSecurityManager, CanDelegate_NoAllowlist) { URLSecurityManager::Create()); ASSERT_TRUE(url_security_manager.get()); - for (size_t i = 0; i < std::size(kTestDataList); ++i) { - url::SchemeHostPort scheme_host_port( - GURL(kTestDataList[i].scheme_host_port)); + for (const auto& test : kTestDataList) { + url::SchemeHostPort scheme_host_port(GURL(test.scheme_host_port)); bool can_delegate = url_security_manager->CanDelegate(scheme_host_port); EXPECT_FALSE(can_delegate); } diff --git a/chromium/net/http/url_security_manager_win.cc b/chromium/net/http/url_security_manager_win.cc index d79327cb841..aa07b494910 100644 --- a/chromium/net/http/url_security_manager_win.cc +++ b/chromium/net/http/url_security_manager_win.cc @@ -46,8 +46,8 @@ class URLSecurityManagerWin : public URLSecurityManagerAllowlist { Microsoft::WRL::ComPtr<IInternetSecurityManager> security_manager_; }; -URLSecurityManagerWin::URLSecurityManagerWin() {} -URLSecurityManagerWin::~URLSecurityManagerWin() {} +URLSecurityManagerWin::URLSecurityManagerWin() = default; +URLSecurityManagerWin::~URLSecurityManagerWin() = default; bool URLSecurityManagerWin::CanUseDefaultCredentials( const url::SchemeHostPort& auth_scheme_host_port) const { diff --git a/chromium/net/http/webfonts_histogram.cc b/chromium/net/http/webfonts_histogram.cc index 2f27c82344c..f353536be5e 100644 --- a/chromium/net/http/webfonts_histogram.cc +++ b/chromium/net/http/webfonts_histogram.cc @@ -37,8 +37,7 @@ void RecordCacheEvent(net::HttpResponseInfo::CacheEntryStatus cache_status, } // namespace -namespace net { -namespace web_fonts_histogram { +namespace net::web_fonts_histogram { // Check if |key| is a URL for a font resource of Google Fonts. // If so, record the WebFont.HttpCacheStatus histogram suffixed by "roboto", @@ -61,5 +60,4 @@ void MaybeRecordCacheStatus(HttpResponseInfo::CacheEntryStatus cache_status, } } -} // namespace web_fonts_histogram -} // namespace net +} // namespace net::web_fonts_histogram diff --git a/chromium/net/http/webfonts_histogram.h b/chromium/net/http/webfonts_histogram.h index 9da1fd3bac6..6583650fe60 100644 --- a/chromium/net/http/webfonts_histogram.h +++ b/chromium/net/http/webfonts_histogram.h @@ -9,17 +9,13 @@ #include "net/http/http_response_info.h" -namespace net { - // A collection of functions for histogram reporting about web fonts. -namespace web_fonts_histogram { +namespace net::web_fonts_histogram { NET_EXPORT void MaybeRecordCacheStatus( HttpResponseInfo::CacheEntryStatus cache_status, const std::string& key); -} // namespace web_fonts_histogram - -} // namespace net +} // namespace net::web_fonts_histogram #endif // NET_HTTP_WEBFONTS_HISTOGRAM_H_ diff --git a/chromium/net/http/webfonts_histogram_unittest.cc b/chromium/net/http/webfonts_histogram_unittest.cc index d14481c30ad..7c112510bee 100644 --- a/chromium/net/http/webfonts_histogram_unittest.cc +++ b/chromium/net/http/webfonts_histogram_unittest.cc @@ -8,8 +8,7 @@ #include "base/test/metrics/histogram_tester.h" #include "testing/gtest/include/gtest/gtest.h" -namespace net { -namespace web_fonts_histogram { +namespace net::web_fonts_histogram { namespace { @@ -134,5 +133,4 @@ TEST(WebfontsHistogramTest, TwoRobotoSameBucket_TwoOpenSansDifferentBucket) { histograms.ExpectTotalCount(kOthersHistogramName, 0); } -} // namespace web_fonts_histogram -} // namespace net +} // namespace net::web_fonts_histogram |