summaryrefslogtreecommitdiff
path: root/chromium/net/spdy
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-16 09:59:13 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-20 10:28:53 +0000
commit6c11fb357ec39bf087b8b632e2b1e375aef1b38b (patch)
treec8315530db18a8ee566521c39ab8a6af4f72bc03 /chromium/net/spdy
parent3ffaed019d0772e59d6cdb2d0d32fe4834c31f72 (diff)
downloadqtwebengine-chromium-6c11fb357ec39bf087b8b632e2b1e375aef1b38b.tar.gz
BASELINE: Update Chromium to 74.0.3729.159
Change-Id: I8d2497da544c275415aedd94dd25328d555de811 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/net/spdy')
-rw-r--r--chromium/net/spdy/bidirectional_stream_spdy_impl.cc16
-rw-r--r--chromium/net/spdy/bidirectional_stream_spdy_impl_unittest.cc7
-rw-r--r--chromium/net/spdy/spdy_http_stream.cc4
-rw-r--r--chromium/net/spdy/spdy_http_stream.h1
-rw-r--r--chromium/net/spdy/spdy_http_stream_unittest.cc1
-rw-r--r--chromium/net/spdy/spdy_network_transaction_unittest.cc31
-rw-r--r--chromium/net/spdy/spdy_proxy_client_socket.cc22
-rw-r--r--chromium/net/spdy/spdy_proxy_client_socket.h7
-rw-r--r--chromium/net/spdy/spdy_proxy_client_socket_unittest.cc92
-rw-r--r--chromium/net/spdy/spdy_session.cc217
-rw-r--r--chromium/net/spdy/spdy_session.h44
-rw-r--r--chromium/net/spdy/spdy_session_fuzzer.cc7
-rw-r--r--chromium/net/spdy/spdy_session_pool.cc117
-rw-r--r--chromium/net/spdy/spdy_session_pool.h36
-rw-r--r--chromium/net/spdy/spdy_session_pool_unittest.cc105
-rw-r--r--chromium/net/spdy/spdy_session_unittest.cc120
-rw-r--r--chromium/net/spdy/spdy_stream.cc96
-rw-r--r--chromium/net/spdy/spdy_stream.h9
-rw-r--r--chromium/net/spdy/spdy_stream_unittest.cc1
-rw-r--r--chromium/net/spdy/spdy_test_util_common.cc31
-rw-r--r--chromium/net/spdy/spdy_test_util_common.h8
-rw-r--r--chromium/net/spdy/spdy_write_queue_unittest.cc3
22 files changed, 655 insertions, 320 deletions
diff --git a/chromium/net/spdy/bidirectional_stream_spdy_impl.cc b/chromium/net/spdy/bidirectional_stream_spdy_impl.cc
index 89f217aaec7..f12814553c7 100644
--- a/chromium/net/spdy/bidirectional_stream_spdy_impl.cc
+++ b/chromium/net/spdy/bidirectional_stream_spdy_impl.cc
@@ -69,8 +69,8 @@ void BidirectionalStreamSpdyImpl::Start(
if (!spdy_session_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(&BidirectionalStreamSpdyImpl::NotifyError,
- weak_factory_.GetWeakPtr(), ERR_CONNECTION_CLOSED));
+ base::BindOnce(&BidirectionalStreamSpdyImpl::NotifyError,
+ weak_factory_.GetWeakPtr(), ERR_CONNECTION_CLOSED));
return;
}
@@ -122,8 +122,8 @@ void BidirectionalStreamSpdyImpl::SendvData(
if (written_end_of_stream_) {
LOG(ERROR) << "Writing after end of stream is written.";
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError,
- weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
+ FROM_HERE, base::BindOnce(&BidirectionalStreamSpdyImpl::NotifyError,
+ weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
return;
}
@@ -397,14 +397,14 @@ bool BidirectionalStreamSpdyImpl::MaybeHandleStreamClosedInSendData() {
// blackhole any pending write data. crbug.com/650438.
if (stream_closed_ && closed_stream_status_ == OK) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::OnDataSent,
- weak_factory_.GetWeakPtr()));
+ FROM_HERE, base::BindOnce(&BidirectionalStreamSpdyImpl::OnDataSent,
+ weak_factory_.GetWeakPtr()));
return true;
}
LOG(ERROR) << "Trying to send data after stream has been destroyed.";
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError,
- weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
+ FROM_HERE, base::BindOnce(&BidirectionalStreamSpdyImpl::NotifyError,
+ weak_factory_.GetWeakPtr(), ERR_UNEXPECTED));
return true;
}
diff --git a/chromium/net/spdy/bidirectional_stream_spdy_impl_unittest.cc b/chromium/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
index 73d06111fda..1a314666e47 100644
--- a/chromium/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
+++ b/chromium/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
@@ -13,6 +13,7 @@
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "base/timer/mock_timer.h"
+#include "base/timer/timer.h"
#include "net/base/load_timing_info.h"
#include "net/base/load_timing_info_test_util.h"
#include "net/base/net_errors.h"
@@ -442,9 +443,9 @@ TEST_F(BidirectionalStreamSpdyImplTest, SendDataAfterStreamFailed) {
EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
}
-INSTANTIATE_TEST_CASE_P(BidirectionalStreamSpdyImplTests,
- BidirectionalStreamSpdyImplTest,
- ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(BidirectionalStreamSpdyImplTests,
+ BidirectionalStreamSpdyImplTest,
+ ::testing::Bool());
// Tests that when received RST_STREAM with NO_ERROR, BidirectionalStream does
// not crash when processing pending writes. See crbug.com/650438.
diff --git a/chromium/net/spdy/spdy_http_stream.cc b/chromium/net/spdy/spdy_http_stream.cc
index 62e070b32fa..a4ef27f8499 100644
--- a/chromium/net/spdy/spdy_http_stream.cc
+++ b/chromium/net/spdy/spdy_http_stream.cc
@@ -17,7 +17,7 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
-#include "net/base/host_port_pair.h"
+#include "net/base/ip_endpoint.h"
#include "net/base/upload_data_stream.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
@@ -322,7 +322,7 @@ int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
int result = stream_->GetPeerAddress(&address);
if (result != OK)
return result;
- response_info_->socket_address = HostPortPair::FromIPEndPoint(address);
+ response_info_->remote_endpoint = address;
if (stream_->type() == SPDY_PUSH_STREAM) {
// Pushed streams do not send any data, and should always be
diff --git a/chromium/net/spdy/spdy_http_stream.h b/chromium/net/spdy/spdy_http_stream.h
index 315cba5b217..60fb740a30d 100644
--- a/chromium/net/spdy/spdy_http_stream.h
+++ b/chromium/net/spdy/spdy_http_stream.h
@@ -14,6 +14,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "net/base/completion_once_callback.h"
+#include "net/base/load_timing_info.h"
#include "net/base/net_export.h"
#include "net/log/net_log_source.h"
#include "net/spdy/multiplexed_http_stream.h"
diff --git a/chromium/net/spdy/spdy_http_stream_unittest.cc b/chromium/net/spdy/spdy_http_stream_unittest.cc
index 4ee7ac8aa96..a17f6b3db81 100644
--- a/chromium/net/spdy/spdy_http_stream_unittest.cc
+++ b/chromium/net/spdy/spdy_http_stream_unittest.cc
@@ -8,6 +8,7 @@
#include <string>
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/net/spdy/spdy_network_transaction_unittest.cc b/chromium/net/spdy/spdy_network_transaction_unittest.cc
index ea86d7cd12b..36bb9bcbd7e 100644
--- a/chromium/net/spdy/spdy_network_transaction_unittest.cc
+++ b/chromium/net/spdy/spdy_network_transaction_unittest.cc
@@ -21,6 +21,7 @@
#include "net/base/chunked_upload_data_stream.h"
#include "net/base/completion_once_callback.h"
#include "net/base/elements_upload_data_stream.h"
+#include "net/base/ip_endpoint.h"
#include "net/base/proxy_delegate.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
@@ -178,8 +179,8 @@ class SpdyNetworkTransactionTest : public TestWithScopedTaskEnvironment {
EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_alpn_negotiated);
- EXPECT_EQ("127.0.0.1", response->socket_address.host());
- EXPECT_EQ(443, response->socket_address.port());
+ EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
+ EXPECT_EQ(443, response->remote_endpoint.port());
output_.status_line = response->headers->GetStatusLine();
output_.response_info = *response; // Make a copy so we can verify.
output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
@@ -4865,8 +4866,8 @@ TEST_F(SpdyNetworkTransactionTest, GracefulGoaway) {
EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_alpn_negotiated);
- EXPECT_EQ("127.0.0.1", response->socket_address.host());
- EXPECT_EQ(443, response->socket_address.port());
+ EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
+ EXPECT_EQ(443, response->remote_endpoint.port());
std::string response_data;
rv = ReadTransaction(&trans2, &response_data);
EXPECT_THAT(rv, IsOk());
@@ -4998,8 +4999,8 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredRetry) {
response->connection_info);
EXPECT_TRUE(response->was_alpn_negotiated);
EXPECT_TRUE(request_.url.SchemeIs("https"));
- EXPECT_EQ("127.0.0.1", response->socket_address.host());
- EXPECT_EQ(443, response->socket_address.port());
+ EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
+ EXPECT_EQ(443, response->remote_endpoint.port());
std::string response_data;
ASSERT_THAT(ReadTransaction(helper.trans(), &response_data), IsOk());
EXPECT_EQ("hello", response_data);
@@ -5088,8 +5089,8 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
response->connection_info);
EXPECT_FALSE(response->was_alpn_negotiated);
EXPECT_TRUE(request_.url.SchemeIs("https"));
- EXPECT_EQ("127.0.0.1", response->socket_address.host());
- EXPECT_EQ(70, response->socket_address.port());
+ EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
+ EXPECT_EQ(70, response->remote_endpoint.port());
std::string response_data;
ASSERT_THAT(ReadTransaction(helper.trans(), &response_data), IsOk());
EXPECT_EQ("hello", response_data);
@@ -5656,9 +5657,9 @@ class SpdyNetworkTransactionPushHeaderTest
}
};
-INSTANTIATE_TEST_CASE_P(,
- SpdyNetworkTransactionPushHeaderTest,
- ::testing::ValuesIn(push_header_test_cases));
+INSTANTIATE_TEST_SUITE_P(,
+ SpdyNetworkTransactionPushHeaderTest,
+ ::testing::ValuesIn(push_header_test_cases));
TEST_P(SpdyNetworkTransactionPushHeaderTest,
PushedResponseHeadersReceivedBeforeRequest) {
@@ -5863,9 +5864,9 @@ class SpdyNetworkTransactionPushUrlTest
}
};
-INSTANTIATE_TEST_CASE_P(,
- SpdyNetworkTransactionPushUrlTest,
- ::testing::ValuesIn(push_url_test_cases));
+INSTANTIATE_TEST_SUITE_P(,
+ SpdyNetworkTransactionPushUrlTest,
+ ::testing::ValuesIn(push_url_test_cases));
TEST_P(SpdyNetworkTransactionPushUrlTest, PushUrlTest) {
RunTest();
@@ -8126,7 +8127,7 @@ TEST_F(SpdyNetworkTransactionTest, SecureWebSocketOverHttp2Proxy) {
response->connection_info);
EXPECT_TRUE(response->was_alpn_negotiated);
EXPECT_FALSE(response->was_fetched_via_spdy);
- EXPECT_EQ(70, response->socket_address.port());
+ EXPECT_EQ(70, response->remote_endpoint.port());
ASSERT_TRUE(response->headers);
EXPECT_EQ("HTTP/1.1 101 Switching Protocols",
response->headers->GetStatusLine());
diff --git a/chromium/net/spdy/spdy_proxy_client_socket.cc b/chromium/net/spdy/spdy_proxy_client_socket.cc
index f8d4713d0ab..c726ddc645d 100644
--- a/chromium/net/spdy/spdy_proxy_client_socket.cc
+++ b/chromium/net/spdy/spdy_proxy_client_socket.cc
@@ -22,7 +22,6 @@
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
-#include "net/http/proxy_connect_redirect_http_stream.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source_type.h"
#include "net/spdy/spdy_http_utils.h"
@@ -45,7 +44,6 @@ SpdyProxyClientSocket::SpdyProxyClientSocket(
user_buffer_len_(0),
write_buffer_len_(0),
was_ever_used_(false),
- redirect_has_load_timing_info_(false),
net_log_(NetLogWithSource::Make(spdy_stream->net_log().net_log(),
NetLogSourceType::PROXY_CLIENT_SOCKET)),
source_dependency_(source_net_log.source()),
@@ -82,7 +80,7 @@ int SpdyProxyClientSocket::RestartWithAuth(CompletionOnceCallback callback) {
// stream may not be reused and a new SpdyProxyClientSocket must be
// created (possibly on top of the same SPDY Session).
next_state_ = STATE_DISCONNECTED;
- return OK;
+ return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH;
}
bool SpdyProxyClientSocket::IsUsingSpdy() const {
@@ -93,15 +91,13 @@ NextProto SpdyProxyClientSocket::GetProxyNegotiatedProtocol() const {
return spdy_stream_->GetNegotiatedProtocol();
}
-void SpdyProxyClientSocket::SetStreamPriority(RequestPriority priority) {
- spdy_stream_->SetPriority(priority);
-}
-
-std::unique_ptr<HttpStream>
-SpdyProxyClientSocket::CreateConnectResponseStream() {
- return std::make_unique<ProxyConnectRedirectHttpStream>(
- redirect_has_load_timing_info_ ? &redirect_load_timing_info_ : nullptr);
-}
+// Ignore priority changes, just use priority of initial request. Since multiple
+// requests are pooled on the SpdyProxyClientSocket, reprioritization doesn't
+// really work.
+//
+// TODO(mmenke): Use a single priority value for all SpdyProxyClientSockets,
+// regardless of what priority they're created with.
+void SpdyProxyClientSocket::SetStreamPriority(RequestPriority priority) {}
// Sends a HEADERS frame to the proxy with a CONNECT request
// for the specified endpoint. Waits for the server to send back
@@ -413,8 +409,6 @@ int SpdyProxyClientSocket::DoReadReplyComplete(int result) {
if (!SanitizeProxyRedirect(&response_))
return ERR_TUNNEL_CONNECTION_FAILED;
- redirect_has_load_timing_info_ =
- spdy_stream_->GetLoadTimingInfo(&redirect_load_timing_info_);
// Note that this triggers a spdy::ERROR_CODE_CANCEL.
spdy_stream_->DetachDelegate();
next_state_ = STATE_DISCONNECTED;
diff --git a/chromium/net/spdy/spdy_proxy_client_socket.h b/chromium/net/spdy/spdy_proxy_client_socket.h
index 4465e5b6ee8..ca6e0750e19 100644
--- a/chromium/net/spdy/spdy_proxy_client_socket.h
+++ b/chromium/net/spdy/spdy_proxy_client_socket.h
@@ -18,7 +18,6 @@
#include "net/base/completion_callback.h"
#include "net/base/completion_once_callback.h"
#include "net/base/host_port_pair.h"
-#include "net/base/load_timing_info.h"
#include "net/base/net_export.h"
#include "net/http/http_auth_controller.h"
#include "net/http/http_request_headers.h"
@@ -36,7 +35,6 @@
namespace net {
-class HttpStream;
class IOBuffer;
class SpdyStream;
@@ -58,7 +56,6 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
// ProxyClientSocket methods:
const HttpResponseInfo* GetConnectResponseInfo() const override;
- std::unique_ptr<HttpStream> CreateConnectResponseStream() override;
const scoped_refptr<HttpAuthController>& GetAuthController() const override;
int RestartWithAuth(CompletionOnceCallback callback) override;
bool IsUsingSpdy() const override;
@@ -173,10 +170,6 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
// True if the transport socket has ever sent data.
bool was_ever_used_;
- // Used only for redirects.
- bool redirect_has_load_timing_info_;
- LoadTimingInfo redirect_load_timing_info_;
-
const NetLogWithSource net_log_;
const NetLogSource source_dependency_;
diff --git a/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc b/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc
index 8e53e3084bc..c7899bdb448 100644
--- a/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc
+++ b/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -13,9 +13,11 @@
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/address_list.h"
+#include "net/base/load_timing_info.h"
#include "net/base/test_completion_callback.h"
#include "net/base/winsock_init.h"
#include "net/dns/mock_host_resolver.h"
+#include "net/http/http_proxy_connect_job.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/log/net_log_event_type.h"
@@ -24,9 +26,15 @@
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
#include "net/socket/client_socket_factory.h"
+#include "net/socket/connect_job_test_util.h"
#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
+#include "net/socket/socks_connect_job.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/socket/ssl_connect_job.h"
+#include "net/socket/stream_socket.h"
#include "net/socket/tcp_client_socket.h"
+#include "net/socket/transport_connect_job.h"
#include "net/spdy/buffered_spdy_framer.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_session_pool.h"
@@ -46,6 +54,8 @@ using net::test::IsOk;
//-----------------------------------------------------------------------------
+namespace net {
+
namespace {
static const char kRequestUrl[] = "https://www.google.com/";
@@ -72,9 +82,60 @@ static const int kLen333 = kLen3 + kLen3 + kLen3;
static const char kRedirectUrl[] = "https://example.com/";
-} // anonymous namespace
+// Creates a SpdySession with a StreamSocket, instead of a ClientSocketHandle.
+base::WeakPtr<SpdySession> CreateSpdyProxySession(
+ HttpNetworkSession* http_session,
+ SpdySessionDependencies* session_deps,
+ const SpdySessionKey& key) {
+ EXPECT_FALSE(http_session->spdy_session_pool()->FindAvailableSession(
+ key, true /* enable_ip_based_pooling */, false /* is_websocket */,
+ NetLogWithSource()));
+
+ auto transport_params = base::MakeRefCounted<TransportSocketParams>(
+ key.host_port_pair(), false /* disable_resolver_cache */,
+ OnHostResolutionCallback());
+
+ SSLConfig ssl_config;
+ auto ssl_params = base::MakeRefCounted<SSLSocketParams>(
+ transport_params, nullptr, nullptr, key.host_port_pair(), ssl_config,
+ key.privacy_mode());
+ TestConnectJobDelegate connect_job_delegate;
+ SSLConnectJob connect_job(
+ MEDIUM,
+ CommonConnectJobParams(
+ SocketTag(), session_deps->socket_factory.get(),
+ session_deps->host_resolver.get(), nullptr /* proxy_delegate */,
+ SSLClientSocketContext(session_deps->cert_verifier.get(),
+ session_deps->channel_id_service.get(),
+ session_deps->transport_security_state.get(),
+ session_deps->cert_transparency_verifier.get(),
+ session_deps->ct_policy_enforcer.get(),
+ nullptr /* ssl_client_session_cache_arg */),
+ SSLClientSocketContext(session_deps->cert_verifier.get(),
+ session_deps->channel_id_service.get(),
+ session_deps->transport_security_state.get(),
+ session_deps->cert_transparency_verifier.get(),
+ session_deps->ct_policy_enforcer.get(),
+ nullptr /* ssl_client_session_cache_arg */),
+ nullptr /* socket_performance_watcher_factory */,
+ nullptr /* network_quality_estimator */, session_deps->net_log,
+ nullptr /* websocket_endpoint_lock_manager */),
+ ssl_params, &connect_job_delegate, nullptr /* net_log */);
+ connect_job_delegate.StartJobExpectingResult(&connect_job, OK,
+ false /* expect_sync_result */);
+
+ base::WeakPtr<SpdySession> spdy_session =
+ http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
+ key, false /* is_trusted_proxy */,
+ connect_job_delegate.ReleaseSocket(), LoadTimingInfo::ConnectTiming(),
+ NetLogWithSource());
+ // Failure is reported asynchronously.
+ EXPECT_TRUE(spdy_session);
+ EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key));
+ return spdy_session;
+}
-namespace net {
+} // namespace
class SpdyProxyClientSocketTest : public PlatformTest,
public WithScopedTaskEnvironment,
@@ -91,7 +152,7 @@ class SpdyProxyClientSocketTest : public PlatformTest,
void PopulateConnectRequestIR(spdy::SpdyHeaderBlock* syn_ir);
void PopulateConnectReplyIR(spdy::SpdyHeaderBlock* block, const char* status);
spdy::SpdySerializedFrame ConstructConnectRequestFrame(
- RequestPriority priority);
+ RequestPriority priority = LOWEST);
spdy::SpdySerializedFrame ConstructConnectAuthRequestFrame();
spdy::SpdySerializedFrame ConstructConnectReplyFrame();
spdy::SpdySerializedFrame ConstructConnectAuthReplyFrame();
@@ -206,8 +267,9 @@ void SpdyProxyClientSocketTest::Initialize(base::span<const MockRead> reads,
session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
// Creates the SPDY session and stream.
- spdy_session_ = CreateSpdySession(session_.get(), endpoint_spdy_session_key_,
- NetLogWithSource());
+ spdy_session_ = CreateSpdyProxySession(session_.get(), &session_deps_,
+ endpoint_spdy_session_key_);
+
base::WeakPtr<SpdyStream> spdy_stream(
CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url_, LOWEST,
@@ -219,7 +281,8 @@ void SpdyProxyClientSocketTest::Initialize(base::span<const MockRead> reads,
spdy_stream, user_agent_, endpoint_host_port_pair_, net_log_.bound(),
new HttpAuthController(
HttpAuth::AUTH_PROXY, GURL("https://" + proxy_host_port_.ToString()),
- session_->http_auth_cache(), session_->http_auth_handler_factory()));
+ session_->http_auth_cache(), session_->http_auth_handler_factory(),
+ session_->host_resolver()));
}
scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
@@ -356,7 +419,7 @@ void SpdyProxyClientSocketTest::PopulateConnectReplyIR(
// Constructs a standard SPDY HEADERS frame for a CONNECT request.
spdy::SpdySerializedFrame
SpdyProxyClientSocketTest::ConstructConnectRequestFrame(
- RequestPriority priority = LOWEST) {
+ RequestPriority priority) {
spdy::SpdyHeaderBlock block;
PopulateConnectRequestIR(&block);
return spdy_util_.ConstructSpdyHeaders(kStreamId, std::move(block), priority,
@@ -413,16 +476,15 @@ SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
spdy::SpdySerializedFrame SpdyProxyClientSocketTest::ConstructBodyFrame(
const char* data,
int length) {
- return spdy_util_.ConstructSpdyDataFrame(kStreamId,
- base::StringPiece(data, length),
- /*fin=*/false);
+ return spdy_util_.ConstructSpdyDataFrame(
+ kStreamId, base::StringPiece(data, length), false /* fin */);
}
// ----------- Connect
-INSTANTIATE_TEST_CASE_P(/* no prefix */,
- SpdyProxyClientSocketTest,
- ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(/* no prefix */,
+ SpdyProxyClientSocketTest,
+ ::testing::Bool());
TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
@@ -537,7 +599,7 @@ TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
}
TEST_P(SpdyProxyClientSocketTest, SetStreamPriority) {
- spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame(HIGHEST));
+ spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame(LOWEST));
MockWrite writes[] = {
CreateMockWrite(conn, 0, SYNCHRONOUS),
};
@@ -550,6 +612,8 @@ TEST_P(SpdyProxyClientSocketTest, SetStreamPriority) {
Initialize(reads, writes);
+ // Set the stream priority. Since a connection was already established, it's
+ // too late to adjust the HTTP2 stream's priority, and the request is ignored.
sock_->SetStreamPriority(HIGHEST);
AssertConnectSucceeds();
diff --git a/chromium/net/spdy/spdy_session.cc b/chromium/net/spdy/spdy_session.cc
index 9c3605b30ad..f63c1271b5e 100644
--- a/chromium/net/spdy/spdy_session.cc
+++ b/chromium/net/spdy/spdy_session.cc
@@ -44,6 +44,7 @@
#include "net/log/net_log_with_source.h"
#include "net/nqe/network_quality_estimator.h"
#include "net/quic/quic_http_utils.h"
+#include "net/socket/client_socket_handle.h"
#include "net/socket/socket.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/header_coalescer.h"
@@ -844,6 +845,7 @@ SpdySession::SpdySession(
http_server_properties_(http_server_properties),
transport_security_state_(transport_security_state),
ssl_config_service_(ssl_config_service),
+ socket_(nullptr),
stream_hi_water_mark_(kFirstStreamId),
last_accepted_push_stream_id_(0),
push_delegate_(push_delegate),
@@ -920,11 +922,10 @@ SpdySession::~SpdySession() {
CHECK(!in_io_loop_);
DcheckDraining();
- // TODO(akalin): Check connection->is_initialized() instead. This
- // requires re-working CreateFakeSpdySession(), though.
- DCHECK(connection_->socket());
+ // TODO(akalin): Check connection->is_initialized().
+ DCHECK(socket_);
// With SPDY we can't recycle sockets.
- connection_->socket()->Disconnect();
+ socket_->Disconnect();
RecordHistograms();
@@ -981,48 +982,40 @@ void SpdySession::CancelPush(const GURL& url) {
ResetStream(stream_id, ERR_ABORTED, "Cancelled push stream.");
}
-void SpdySession::InitializeWithSocket(
- std::unique_ptr<ClientSocketHandle> connection,
+void SpdySession::InitializeWithSocketHandle(
+ std::unique_ptr<ClientSocketHandle> client_socket_handle,
SpdySessionPool* pool) {
- CHECK(!in_io_loop_);
- DCHECK_EQ(availability_state_, STATE_AVAILABLE);
- DCHECK_EQ(read_state_, READ_STATE_DO_READ);
- DCHECK_EQ(write_state_, WRITE_STATE_IDLE);
- DCHECK(!connection_);
+ DCHECK(!client_socket_handle_);
+ DCHECK(!owned_stream_socket_);
+ DCHECK(!socket_);
// TODO(akalin): Check connection->is_initialized() instead. This
// requires re-working CreateFakeSpdySession(), though.
- DCHECK(connection->socket());
+ DCHECK(client_socket_handle->socket());
- connection_ = std::move(connection);
+ client_socket_handle_ = std::move(client_socket_handle);
+ socket_ = client_socket_handle_->socket();
+ client_socket_handle_->AddHigherLayeredPool(this);
- session_send_window_size_ = kDefaultInitialWindowSize;
- session_recv_window_size_ = kDefaultInitialWindowSize;
+ InitializeInternal(pool);
+}
- auto it = initial_settings_.find(spdy::SETTINGS_MAX_HEADER_LIST_SIZE);
- uint32_t spdy_max_header_list_size =
- (it == initial_settings_.end()) ? kSpdyMaxHeaderListSize : it->second;
- buffered_spdy_framer_ = std::make_unique<BufferedSpdyFramer>(
- spdy_max_header_list_size, net_log_, time_func_);
- buffered_spdy_framer_->set_visitor(this);
- buffered_spdy_framer_->set_debug_visitor(this);
- buffered_spdy_framer_->UpdateHeaderDecoderTableSize(max_header_table_size_);
+void SpdySession::InitializeWithSocket(
+ std::unique_ptr<StreamSocket> stream_socket,
+ const LoadTimingInfo::ConnectTiming& connect_timing,
+ SpdySessionPool* pool) {
+ DCHECK(!client_socket_handle_);
+ DCHECK(!owned_stream_socket_);
+ DCHECK(!socket_);
- net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_INITIALIZED,
- base::Bind(&NetLogSpdyInitializedCallback,
- connection_->socket()->NetLog().source()));
+ DCHECK(stream_socket);
- DCHECK_EQ(availability_state_, STATE_AVAILABLE);
- connection_->AddHigherLayeredPool(this);
- if (enable_sending_initial_data_)
- SendInitialData();
- pool_ = pool;
+ owned_stream_socket_ = std::move(stream_socket);
+ socket_ = owned_stream_socket_.get();
+ connect_timing_ =
+ std::make_unique<LoadTimingInfo::ConnectTiming>(connect_timing);
- // Bootstrap the read loop.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&SpdySession::PumpReadLoop, weak_factory_.GetWeakPtr(),
- READ_STATE_DO_READ, OK));
+ InitializeInternal(pool);
}
bool SpdySession::VerifyDomainAuthentication(const std::string& domain) const {
@@ -1283,15 +1276,15 @@ bool SpdySession::GetRemoteEndpoint(IPEndPoint* endpoint) {
}
bool SpdySession::GetSSLInfo(SSLInfo* ssl_info) const {
- return connection_->socket()->GetSSLInfo(ssl_info);
+ return socket_->GetSSLInfo(ssl_info);
}
bool SpdySession::WasAlpnNegotiated() const {
- return connection_->socket()->WasAlpnNegotiated();
+ return socket_->WasAlpnNegotiated();
}
NextProto SpdySession::GetNegotiatedProtocol() const {
- return connection_->socket()->GetNegotiatedProtocol();
+ return socket_->GetNegotiatedProtocol();
}
void SpdySession::SendStreamWindowUpdate(spdy::SpdyStreamId stream_id,
@@ -1388,9 +1381,8 @@ std::unique_ptr<base::Value> SpdySession::GetInfoAsValue() const {
dict->SetInteger("unclaimed_pushed_streams",
pool_->push_promise_index()->CountStreamsForSession(this));
- dict->SetString(
- "negotiated_protocol",
- NextProtoToString(connection_->socket()->GetNegotiatedProtocol()));
+ dict->SetString("negotiated_protocol",
+ NextProtoToString(socket_->GetNegotiatedProtocol()));
dict->SetInteger("error", error_on_close_);
dict->SetInteger("max_concurrent_streams", max_concurrent_streams_);
@@ -1411,26 +1403,50 @@ std::unique_ptr<base::Value> SpdySession::GetInfoAsValue() const {
}
bool SpdySession::IsReused() const {
- return buffered_spdy_framer_->frames_received() > 0 ||
- connection_->reuse_type() == ClientSocketHandle::UNUSED_IDLE;
+ if (buffered_spdy_framer_->frames_received() > 0)
+ return true;
+
+ // If there's no socket pool in use (i.e., |owned_stream_socket_| is
+ // non-null), then the SpdySession could only have been created with freshly
+ // connected socket, since canceling the H2 session request would have
+ // destroyed the socket.
+ return owned_stream_socket_ ||
+ client_socket_handle_->reuse_type() == ClientSocketHandle::UNUSED_IDLE;
}
bool SpdySession::GetLoadTimingInfo(spdy::SpdyStreamId stream_id,
LoadTimingInfo* load_timing_info) const {
- return connection_->GetLoadTimingInfo(stream_id != kFirstStreamId,
- load_timing_info);
+ if (client_socket_handle_) {
+ DCHECK(!connect_timing_);
+ return client_socket_handle_->GetLoadTimingInfo(stream_id != kFirstStreamId,
+ load_timing_info);
+ }
+
+ DCHECK(connect_timing_);
+ DCHECK(socket_);
+
+ // The socket is considered "fresh" (not reused) only for the first stream on
+ // a SPDY session. All others consider it reused, and don't return connection
+ // establishment timing information.
+ load_timing_info->socket_reused = (stream_id != kFirstStreamId);
+ if (!load_timing_info->socket_reused)
+ load_timing_info->connect_timing = *connect_timing_;
+
+ load_timing_info->socket_log_id = socket_->NetLog().source().id;
+
+ return true;
}
int SpdySession::GetPeerAddress(IPEndPoint* address) const {
- if (connection_->socket())
- return connection_->socket()->GetPeerAddress(address);
+ if (socket_)
+ return socket_->GetPeerAddress(address);
return ERR_SOCKET_NOT_CONNECTED;
}
int SpdySession::GetLocalAddress(IPEndPoint* address) const {
- if (connection_->socket())
- return connection_->socket()->GetLocalAddress(address);
+ if (socket_)
+ return socket_->GetLocalAddress(address);
return ERR_SOCKET_NOT_CONNECTED;
}
@@ -1523,7 +1539,7 @@ size_t SpdySession::DumpMemoryStats(StreamSocket::SocketMemoryStats* stats,
// TODO(xunjieli): Include |pending_create_stream_queues_| when WeakPtr is
// supported in memory_usage_estimator.h.
*is_session_active = is_active();
- connection_->DumpMemoryStats(stats);
+ socket_->DumpMemoryStats(stats);
// |connection_| is estimated in stats->total_size. |read_buffer_| is
// estimated in |read_buffer_size|. TODO(xunjieli): Make them use EMU().
@@ -1542,7 +1558,7 @@ size_t SpdySession::DumpMemoryStats(StreamSocket::SocketMemoryStats* stats,
}
bool SpdySession::ChangeSocketTag(const SocketTag& new_tag) {
- if (!IsAvailable() || !connection_->socket())
+ if (!IsAvailable() || !socket_)
return false;
// Changing the tag on the underlying socket will affect all streams,
@@ -1550,7 +1566,7 @@ bool SpdySession::ChangeSocketTag(const SocketTag& new_tag) {
if (is_active())
return false;
- connection_->socket()->ApplySocketTag(new_tag);
+ socket_->ApplySocketTag(new_tag);
SpdySessionKey new_key(spdy_session_key_.host_port_pair(),
spdy_session_key_.proxy_server(),
@@ -1567,6 +1583,40 @@ void SpdySession::RecordSpdyPushedStreamFateHistogram(
UMA_HISTOGRAM_ENUMERATION("Net.SpdyPushedStreamFate", value);
}
+void SpdySession::InitializeInternal(SpdySessionPool* pool) {
+ CHECK(!in_io_loop_);
+ DCHECK_EQ(availability_state_, STATE_AVAILABLE);
+ DCHECK_EQ(read_state_, READ_STATE_DO_READ);
+ DCHECK_EQ(write_state_, WRITE_STATE_IDLE);
+
+ session_send_window_size_ = kDefaultInitialWindowSize;
+ session_recv_window_size_ = kDefaultInitialWindowSize;
+
+ auto it = initial_settings_.find(spdy::SETTINGS_MAX_HEADER_LIST_SIZE);
+ uint32_t spdy_max_header_list_size =
+ (it == initial_settings_.end()) ? kSpdyMaxHeaderListSize : it->second;
+ buffered_spdy_framer_ = std::make_unique<BufferedSpdyFramer>(
+ spdy_max_header_list_size, net_log_, time_func_);
+ buffered_spdy_framer_->set_visitor(this);
+ buffered_spdy_framer_->set_debug_visitor(this);
+ buffered_spdy_framer_->UpdateHeaderDecoderTableSize(max_header_table_size_);
+
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_INITIALIZED,
+ base::BindRepeating(&NetLogSpdyInitializedCallback,
+ socket_->NetLog().source()));
+
+ DCHECK_EQ(availability_state_, STATE_AVAILABLE);
+ if (enable_sending_initial_data_)
+ SendInitialData();
+ pool_ = pool;
+
+ // Bootstrap the read loop.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindRepeating(&SpdySession::PumpReadLoop,
+ weak_factory_.GetWeakPtr(), READ_STATE_DO_READ, OK));
+}
+
// {,Try}CreateStream() can be called with |in_io_loop_| set if a stream is
// being created in response to another being closed due to received data.
@@ -1615,10 +1665,10 @@ int SpdySession::CreateStream(const SpdyStreamRequest& request,
if (availability_state_ == STATE_DRAINING)
return ERR_CONNECTION_CLOSED;
- DCHECK(connection_->socket());
+ DCHECK(socket_);
UMA_HISTOGRAM_BOOLEAN("Net.SpdySession.CreateStreamWithSocketConnected",
- connection_->socket()->IsConnected());
- if (!connection_->socket()->IsConnected()) {
+ socket_->IsConnected());
+ if (!socket_->IsConnected()) {
DoDrainSession(
ERR_CONNECTION_CLOSED,
"Tried to create SPDY stream for a closed socket connection.");
@@ -1711,8 +1761,8 @@ void SpdySession::ProcessPendingStreamRequests() {
// possible that the un-stalled stream will be stalled again if it loses.
// TODO(jgraettinger): Provide stronger ordering guarantees.
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&SpdySession::CompleteStreamRequest,
- weak_factory_.GetWeakPtr(), pending_request));
+ FROM_HERE, base::BindOnce(&SpdySession::CompleteStreamRequest,
+ weak_factory_.GetWeakPtr(), pending_request));
}
}
@@ -1867,8 +1917,8 @@ void SpdySession::TryCreatePushStream(spdy::SpdyStreamId stream_id,
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
- base::Bind(&SpdySession::CancelPushedStreamIfUnclaimed, GetWeakPtr(),
- stream_id),
+ base::BindOnce(&SpdySession::CancelPushedStreamIfUnclaimed, GetWeakPtr(),
+ stream_id),
base::TimeDelta::FromSeconds(kPushedStreamLifetimeSeconds));
net::NetworkTrafficAnnotationTag traffic_annotation =
@@ -1962,10 +2012,11 @@ void SpdySession::CloseActiveStreamIterator(ActiveStreamMap::iterator it,
DeleteStream(std::move(owned_stream), status);
- // If there are no active streams and the socket pool is stalled, close the
- // session to free up a socket slot.
- if (active_streams_.empty() && created_streams_.empty() &&
- connection_->IsPoolStalled()) {
+ // If the socket belongs to a socket pool, and there are no active streams,
+ // and the socket pool is stalled, then close the session to free up a socket
+ // slot.
+ if (client_socket_handle_ && active_streams_.empty() &&
+ created_streams_.empty() && client_socket_handle_->IsPoolStalled()) {
DoDrainSession(ERR_CONNECTION_CLOSED, "Closing idle connection.");
}
}
@@ -2095,8 +2146,8 @@ int SpdySession::DoReadLoop(ReadState expected_read_state, int result) {
time_func_() > yield_after_time)) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(&SpdySession::PumpReadLoop, weak_factory_.GetWeakPtr(),
- READ_STATE_DO_READ, OK));
+ base::BindOnce(&SpdySession::PumpReadLoop, weak_factory_.GetWeakPtr(),
+ READ_STATE_DO_READ, OK));
result = ERR_IO_PENDING;
break;
}
@@ -2112,13 +2163,12 @@ int SpdySession::DoRead() {
DCHECK(!read_buffer_);
CHECK(in_io_loop_);
- CHECK(connection_);
- CHECK(connection_->socket());
+ CHECK(socket_);
read_state_ = READ_STATE_DO_READ_COMPLETE;
int rv = ERR_READ_IF_READY_NOT_IMPLEMENTED;
read_buffer_ = base::MakeRefCounted<IOBuffer>(kReadBufferSize);
if (base::FeatureList::IsEnabled(Socket::kReadIfReadyExperiment)) {
- rv = connection_->socket()->ReadIfReady(
+ rv = socket_->ReadIfReady(
read_buffer_.get(), kReadBufferSize,
base::Bind(&SpdySession::PumpReadLoop, weak_factory_.GetWeakPtr(),
READ_STATE_DO_READ));
@@ -2130,7 +2180,7 @@ int SpdySession::DoRead() {
}
if (rv == ERR_READ_IF_READY_NOT_IMPLEMENTED) {
// Fallback to regular Read().
- return connection_->socket()->Read(
+ return socket_->Read(
read_buffer_.get(), kReadBufferSize,
base::Bind(&SpdySession::PumpReadLoop, weak_factory_.GetWeakPtr(),
READ_STATE_DO_READ_COMPLETE));
@@ -2201,8 +2251,8 @@ void SpdySession::MaybePostWriteLoop() {
write_state_ = WRITE_STATE_DO_WRITE;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(&SpdySession::PumpWriteLoop, weak_factory_.GetWeakPtr(),
- WRITE_STATE_DO_WRITE, OK));
+ base::BindOnce(&SpdySession::PumpWriteLoop, weak_factory_.GetWeakPtr(),
+ WRITE_STATE_DO_WRITE, OK));
}
}
@@ -2297,7 +2347,7 @@ int SpdySession::DoWrite() {
scoped_refptr<IOBuffer> write_io_buffer =
in_flight_write_->GetIOBufferForRemainingData();
- return connection_->socket()->Write(
+ return socket_->Write(
write_io_buffer.get(), in_flight_write_->GetRemainingSize(),
base::Bind(&SpdySession::PumpWriteLoop, weak_factory_.GetWeakPtr(),
WRITE_STATE_DO_WRITE_COMPLETE),
@@ -2553,8 +2603,9 @@ void SpdySession::PlanToCheckPingStatus() {
check_ping_status_pending_ = true;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&SpdySession::CheckPingStatus,
- weak_factory_.GetWeakPtr(), time_func_()),
+ FROM_HERE,
+ base::BindOnce(&SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(),
+ time_func_()),
hung_interval_);
}
@@ -2579,8 +2630,9 @@ void SpdySession::CheckPingStatus(base::TimeTicks last_check_time) {
// Check the status of connection after a delay.
const base::TimeDelta delay = last_read_time_ + hung_interval_ - now;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&SpdySession::CheckPingStatus,
- weak_factory_.GetWeakPtr(), now),
+ FROM_HERE,
+ base::BindOnce(&SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(),
+ now),
delay);
}
@@ -3114,7 +3166,7 @@ void SpdySession::OnWindowUpdate(spdy::SpdyStreamId stream_id,
DoDrainSession(
ERR_SPDY_PROTOCOL_ERROR,
"Received WINDOW_UPDATE with an invalid delta_window_size " +
- base::IntToString(delta_window_size));
+ base::NumberToString(delta_window_size));
return;
}
@@ -3353,9 +3405,9 @@ void SpdySession::IncreaseSendWindowSize(int delta_window_size) {
DoDrainSession(
ERR_SPDY_PROTOCOL_ERROR,
"Received WINDOW_UPDATE [delta: " +
- base::IntToString(delta_window_size) +
+ base::NumberToString(delta_window_size) +
"] for session overflows session_send_window_size_ [current: " +
- base::IntToString(session_send_window_size_) + "]");
+ base::NumberToString(session_send_window_size_) + "]");
return;
}
@@ -3432,9 +3484,10 @@ void SpdySession::DecreaseRecvWindowSize(int32_t delta_window_size) {
RecordProtocolErrorHistogram(PROTOCOL_ERROR_RECEIVE_WINDOW_VIOLATION);
DoDrainSession(
ERR_SPDY_FLOW_CONTROL_ERROR,
- "delta_window_size is " + base::IntToString(delta_window_size) +
+ "delta_window_size is " + base::NumberToString(delta_window_size) +
" in DecreaseRecvWindowSize, which is larger than the receive " +
- "window size of " + base::IntToString(session_recv_window_size_));
+ "window size of " +
+ base::NumberToString(session_recv_window_size_));
return;
}
diff --git a/chromium/net/spdy/spdy_session.h b/chromium/net/spdy/spdy_session.h
index 2f846ffdf36..235c85a2181 100644
--- a/chromium/net/spdy/spdy_session.h
+++ b/chromium/net/spdy/spdy_session.h
@@ -27,11 +27,11 @@
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/load_states.h"
+#include "net/base/load_timing_info.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
#include "net/log/net_log_source.h"
-#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool.h"
#include "net/socket/next_proto.h"
#include "net/socket/ssl_client_socket.h"
@@ -86,7 +86,6 @@ const int kYieldAfterDurationMilliseconds = 20;
const spdy::SpdyStreamId kFirstStreamId = 1;
const spdy::SpdyStreamId kLastStreamId = 0x7fffffff;
-struct LoadTimingInfo;
class NetLog;
class NetworkQualityEstimator;
class SpdyStream;
@@ -179,7 +178,8 @@ enum class SpdyPushedStreamFate {
kAcceptedMatchingVary = 18,
kPushDisabled = 19,
kAlreadyInCache = 20,
- kMaxValue = kAlreadyInCache
+ kUnsupportedStatusCode = 21,
+ kMaxValue = kUnsupportedStatusCode
};
// If these compile asserts fail then SpdyProtocolErrorDetails needs
@@ -348,10 +348,19 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// |pool| is the SpdySessionPool that owns us. Its lifetime must
// strictly be greater than |this|.
//
- // The session begins reading from |connection| on a subsequent event loop
- // iteration, so the SpdySession may close immediately afterwards if the first
- // read of |connection| fails.
- void InitializeWithSocket(std::unique_ptr<ClientSocketHandle> connection,
+ // The session begins reading from |client_socket_handle| on a subsequent
+ // event loop iteration, so the SpdySession may close immediately afterwards
+ // if the first read of |client_socket_handle| fails.
+ void InitializeWithSocketHandle(
+ std::unique_ptr<ClientSocketHandle> client_socket_handle,
+ SpdySessionPool* pool);
+
+ // Just like InitializeWithSocketHandle(), but for use when the session is not
+ // on top of a socket pool, but instead directly on top of a socket, which the
+ // session has sole ownership of, and is responsible for deleting directly
+ // itself.
+ void InitializeWithSocket(std::unique_ptr<StreamSocket> stream_socket,
+ const LoadTimingInfo::ConnectTiming& connect_timing,
SpdySessionPool* pool);
// Check to see if this SPDY session can support an additional domain.
@@ -476,9 +485,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
// Returns true if the underlying transport socket ever had any reads or
// writes.
- bool WasEverUsed() const {
- return connection_->socket()->WasEverUsed();
- }
+ bool WasEverUsed() const { return socket_->WasEverUsed(); }
// Returns the load timing information from the perspective of the given
// stream. If it's not the first stream, the connection is considered reused
@@ -595,6 +602,9 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
WRITE_STATE_DO_WRITE_COMPLETE,
};
+ // Has the shared logic for the other two Initialize methods that call it.
+ void InitializeInternal(SpdySessionPool* pool);
+
// Called by SpdyStreamRequest to start a request to create a
// stream. If OK is returned, then |stream| will be filled in with a
// valid stream. If ERR_IO_PENDING is returned, then
@@ -937,8 +947,18 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
TransportSecurityState* transport_security_state_;
SSLConfigService* ssl_config_service_;
- // The socket handle for this session.
- std::unique_ptr<ClientSocketHandle> connection_;
+ // One of these two owns the socket for this session, which is stored in
+ // |socket_|. If |client_socket_handle_| is non-null, this session is on top
+ // of a socket in a socket pool. If |owned_stream_socket_| is non-null, this
+ // session is directly on top of a socket, which is not in a socket pool.
+ std::unique_ptr<ClientSocketHandle> client_socket_handle_;
+ std::unique_ptr<StreamSocket> owned_stream_socket_;
+
+ // This is non-null only if |owned_stream_socket_| is non-null.
+ std::unique_ptr<LoadTimingInfo::ConnectTiming> connect_timing_;
+
+ // The socket for this session.
+ StreamSocket* socket_;
// The read buffer used to read data from the socket.
// Non-null if there is a Read() pending.
diff --git a/chromium/net/spdy/spdy_session_fuzzer.cc b/chromium/net/spdy/spdy_session_fuzzer.cc
index 93a942911a7..4b92029986c 100644
--- a/chromium/net/spdy/spdy_session_fuzzer.cc
+++ b/chromium/net/spdy/spdy_session_fuzzer.cc
@@ -12,7 +12,6 @@
#include "net/cert/x509_certificate.h"
#include "net/log/net_log_source.h"
#include "net/log/test_net_log.h"
-#include "net/socket/client_socket_handle.h"
#include "net/socket/fuzzed_socket_factory.h"
#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
@@ -65,7 +64,7 @@ class FuzzedSocketFactoryWithMockSSLData : public FuzzedSocketFactory {
void AddSSLSocketDataProvider(SSLSocketDataProvider* socket);
std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
- std::unique_ptr<ClientSocketHandle> transport_socket,
+ std::unique_ptr<StreamSocket> nested_socket,
const HostPortPair& host_and_port,
const SSLConfig& ssl_config,
const SSLClientSocketContext& context) override;
@@ -85,11 +84,11 @@ void FuzzedSocketFactoryWithMockSSLData::AddSSLSocketDataProvider(
std::unique_ptr<SSLClientSocket>
FuzzedSocketFactoryWithMockSSLData::CreateSSLClientSocket(
- std::unique_ptr<ClientSocketHandle> transport_socket,
+ std::unique_ptr<StreamSocket> nested_socket,
const HostPortPair& host_and_port,
const SSLConfig& ssl_config,
const SSLClientSocketContext& context) {
- return std::make_unique<MockSSLClientSocket>(std::move(transport_socket),
+ return std::make_unique<MockSSLClientSocket>(std::move(nested_socket),
host_and_port, ssl_config,
mock_ssl_data_.GetNext());
}
diff --git a/chromium/net/spdy/spdy_session_pool.cc b/chromium/net/spdy/spdy_session_pool.cc
index 27e4f5635a3..c252a15400a 100644
--- a/chromium/net/spdy/spdy_session_pool.cc
+++ b/chromium/net/spdy/spdy_session_pool.cc
@@ -7,10 +7,12 @@
#include <algorithm>
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_usage_estimator.h"
#include "base/trace_event/process_memory_dump.h"
@@ -19,6 +21,8 @@
#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/trace_constants.h"
+#include "net/dns/host_resolver.h"
+#include "net/dns/host_resolver_source.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_stream_request.h"
@@ -98,48 +102,38 @@ SpdySessionPool::~SpdySessionPool() {
CertDatabase::GetInstance()->RemoveObserver(this);
}
-base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket(
+base::WeakPtr<SpdySession>
+SpdySessionPool::CreateAvailableSessionFromSocketHandle(
const SpdySessionKey& key,
bool is_trusted_proxy,
- std::unique_ptr<ClientSocketHandle> connection,
+ std::unique_ptr<ClientSocketHandle> client_socket_handle,
const NetLogWithSource& net_log) {
TRACE_EVENT0(NetTracingCategory(),
- "SpdySessionPool::CreateAvailableSessionFromSocket");
-
- UMA_HISTOGRAM_ENUMERATION(
- "Net.SpdySessionGet", IMPORTED_FROM_SOCKET, SPDY_SESSION_GET_MAX);
-
- auto new_session = std::make_unique<SpdySession>(
- key, http_server_properties_, transport_security_state_,
- ssl_config_service_, quic_supported_versions_,
- enable_sending_initial_data_, enable_ping_based_connection_checking_,
- support_ietf_format_quic_altsvc_, is_trusted_proxy,
- session_max_recv_window_size_, initial_settings_, greased_http2_frame_,
- time_func_, push_delegate_, network_quality_estimator_,
- net_log.net_log());
+ "SpdySessionPool::CreateAvailableSessionFromSocketHandle");
- new_session->InitializeWithSocket(std::move(connection), this);
+ std::unique_ptr<SpdySession> new_session =
+ CreateSession(key, is_trusted_proxy, net_log.net_log());
+ new_session->InitializeWithSocketHandle(std::move(client_socket_handle),
+ this);
+ return InsertSession(key, std::move(new_session), net_log);
+}
- base::WeakPtr<SpdySession> available_session = new_session->GetWeakPtr();
- sessions_.insert(new_session.release());
- MapKeyToAvailableSession(key, available_session);
+base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket(
+ const SpdySessionKey& key,
+ bool is_trusted_proxy,
+ std::unique_ptr<StreamSocket> socket_stream,
+ const LoadTimingInfo::ConnectTiming& connect_timing,
+ const NetLogWithSource& net_log) {
+ TRACE_EVENT0(NetTracingCategory(),
+ "SpdySessionPool::CreateAvailableSessionFromSocket");
- net_log.AddEvent(
- NetLogEventType::HTTP2_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET,
- available_session->net_log().source().ToEventParametersCallback());
+ std::unique_ptr<SpdySession> new_session =
+ CreateSession(key, is_trusted_proxy, net_log.net_log());
- // Look up the IP address for this session so that we can match
- // future sessions (potentially to different domains) which can
- // potentially be pooled with this one. Because GetPeerAddress()
- // reports the proxy's address instead of the origin server, check
- // to see if this is a direct connection.
- if (key.proxy_server().is_direct()) {
- IPEndPoint address;
- if (available_session->GetPeerAddress(&address) == OK)
- aliases_.insert(AliasMap::value_type(address, key));
- }
+ new_session->InitializeWithSocket(std::move(socket_stream), connect_timing,
+ this);
- return available_session;
+ return InsertSession(key, std::move(new_session), net_log);
}
base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession(
@@ -183,18 +177,19 @@ base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession(
return base::WeakPtr<SpdySession>();
// Look up IP addresses from resolver cache.
- HostResolver::RequestInfo resolve_info(key.host_port_pair());
- AddressList addresses;
- int rv = resolver_->ResolveFromCache(resolve_info, &addresses, net_log);
+ HostResolver::ResolveHostParameters parameters;
+ parameters.source = HostResolverSource::LOCAL_ONLY;
+ std::unique_ptr<HostResolver::ResolveHostRequest> request =
+ resolver_->CreateRequest(key.host_port_pair(), net_log, parameters);
+
+ int rv = request->Start(base::BindOnce([](int error) { NOTREACHED(); }));
DCHECK_NE(rv, ERR_IO_PENDING);
if (rv != OK)
return base::WeakPtr<SpdySession>();
// Check if we have a session through a domain alias.
- for (AddressList::const_iterator address_it = addresses.begin();
- address_it != addresses.end();
- ++address_it) {
- auto range = aliases_.equal_range(*address_it);
+ for (const auto& address : request->GetAddressResults().value().endpoints()) {
+ auto range = aliases_.equal_range(address);
for (auto alias_it = range.first; alias_it != range.second; ++alias_it) {
// We found an alias.
const SpdySessionKey& alias_key = alias_it->second;
@@ -602,4 +597,46 @@ void SpdySessionPool::CloseCurrentSessionsHelper(Error error,
}
}
+std::unique_ptr<SpdySession> SpdySessionPool::CreateSession(
+ const SpdySessionKey& key,
+ bool is_trusted_proxy,
+ NetLog* net_log) {
+ UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", IMPORTED_FROM_SOCKET,
+ SPDY_SESSION_GET_MAX);
+
+ return std::make_unique<SpdySession>(
+ key, http_server_properties_, transport_security_state_,
+ ssl_config_service_, quic_supported_versions_,
+ enable_sending_initial_data_, enable_ping_based_connection_checking_,
+ support_ietf_format_quic_altsvc_, is_trusted_proxy,
+ session_max_recv_window_size_, initial_settings_, greased_http2_frame_,
+ time_func_, push_delegate_, network_quality_estimator_, net_log);
+}
+
+base::WeakPtr<SpdySession> SpdySessionPool::InsertSession(
+ const SpdySessionKey& key,
+ std::unique_ptr<SpdySession> new_session,
+ const NetLogWithSource& source_net_log) {
+ base::WeakPtr<SpdySession> available_session = new_session->GetWeakPtr();
+ sessions_.insert(new_session.release());
+ MapKeyToAvailableSession(key, available_session);
+
+ source_net_log.AddEvent(
+ NetLogEventType::HTTP2_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET,
+ available_session->net_log().source().ToEventParametersCallback());
+
+ // Look up the IP address for this session so that we can match
+ // future sessions (potentially to different domains) which can
+ // potentially be pooled with this one. Because GetPeerAddress()
+ // reports the proxy's address instead of the origin server, check
+ // to see if this is a direct connection.
+ if (key.proxy_server().is_direct()) {
+ IPEndPoint address;
+ if (available_session->GetPeerAddress(&address) == OK)
+ aliases_.insert(AliasMap::value_type(address, key));
+ }
+
+ return available_session;
+}
+
} // namespace net
diff --git a/chromium/net/spdy/spdy_session_pool.h b/chromium/net/spdy/spdy_session_pool.h
index 4ff38a3f8a8..755d0cd8392 100644
--- a/chromium/net/spdy/spdy_session_pool.h
+++ b/chromium/net/spdy/spdy_session_pool.h
@@ -20,6 +20,7 @@
#include "base/optional.h"
#include "net/base/host_port_pair.h"
#include "net/base/ip_endpoint.h"
+#include "net/base/load_timing_info.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
@@ -48,6 +49,7 @@ class HttpStreamRequest;
class NetLogWithSource;
class NetworkQualityEstimator;
class SpdySession;
+class StreamSocket;
class TransportSecurityState;
// This is a very simple pool for open SpdySessions.
@@ -95,12 +97,28 @@ class NET_EXPORT SpdySessionPool
// not already be a session for the given key.
//
// Returns the new SpdySession. Note that the SpdySession begins reading from
- // |connection| on a subsequent event loop iteration, so it may be closed
- // immediately afterwards if the first read of |connection| fails.
+ // |client_socket_handle| on a subsequent event loop iteration, so it may be
+ // closed immediately afterwards if the first read of |client_socket_handle|
+ // fails.
+ base::WeakPtr<SpdySession> CreateAvailableSessionFromSocketHandle(
+ const SpdySessionKey& key,
+ bool is_trusted_proxy,
+ std::unique_ptr<ClientSocketHandle> client_socket_handle,
+ const NetLogWithSource& net_log);
+
+ // Just like the above method, except it takes a SocketStream instead of a
+ // ClientSocketHandle, and separate connect timing information. When this
+ // constructor is used, there is no socket pool beneath the SpdySession.
+ // Instead, the session takes exclusive ownership of the underting socket, and
+ // destroying the session will directly destroy the socket, as opposed to
+ // disconnected it and then returning it to the socket pool. This is intended
+ // for use with H2 proxies, which are layered beneath the socket pools and
+ // can have sockets above them for tunnels, which are put in a socket pool.
base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket(
const SpdySessionKey& key,
bool is_trusted_proxy,
- std::unique_ptr<ClientSocketHandle> connection,
+ std::unique_ptr<StreamSocket> socket_stream,
+ const LoadTimingInfo::ConnectTiming& connect_timing,
const NetLogWithSource& net_log);
// If there is an available session for |key|, return it.
@@ -254,6 +272,18 @@ class NET_EXPORT SpdySessionPool
const std::string& description,
bool idle_only);
+ // Creates a new session. The session must be initialized before
+ // InsertSession() is invoked.
+ std::unique_ptr<SpdySession> CreateSession(const SpdySessionKey& key,
+ bool is_trusted_proxy,
+ NetLog* net_log);
+ // Adds a new session previously created with CreateSession to the pool.
+ // |source_net_log| is the NetLog for the object that created the session.
+ base::WeakPtr<SpdySession> InsertSession(
+ const SpdySessionKey& key,
+ std::unique_ptr<SpdySession> new_session,
+ const NetLogWithSource& source_net_log);
+
HttpServerProperties* http_server_properties_;
TransportSecurityState* transport_security_state_;
diff --git a/chromium/net/spdy/spdy_session_pool_unittest.cc b/chromium/net/spdy/spdy_session_pool_unittest.cc
index 36461432fb4..d294ff9e0d8 100644
--- a/chromium/net/spdy/spdy_session_pool_unittest.cc
+++ b/chromium/net/spdy/spdy_session_pool_unittest.cc
@@ -15,7 +15,6 @@
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/traced_value.h"
#include "build/build_config.h"
-#include "net/base/completion_once_callback.h"
#include "net/dns/host_cache.h"
#include "net/http/http_network_session.h"
#include "net/log/net_log_with_source.h"
@@ -29,6 +28,7 @@
#include "net/spdy/spdy_test_util_common.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
+#include "net/test/test_certificate_data.h"
#include "net/test/test_data_directory.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -70,6 +70,7 @@ class SpdySessionPoolTest : public TestWithScopedTaskEnvironment {
}
void RunIPPoolingTest(SpdyPoolCloseSessionsType close_sessions_type);
+ void RunIPPoolingDisabledTest(SSLSocketDataProvider* ssl);
size_t num_active_streams(base::WeakPtr<SpdySession> session) {
return session->active_streams_.size();
@@ -343,7 +344,6 @@ void SpdySessionPoolTest::RunIPPoolingTest(
std::string name;
std::string iplist;
SpdySessionKey key;
- AddressList addresses;
} test_hosts[] = {
{"http://www.example.org", "www.example.org",
"192.0.2.33,192.168.0.1,192.168.0.5"},
@@ -360,11 +360,8 @@ void SpdySessionPoolTest::RunIPPoolingTest(
// This test requires that the HostResolver cache be populated. Normal
// code would have done this already, but we do it manually.
- HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
- std::unique_ptr<HostResolver::Request> request;
- int rv = session_deps_.host_resolver->Resolve(
- info, DEFAULT_PRIORITY, &test_hosts[i].addresses,
- CompletionOnceCallback(), &request, NetLogWithSource());
+ int rv = session_deps_.host_resolver->LoadIntoCache(
+ HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
EXPECT_THAT(rv, IsOk());
// Setup a SpdySessionKey.
@@ -519,6 +516,54 @@ void SpdySessionPoolTest::RunIPPoolingTest(
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
}
+void SpdySessionPoolTest::RunIPPoolingDisabledTest(SSLSocketDataProvider* ssl) {
+ const int kTestPort = 80;
+ struct TestHosts {
+ std::string name;
+ std::string iplist;
+ SpdySessionKey key;
+ } test_hosts[] = {
+ {"www.webkit.org", "192.0.2.33,192.168.0.1,192.168.0.5"},
+ {"js.webkit.com", "192.168.0.4,192.168.0.1,192.0.2.33"},
+ };
+
+ session_deps_.host_resolver->set_synchronous_mode(true);
+ for (size_t i = 0; i < base::size(test_hosts); i++) {
+ session_deps_.host_resolver->rules()->AddIPLiteralRule(
+ test_hosts[i].name, test_hosts[i].iplist, std::string());
+
+ // This test requires that the HostResolver cache be populated. Normal
+ // code would have done this already, but we do it manually.
+ int rv = session_deps_.host_resolver->LoadIntoCache(
+ HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
+ EXPECT_THAT(rv, IsOk());
+
+ // Setup a SpdySessionKey
+ test_hosts[i].key =
+ SpdySessionKey(HostPortPair(test_hosts[i].name, kTestPort),
+ ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
+ SpdySessionKey::IsProxySession::kFalse, SocketTag());
+ }
+
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING),
+ };
+ StaticSocketDataProvider data(reads, base::span<MockWrite>());
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(ssl);
+
+ CreateNetworkSession();
+
+ base::WeakPtr<SpdySession> spdy_session = CreateSpdySession(
+ http_session_.get(), test_hosts[0].key, NetLogWithSource());
+ EXPECT_TRUE(
+ HasSpdySession(http_session_->spdy_session_pool(), test_hosts[0].key));
+ EXPECT_FALSE(
+ HasSpdySession(http_session_->spdy_session_pool(), test_hosts[1].key));
+
+ http_session_->spdy_session_pool()->CloseAllSessions();
+}
+
TEST_F(SpdySessionPoolTest, IPPooling) {
RunIPPoolingTest(SPDY_POOL_CLOSE_SESSIONS_MANUALLY);
}
@@ -539,7 +584,6 @@ TEST_F(SpdySessionPoolTest, IPPoolingNetLog) {
std::string name;
std::string iplist;
SpdySessionKey key;
- AddressList addresses;
} test_hosts[] = {
{"www.example.org", "192.168.0.1"}, {"mail.example.org", "192.168.0.1"},
};
@@ -550,11 +594,8 @@ TEST_F(SpdySessionPoolTest, IPPoolingNetLog) {
session_deps_.host_resolver->rules()->AddIPLiteralRule(
test_hosts[i].name, test_hosts[i].iplist, std::string());
- HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
- std::unique_ptr<HostResolver::Request> request;
- int rv = session_deps_.host_resolver->Resolve(
- info, DEFAULT_PRIORITY, &test_hosts[i].addresses,
- CompletionOnceCallback(), &request, NetLogWithSource());
+ int rv = session_deps_.host_resolver->LoadIntoCache(
+ HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
EXPECT_THAT(rv, IsOk());
test_hosts[i].key =
@@ -621,7 +662,6 @@ TEST_F(SpdySessionPoolTest, IPPoolingDisabled) {
std::string name;
std::string iplist;
SpdySessionKey key;
- AddressList addresses;
} test_hosts[] = {
{"www.example.org", "192.168.0.1"}, {"mail.example.org", "192.168.0.1"},
};
@@ -632,11 +672,8 @@ TEST_F(SpdySessionPoolTest, IPPoolingDisabled) {
session_deps_.host_resolver->rules()->AddIPLiteralRule(
test_hosts[i].name, test_hosts[i].iplist, std::string());
- HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
- std::unique_ptr<HostResolver::Request> request;
- int rv = session_deps_.host_resolver->Resolve(
- info, DEFAULT_PRIORITY, &test_hosts[i].addresses,
- CompletionOnceCallback(), &request, NetLogWithSource());
+ int rv = session_deps_.host_resolver->LoadIntoCache(
+ HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
EXPECT_THAT(rv, IsOk());
test_hosts[i].key =
@@ -688,6 +725,26 @@ TEST_F(SpdySessionPoolTest, IPPoolingDisabled) {
EXPECT_NE(session0.get(), session1.get());
}
+// Verifies that an SSL connection with client authentication disables SPDY IP
+// pooling.
+TEST_F(SpdySessionPoolTest, IPPoolingClientCert) {
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ ssl.ssl_info.cert = X509Certificate::CreateFromBytes(
+ reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der));
+ ASSERT_TRUE(ssl.ssl_info.cert);
+ ssl.ssl_info.client_cert_sent = true;
+ ssl.next_proto = kProtoHTTP2;
+ RunIPPoolingDisabledTest(&ssl);
+}
+
+// Verifies that an SSL connection with channel ID disables SPDY IP pooling.
+TEST_F(SpdySessionPoolTest, IPPoolingChannelID) {
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ ssl.ssl_info.channel_id_sent = true;
+ ssl.next_proto = kProtoHTTP2;
+ RunIPPoolingDisabledTest(&ssl);
+}
+
// Construct a Pool with SpdySessions in various availability states. Simulate
// an IP address change. Ensure sessions gracefully shut down. Regression test
// for crbug.com/379469.
@@ -929,7 +986,7 @@ class SpdySessionMemoryDumpTest
public testing::WithParamInterface<
base::trace_event::MemoryDumpLevelOfDetail> {};
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
SpdySessionMemoryDumpTest,
::testing::Values(base::trace_event::MemoryDumpLevelOfDetail::DETAILED,
@@ -990,7 +1047,6 @@ TEST_F(SpdySessionPoolTest, FindAvailableSessionForWebSocket) {
std::string name;
std::string iplist;
SpdySessionKey key;
- AddressList addresses;
} test_hosts[] = {
{"www.example.org", "192.168.0.1"}, {"mail.example.org", "192.168.0.1"},
};
@@ -1001,11 +1057,8 @@ TEST_F(SpdySessionPoolTest, FindAvailableSessionForWebSocket) {
session_deps_.host_resolver->rules()->AddIPLiteralRule(
test_hosts[i].name, test_hosts[i].iplist, std::string());
- HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
- std::unique_ptr<HostResolver::Request> request;
- int rv = session_deps_.host_resolver->Resolve(
- info, DEFAULT_PRIORITY, &test_hosts[i].addresses,
- CompletionOnceCallback(), &request, NetLogWithSource());
+ int rv = session_deps_.host_resolver->LoadIntoCache(
+ HostPortPair(test_hosts[i].name, kTestPort), base::nullopt);
EXPECT_THAT(rv, IsOk());
test_hosts[i].key =
diff --git a/chromium/net/spdy/spdy_session_unittest.cc b/chromium/net/spdy/spdy_session_unittest.cc
index 878560da271..0b86dc391c4 100644
--- a/chromium/net/spdy/spdy_session_unittest.cc
+++ b/chromium/net/spdy/spdy_session_unittest.cc
@@ -134,8 +134,8 @@ class SpdySessionTest : public PlatformTest, public WithScopedTaskEnvironment {
protected:
SpdySessionTest()
- : SpdySessionTest(
- base::test::ScopedTaskEnvironment::MainThreadType::IO){};
+ : SpdySessionTest(base::test::ScopedTaskEnvironment::MainThreadType::IO) {
+ }
explicit SpdySessionTest(
base::test::ScopedTaskEnvironment::MainThreadType type)
@@ -368,7 +368,7 @@ class SpdySessionTestWithMockTime : public SpdySessionTest {
protected:
SpdySessionTestWithMockTime()
: SpdySessionTest(
- base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME){};
+ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {}
};
// Try to create a SPDY session that will fail during
@@ -950,6 +950,71 @@ TEST_F(SpdySessionTest, HeadersAfterGoAway) {
histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}
+// Regression test for https://crbug.com/903737: pushed response with status
+// code different from 2xx or 3xx or 416 should be rejected.
+TEST_F(SpdySessionTest, UnsupportedPushedStatusCode) {
+ base::HistogramTester histogram_tester;
+
+ spdy::SpdyHeaderBlock push_promise_header_block;
+ push_promise_header_block[spdy::kHttp2MethodHeader] = "GET";
+ spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_promise_header_block);
+ spdy::SpdySerializedFrame push_promise_frame(
+ spdy_util_.ConstructSpdyPushPromise(
+ 1, 2, std::move(push_promise_header_block)));
+
+ spdy::SpdyHeaderBlock response_header_block;
+ response_header_block[spdy::kHttp2StatusHeader] = "401";
+ spdy::SpdySerializedFrame response_headers_frame(
+ spdy_util_.ConstructSpdyResponseHeaders(
+ 2, std::move(response_header_block), false));
+
+ MockRead reads[] = {
+ MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(push_promise_frame, 2),
+ CreateMockRead(response_headers_frame, 4), MockRead(ASYNC, 0, 6)};
+
+ spdy::SpdySerializedFrame req(
+ spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
+ spdy::SpdySerializedFrame priority(
+ spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
+ spdy::SpdySerializedFrame rst(
+ spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
+
+ MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
+ CreateMockWrite(rst, 5)};
+
+ SequencedSocketData data(reads, writes);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ AddSSLSocketData();
+
+ CreateNetworkSession();
+ CreateSpdySession();
+
+ base::WeakPtr<SpdyStream> spdy_stream =
+ CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
+ test_url_, MEDIUM, NetLogWithSource());
+ test::StreamDelegateDoNothing delegate(spdy_stream);
+ spdy_stream->SetDelegate(&delegate);
+
+ spdy::SpdyHeaderBlock headers(
+ spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
+ spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1u, spdy_stream->stream_id());
+ EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
+
+ // Read the PUSH_PROMISE and HEADERS frames.
+ data.Resume();
+ base::RunLoop().RunUntilIdle();
+
+ histogram_tester.ExpectBucketCount(
+ "Net.SpdyPushedStreamFate",
+ static_cast<int>(SpdyPushedStreamFate::kUnsupportedStatusCode), 1);
+ histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
+}
+
// A session observing a network change with active streams should close
// when the last active stream is closed.
TEST_F(SpdySessionTest, NetworkChangeWithActiveStreams) {
@@ -1076,7 +1141,7 @@ TEST_F(SpdySessionTestWithMockTime, ClientPing) {
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
- EXPECT_FALSE(MainThreadHasPendingTask());
+ EXPECT_TRUE(MainThreadIsIdle());
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
EXPECT_FALSE(session_);
EXPECT_FALSE(spdy_stream1);
@@ -1808,7 +1873,7 @@ TEST_F(SpdySessionTestWithMockTime, FailedPing) {
// Since no response to PING has been received,
// CheckPingStatus() closes the connection.
- EXPECT_FALSE(MainThreadHasPendingTask());
+ EXPECT_TRUE(MainThreadIsIdle());
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
EXPECT_FALSE(session_);
EXPECT_FALSE(spdy_stream1);
@@ -3470,9 +3535,8 @@ TEST_F(SpdySessionTest, CloseOneIdleConnection) {
CreateNetworkSession();
- TransportClientSocketPool* pool =
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL);
+ TransportClientSocketPool* pool = http_session_->GetSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct());
// Create an idle SPDY session.
CreateSpdySession();
@@ -3491,7 +3555,9 @@ TEST_F(SpdySessionTest, CloseOneIdleConnection) {
CreateFromTransportSocketParams(params2),
DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
- callback2.callback(), pool, NetLogWithSource()));
+ callback2.callback(),
+ ClientSocketPool::ProxyAuthCallback(), pool,
+ NetLogWithSource()));
EXPECT_TRUE(pool->IsStalled());
// The socket pool should close the connection asynchronously and establish a
@@ -3530,9 +3596,8 @@ TEST_F(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
CreateNetworkSession();
- TransportClientSocketPool* pool =
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL);
+ TransportClientSocketPool* pool = http_session_->GetSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct());
// Create an idle SPDY session.
SpdySessionKey key1(HostPortPair("www.example.org", 80),
@@ -3546,14 +3611,10 @@ TEST_F(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
SpdySessionKey key2(HostPortPair("mail.example.org", 80),
ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
SpdySessionKey::IsProxySession::kFalse, SocketTag());
- HostResolver::RequestInfo info(key2.host_port_pair());
- AddressList addresses;
- std::unique_ptr<HostResolver::Request> request;
// Pre-populate the DNS cache, since a cached entry is required in order to
// create the alias.
- int rv = session_deps_.host_resolver->Resolve(
- info, DEFAULT_PRIORITY, &addresses, CompletionOnceCallback(), &request,
- NetLogWithSource());
+ int rv = session_deps_.host_resolver->LoadIntoCache(key2.host_port_pair(),
+ base::nullopt);
EXPECT_THAT(rv, IsOk());
// Get a session for |key2|, which should return the session created earlier.
@@ -3577,7 +3638,9 @@ TEST_F(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
CreateFromTransportSocketParams(params3),
DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
- callback3.callback(), pool, NetLogWithSource()));
+ callback3.callback(),
+ ClientSocketPool::ProxyAuthCallback(), pool,
+ NetLogWithSource()));
EXPECT_TRUE(pool->IsStalled());
// The socket pool should close the connection asynchronously and establish a
@@ -3619,9 +3682,8 @@ TEST_F(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
CreateNetworkSession();
- TransportClientSocketPool* pool =
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL);
+ TransportClientSocketPool* pool = http_session_->GetSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct());
// Create a SPDY session.
CreateSpdySession();
@@ -3657,7 +3719,9 @@ TEST_F(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
CreateFromTransportSocketParams(params2),
DEFAULT_PRIORITY, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
- callback2.callback(), pool, NetLogWithSource()));
+ callback2.callback(),
+ ClientSocketPool::ProxyAuthCallback(), pool,
+ NetLogWithSource()));
EXPECT_TRUE(pool->IsStalled());
// Running the message loop should cause the socket pool to ask the SPDY
@@ -6066,11 +6130,11 @@ class SpdySessionReadIfReadyTest
base::test::ScopedFeatureList scoped_feature_list_;
};
-INSTANTIATE_TEST_CASE_P(/* no prefix */,
- SpdySessionReadIfReadyTest,
- testing::Values(READ_IF_READY_ENABLED_SUPPORTED,
- READ_IF_READY_ENABLED_NOT_SUPPORTED,
- READ_IF_READY_DISABLED));
+INSTANTIATE_TEST_SUITE_P(/* no prefix */,
+ SpdySessionReadIfReadyTest,
+ testing::Values(READ_IF_READY_ENABLED_SUPPORTED,
+ READ_IF_READY_ENABLED_NOT_SUPPORTED,
+ READ_IF_READY_DISABLED));
// Tests basic functionality of ReadIfReady() when it is enabled or disabled.
TEST_P(SpdySessionReadIfReadyTest, ReadIfReady) {
diff --git a/chromium/net/spdy/spdy_stream.cc b/chromium/net/spdy/spdy_stream.cc
index 804ee2c0677..f871d64ed78 100644
--- a/chromium/net/spdy/spdy_stream.cc
+++ b/chromium/net/spdy/spdy_stream.cc
@@ -20,6 +20,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_usage_estimator.h"
#include "base/values.h"
+#include "net/base/load_timing_info.h"
#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
@@ -105,7 +106,6 @@ SpdyStream::SpdyStream(SpdyStreamType type,
request_time_(base::Time::Now()),
response_state_(READY_FOR_HEADERS),
io_state_(STATE_IDLE),
- response_status_(OK),
net_log_(net_log),
raw_received_bytes_(0),
raw_sent_bytes_(0),
@@ -138,7 +138,8 @@ void SpdyStream::SetDelegate(Delegate* delegate) {
if (io_state_ == STATE_HALF_CLOSED_LOCAL_UNCLAIMED) {
DCHECK_EQ(type_, SPDY_PUSH_STREAM);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&SpdyStream::PushedStreamReplay, GetWeakPtr()));
+ FROM_HERE,
+ base::BindOnce(&SpdyStream::PushedStreamReplay, GetWeakPtr()));
}
}
@@ -344,9 +345,9 @@ void SpdyStream::DecreaseRecvWindowSize(int32_t delta_window_size) {
if (delta_window_size > recv_window_size_ - unacked_recv_window_bytes_) {
session_->ResetStream(
stream_id_, ERR_SPDY_FLOW_CONTROL_ERROR,
- "delta_window_size is " + base::IntToString(delta_window_size) +
+ "delta_window_size is " + base::NumberToString(delta_window_size) +
" in DecreaseRecvWindowSize, which is larger than the receive " +
- "window size of " + base::IntToString(recv_window_size_));
+ "window size of " + base::NumberToString(recv_window_size_));
return;
}
@@ -382,44 +383,42 @@ void SpdyStream::OnHeadersReceived(
base::Time response_time,
base::TimeTicks recv_first_byte_time) {
switch (response_state_) {
- case READY_FOR_HEADERS:
+ case READY_FOR_HEADERS: {
// No header block has been received yet.
DCHECK(response_headers_.empty());
- {
- spdy::SpdyHeaderBlock::const_iterator it =
- response_headers.find(spdy::kHttp2StatusHeader);
- if (it == response_headers.end()) {
- const std::string error("Response headers do not include :status.");
- LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
- session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR, error);
- return;
- }
-
- int status;
- if (!StringToInt(it->second, &status)) {
- const std::string error("Cannot parse :status.");
- LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
- session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR, error);
- return;
- }
-
- base::UmaHistogramSparse("Net.SpdyResponseCode", status);
-
- // Include 1XX responses in the TTFB as per the resource timing spec
- // for responseStart.
- if (recv_first_byte_time_.is_null())
- recv_first_byte_time_ = recv_first_byte_time;
-
- // Ignore informational headers like 103 Early Hints.
- // TODO(bnc): Add support for 103 Early Hints, https://crbug.com/671310.
- // However, do not ignore 101 Switching Protocols, because broken
- // servers might send this as a response to a WebSocket request,
- // in which case it needs to pass through so that the WebSocket layer
- // can signal an error.
- if (status / 100 == 1 && status != 101) {
- return;
- }
+ spdy::SpdyHeaderBlock::const_iterator it =
+ response_headers.find(spdy::kHttp2StatusHeader);
+ if (it == response_headers.end()) {
+ const std::string error("Response headers do not include :status.");
+ LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
+ session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR, error);
+ return;
+ }
+
+ int status;
+ if (!StringToInt(it->second, &status)) {
+ const std::string error("Cannot parse :status.");
+ LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
+ session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR, error);
+ return;
+ }
+
+ base::UmaHistogramSparse("Net.SpdyResponseCode", status);
+
+ // Include 1XX responses in the TTFB as per the resource timing spec
+ // for responseStart.
+ if (recv_first_byte_time_.is_null())
+ recv_first_byte_time_ = recv_first_byte_time;
+
+ // Ignore informational headers like 103 Early Hints.
+ // TODO(bnc): Add support for 103 Early Hints, https://crbug.com/671310.
+ // However, do not ignore 101 Switching Protocols, because broken
+ // servers might send this as a response to a WebSocket request,
+ // in which case it needs to pass through so that the WebSocket layer
+ // can signal an error.
+ if (status / 100 == 1 && status != 101) {
+ return;
}
response_state_ = READY_FOR_DATA_OR_TRAILERS;
@@ -453,10 +452,10 @@ void SpdyStream::OnHeadersReceived(
DCHECK_NE(io_state_, STATE_IDLE);
response_time_ = response_time;
- SaveResponseHeaders(response_headers);
+ SaveResponseHeaders(response_headers, status);
break;
-
+ }
case READY_FOR_DATA_OR_TRAILERS:
// Second header block is trailers.
if (type_ == SPDY_PUSH_STREAM) {
@@ -686,7 +685,6 @@ void SpdyStream::OnClose(int status) {
status = OK;
}
}
- response_status_ = status;
Delegate* delegate = delegate_;
delegate_ = NULL;
if (delegate)
@@ -913,7 +911,8 @@ void SpdyStream::QueueNextDataFrame() {
}
void SpdyStream::SaveResponseHeaders(
- const spdy::SpdyHeaderBlock& response_headers) {
+ const spdy::SpdyHeaderBlock& response_headers,
+ int status) {
DCHECK(response_headers_.empty());
if (response_headers.find("transfer-encoding") != response_headers.end()) {
session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR,
@@ -926,6 +925,17 @@ void SpdyStream::SaveResponseHeaders(
response_headers_.insert(*it);
}
+ // Reject pushed stream with unsupported status code regardless of whether
+ // delegate is already attached or not.
+ if (type_ == SPDY_PUSH_STREAM &&
+ (status / 100 != 2 && status / 100 != 3 && status != 416)) {
+ SpdySession::RecordSpdyPushedStreamFateHistogram(
+ SpdyPushedStreamFate::kUnsupportedStatusCode);
+ session_->ResetStream(stream_id_, ERR_SPDY_CLIENT_REFUSED_STREAM,
+ "Unsupported status code for pushed stream.");
+ return;
+ }
+
// If delegate is not yet attached, OnHeadersReceived() will be called after
// the delegate gets attached to the stream.
if (!delegate_)
diff --git a/chromium/net/spdy/spdy_stream.h b/chromium/net/spdy/spdy_stream.h
index 35fdf444afa..2f5917513c3 100644
--- a/chromium/net/spdy/spdy_stream.h
+++ b/chromium/net/spdy/spdy_stream.h
@@ -370,8 +370,6 @@ class NET_EXPORT_PRIVATE SpdyStream {
// yet.
bool IsReservedRemote() const;
- int response_status() const { return response_status_; }
-
void AddRawReceivedBytes(size_t received_bytes);
void AddRawSentBytes(size_t sent_bytes);
@@ -451,7 +449,8 @@ class NET_EXPORT_PRIVATE SpdyStream {
// Saves the given headers into |response_headers_| and calls
// OnHeadersReceived() on the delegate if attached.
- void SaveResponseHeaders(const spdy::SpdyHeaderBlock& response_headers);
+ void SaveResponseHeaders(const spdy::SpdyHeaderBlock& response_headers,
+ int status);
static std::string DescribeState(State state);
@@ -511,10 +510,6 @@ class NET_EXPORT_PRIVATE SpdyStream {
State io_state_;
- // Since we buffer the response, we also buffer the response status.
- // Not valid until the stream is closed.
- int response_status_;
-
NetLogWithSource net_log_;
base::TimeTicks send_time_;
diff --git a/chromium/net/spdy/spdy_stream_unittest.cc b/chromium/net/spdy/spdy_stream_unittest.cc
index 0923dd0bfbf..e0dc4d759fa 100644
--- a/chromium/net/spdy/spdy_stream_unittest.cc
+++ b/chromium/net/spdy/spdy_stream_unittest.cc
@@ -14,6 +14,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
diff --git a/chromium/net/spdy/spdy_test_util_common.cc b/chromium/net/spdy/spdy_test_util_common.cc
index c47fc5e5a10..036ad98cd32 100644
--- a/chromium/net/spdy/spdy_test_util_common.cc
+++ b/chromium/net/spdy/spdy_test_util_common.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/base64.h"
+#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
@@ -18,13 +19,17 @@
#include "net/cert/do_nothing_ct_verifier.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
+#include "net/dns/host_resolver.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_transaction.h"
+#include "net/http/http_proxy_connect_job.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/next_proto.h"
#include "net/socket/socket_tag.h"
+#include "net/socket/socks_connect_job.h"
#include "net/socket/ssl_client_socket.h"
+#include "net/socket/ssl_connect_job.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/socket/transport_connect_job.h"
#include "net/spdy/buffered_spdy_framer.h"
@@ -324,8 +329,7 @@ SpdySessionDependencies::SpdySessionDependencies(
proxy_resolution_service(std::move(proxy_resolution_service)),
ssl_config_service(std::make_unique<SSLConfigServiceDefaults>()),
socket_factory(std::make_unique<MockClientSocketFactory>()),
- http_auth_handler_factory(
- HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
http_server_properties(std::make_unique<HttpServerPropertiesImpl>()),
enable_ip_pooling(true),
enable_ping(false),
@@ -398,7 +402,7 @@ HttpNetworkSession::Context SpdySessionDependencies::CreateSessionContext(
SpdySessionDependencies* session_deps) {
HttpNetworkSession::Context context;
context.client_socket_factory = session_deps->socket_factory.get();
- context.host_resolver = session_deps->host_resolver.get();
+ context.host_resolver = session_deps->GetHostResolver();
context.cert_verifier = session_deps->cert_verifier.get();
context.channel_id_service = session_deps->channel_id_service.get();
context.transport_security_state =
@@ -432,7 +436,7 @@ SpdyURLRequestContext::SpdyURLRequestContext() : storage_(this) {
std::make_unique<DoNothingCTVerifier>());
storage_.set_ssl_config_service(std::make_unique<SSLConfigServiceDefaults>());
storage_.set_http_auth_handler_factory(
- HttpAuthHandlerFactory::CreateDefault(host_resolver()));
+ HttpAuthHandlerFactory::CreateDefault());
storage_.set_http_server_properties(
std::make_unique<HttpServerPropertiesImpl>());
storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
@@ -494,15 +498,19 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper(
transport_params, nullptr, nullptr, key.host_port_pair(), ssl_config,
key.privacy_mode());
int rv = connection->Init(
- key.host_port_pair().ToString(), ssl_params, MEDIUM, key.socket_tag(),
- ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
- http_session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL),
+ key.host_port_pair().ToString(),
+ TransportClientSocketPool::SocketParams::CreateFromSSLSocketParams(
+ ssl_params),
+ MEDIUM, key.socket_tag(), ClientSocketPool::RespectLimits::ENABLED,
+ callback.callback(), ClientSocketPool::ProxyAuthCallback(),
+ http_session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
+ ProxyServer::Direct()),
net_log);
rv = callback.GetResult(rv);
EXPECT_THAT(rv, IsOk());
base::WeakPtr<SpdySession> spdy_session =
- http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
+ http_session->spdy_session_pool()->CreateAvailableSessionFromSocketHandle(
key, is_trusted_proxy, std::move(connection), net_log);
// Failure is reported asynchronously.
EXPECT_TRUE(spdy_session);
@@ -605,7 +613,7 @@ base::WeakPtr<SpdySession> CreateFakeSpdySessionHelper(
handle->SetSocket(std::make_unique<FakeSpdySessionClientSocket>(
expected_status == OK ? ERR_IO_PENDING : expected_status));
base::WeakPtr<SpdySession> spdy_session =
- pool->CreateAvailableSessionFromSocket(
+ pool->CreateAvailableSessionFromSocketHandle(
key,
/*is_trusted_proxy=*/false, std::move(handle), NetLogWithSource());
// Failure is reported asynchronously.
@@ -951,7 +959,8 @@ spdy::SpdySerializedFrame SpdyTestUtil::ConstructSpdyReplyError(
block["hello"] = "bye";
AppendToHeaderBlock(extra_headers, extra_header_count, &block);
- return ConstructSpdyReply(stream_id, std::move(block));
+ spdy::SpdyHeadersIR reply(stream_id, std::move(block));
+ return spdy::SpdySerializedFrame(response_spdy_framer_.SerializeFrame(reply));
}
spdy::SpdySerializedFrame SpdyTestUtil::ConstructSpdyReplyError(int stream_id) {
@@ -1065,7 +1074,7 @@ spdy::SpdyHeaderBlock SpdyTestUtil::ConstructHeaderBlock(
headers[spdy::kHttp2SchemeHeader] = scheme.c_str();
headers[spdy::kHttp2PathHeader] = path.c_str();
if (content_length) {
- std::string length_str = base::Int64ToString(*content_length);
+ std::string length_str = base::NumberToString(*content_length);
headers["content-length"] = length_str;
}
return headers;
diff --git a/chromium/net/spdy/spdy_test_util_common.h b/chromium/net/spdy/spdy_test_util_common.h
index 0f480ab4289..a15d79ea052 100644
--- a/chromium/net/spdy/spdy_test_util_common.h
+++ b/chromium/net/spdy/spdy_test_util_common.h
@@ -52,6 +52,7 @@ class CTVerifier;
class CTPolicyEnforcer;
class HashValue;
class HostPortPair;
+class HostResolver;
class NetLogWithSource;
class SpdySessionKey;
class SpdyStream;
@@ -183,6 +184,11 @@ struct SpdySessionDependencies {
~SpdySessionDependencies();
+ HostResolver* GetHostResolver() {
+ return alternate_host_resolver ? alternate_host_resolver.get()
+ : host_resolver.get();
+ }
+
static std::unique_ptr<HttpNetworkSession> SpdyCreateSession(
SpdySessionDependencies* session_deps);
@@ -198,6 +204,8 @@ struct SpdySessionDependencies {
// NOTE: host_resolver must be ordered before http_auth_handler_factory.
std::unique_ptr<MockHostResolverBase> host_resolver;
+ // For using a HostResolver not derived from MockHostResolverBase.
+ std::unique_ptr<HostResolver> alternate_host_resolver;
std::unique_ptr<CertVerifier> cert_verifier;
std::unique_ptr<ChannelIDService> channel_id_service;
std::unique_ptr<TransportSecurityState> transport_security_state;
diff --git a/chromium/net/spdy/spdy_write_queue_unittest.cc b/chromium/net/spdy/spdy_write_queue_unittest.cc
index b561ae9c7f7..e5d6a258500 100644
--- a/chromium/net/spdy/spdy_write_queue_unittest.cc
+++ b/chromium/net/spdy/spdy_write_queue_unittest.cc
@@ -9,6 +9,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
@@ -44,7 +45,7 @@ std::unique_ptr<SpdyBufferProducer> StringToProducer(const std::string& s) {
// Makes a SpdyBufferProducer producing a frame with the data in the
// given int (converted to a string).
std::unique_ptr<SpdyBufferProducer> IntToProducer(int i) {
- return StringToProducer(base::IntToString(i));
+ return StringToProducer(base::NumberToString(i));
}
// Producer whose produced buffer will enqueue yet another buffer into the