spdy_proxy_client_socket_unittest.cc 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/spdy/spdy_proxy_client_socket.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/callback_helpers.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/run_loop.h"
  10. #include "base/strings/string_piece.h"
  11. #include "base/strings/utf_string_conversions.h"
  12. #include "net/base/address_list.h"
  13. #include "net/base/host_port_pair.h"
  14. #include "net/base/load_timing_info.h"
  15. #include "net/base/proxy_server.h"
  16. #include "net/base/test_completion_callback.h"
  17. #include "net/base/winsock_init.h"
  18. #include "net/dns/mock_host_resolver.h"
  19. #include "net/dns/public/secure_dns_policy.h"
  20. #include "net/http/http_proxy_connect_job.h"
  21. #include "net/http/http_response_headers.h"
  22. #include "net/http/http_response_info.h"
  23. #include "net/log/net_log.h"
  24. #include "net/log/net_log_event_type.h"
  25. #include "net/log/net_log_source.h"
  26. #include "net/log/test_net_log.h"
  27. #include "net/log/test_net_log_util.h"
  28. #include "net/socket/client_socket_factory.h"
  29. #include "net/socket/connect_job_test_util.h"
  30. #include "net/socket/next_proto.h"
  31. #include "net/socket/socket_tag.h"
  32. #include "net/socket/socket_test_util.h"
  33. #include "net/socket/socks_connect_job.h"
  34. #include "net/socket/ssl_client_socket.h"
  35. #include "net/socket/ssl_connect_job.h"
  36. #include "net/socket/stream_socket.h"
  37. #include "net/socket/tcp_client_socket.h"
  38. #include "net/socket/transport_connect_job.h"
  39. #include "net/spdy/buffered_spdy_framer.h"
  40. #include "net/spdy/spdy_http_utils.h"
  41. #include "net/spdy/spdy_session_pool.h"
  42. #include "net/spdy/spdy_test_util_common.h"
  43. #include "net/test/cert_test_util.h"
  44. #include "net/test/gtest_util.h"
  45. #include "net/test/test_data_directory.h"
  46. #include "net/test/test_with_task_environment.h"
  47. #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
  48. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  49. #include "testing/gmock/include/gmock/gmock.h"
  50. #include "testing/gtest/include/gtest/gtest.h"
  51. #include "testing/platform_test.h"
  52. #include "url/gurl.h"
  53. #include "url/scheme_host_port.h"
  54. using net::test::IsError;
  55. using net::test::IsOk;
  56. //-----------------------------------------------------------------------------
  57. namespace net {
  58. namespace {
  59. static const char kRequestUrl[] = "https://www.google.com/";
  60. static const char kOriginHost[] = "www.google.com";
  61. static const int kOriginPort = 443;
  62. static const char kOriginHostPort[] = "www.google.com:443";
  63. static const char kProxyUrl[] = "https://myproxy:6121/";
  64. static const char kProxyHost[] = "myproxy";
  65. static const int kProxyPort = 6121;
  66. static const char kUserAgent[] = "Mozilla/1.0";
  67. static const int kStreamId = 1;
  68. static const char kMsg1[] = "\0hello!\xff";
  69. static const int kLen1 = 8;
  70. static const char kMsg2[] = "\0a2345678\0";
  71. static const int kLen2 = 10;
  72. static const char kMsg3[] = "bye!";
  73. static const int kLen3 = 4;
  74. static const char kMsg33[] = "bye!bye!";
  75. static const int kLen33 = kLen3 + kLen3;
  76. static const char kMsg333[] = "bye!bye!bye!";
  77. static const int kLen333 = kLen3 + kLen3 + kLen3;
  78. static const char kRedirectUrl[] = "https://example.com/";
  79. // Creates a SpdySession with a StreamSocket, instead of a ClientSocketHandle.
  80. base::WeakPtr<SpdySession> CreateSpdyProxySession(
  81. const url::SchemeHostPort& destination,
  82. HttpNetworkSession* http_session,
  83. const SpdySessionKey& key,
  84. const CommonConnectJobParams* common_connect_job_params) {
  85. EXPECT_FALSE(http_session->spdy_session_pool()->FindAvailableSession(
  86. key, true /* enable_ip_based_pooling */, false /* is_websocket */,
  87. NetLogWithSource()));
  88. auto transport_params = base::MakeRefCounted<TransportSocketParams>(
  89. destination, NetworkIsolationKey(), SecureDnsPolicy::kAllow,
  90. OnHostResolutionCallback(),
  91. /*supported_alpns=*/base::flat_set<std::string>{"h2", "http/1.1"});
  92. SSLConfig ssl_config;
  93. auto ssl_params = base::MakeRefCounted<SSLSocketParams>(
  94. transport_params, nullptr, nullptr,
  95. HostPortPair::FromSchemeHostPort(destination), ssl_config,
  96. key.privacy_mode(), key.network_isolation_key());
  97. TestConnectJobDelegate connect_job_delegate;
  98. SSLConnectJob connect_job(MEDIUM, SocketTag(), common_connect_job_params,
  99. ssl_params, &connect_job_delegate,
  100. nullptr /* net_log */);
  101. connect_job_delegate.StartJobExpectingResult(&connect_job, OK,
  102. false /* expect_sync_result */);
  103. base::WeakPtr<SpdySession> spdy_session =
  104. http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
  105. key, connect_job_delegate.ReleaseSocket(),
  106. LoadTimingInfo::ConnectTiming(), NetLogWithSource());
  107. // Failure is reported asynchronously.
  108. EXPECT_TRUE(spdy_session);
  109. EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key));
  110. return spdy_session;
  111. }
  112. } // namespace
  113. class SpdyProxyClientSocketTest : public PlatformTest,
  114. public WithTaskEnvironment,
  115. public ::testing::WithParamInterface<bool> {
  116. public:
  117. SpdyProxyClientSocketTest();
  118. SpdyProxyClientSocketTest(const SpdyProxyClientSocketTest&) = delete;
  119. SpdyProxyClientSocketTest& operator=(const SpdyProxyClientSocketTest&) =
  120. delete;
  121. ~SpdyProxyClientSocketTest() override;
  122. void TearDown() override;
  123. protected:
  124. void Initialize(base::span<const MockRead> reads,
  125. base::span<const MockWrite> writes);
  126. void PopulateConnectRequestIR(spdy::Http2HeaderBlock* syn_ir);
  127. void PopulateConnectReplyIR(spdy::Http2HeaderBlock* block,
  128. const char* status);
  129. spdy::SpdySerializedFrame ConstructConnectRequestFrame(
  130. RequestPriority priority = LOWEST);
  131. spdy::SpdySerializedFrame ConstructConnectAuthRequestFrame();
  132. spdy::SpdySerializedFrame ConstructConnectReplyFrame();
  133. spdy::SpdySerializedFrame ConstructConnectAuthReplyFrame();
  134. spdy::SpdySerializedFrame ConstructConnectRedirectReplyFrame();
  135. spdy::SpdySerializedFrame ConstructConnectErrorReplyFrame();
  136. spdy::SpdySerializedFrame ConstructBodyFrame(const char* data,
  137. int length,
  138. bool fin = false);
  139. scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
  140. void AssertConnectSucceeds();
  141. void AssertConnectFails(int result);
  142. void AssertConnectionEstablished();
  143. void AssertSyncReadEquals(const char* data, int len);
  144. void AssertSyncReadEOF();
  145. void AssertAsyncReadEquals(const char* data, int len, bool fin = false);
  146. void AssertReadStarts(const char* data, int len);
  147. void AssertReadReturns(const char* data, int len);
  148. void AssertAsyncWriteSucceeds(const char* data, int len);
  149. void AssertWriteReturns(const char* data, int len, int rv);
  150. void AssertWriteLength(int len);
  151. void AddAuthToCache() {
  152. const std::u16string kFoo(u"foo");
  153. const std::u16string kBar(u"bar");
  154. session_->http_auth_cache()->Add(
  155. url::SchemeHostPort{GURL(kProxyUrl)}, HttpAuth::AUTH_PROXY, "MyRealm1",
  156. HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
  157. "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
  158. }
  159. void ResumeAndRun() {
  160. // Run until the pause, if the provider isn't paused yet.
  161. data_->RunUntilPaused();
  162. data_->Resume();
  163. base::RunLoop().RunUntilIdle();
  164. }
  165. void CloseSpdySession(Error error, const std::string& description) {
  166. spdy_session_->CloseSessionOnError(error, description);
  167. }
  168. // Whether to use net::Socket::ReadIfReady() instead of net::Socket::Read().
  169. bool use_read_if_ready() const { return GetParam(); }
  170. NetLogWithSource net_log_with_source_{
  171. NetLogWithSource::Make(NetLogSourceType::NONE)};
  172. RecordingNetLogObserver net_log_observer_;
  173. SpdyTestUtil spdy_util_;
  174. std::unique_ptr<SpdyProxyClientSocket> sock_;
  175. TestCompletionCallback read_callback_;
  176. TestCompletionCallback write_callback_;
  177. std::unique_ptr<SequencedSocketData> data_;
  178. private:
  179. scoped_refptr<IOBuffer> read_buf_;
  180. SpdySessionDependencies session_deps_;
  181. std::unique_ptr<HttpNetworkSession> session_;
  182. MockConnect connect_data_;
  183. base::WeakPtr<SpdySession> spdy_session_;
  184. std::string user_agent_;
  185. GURL url_;
  186. HostPortPair proxy_host_port_;
  187. HostPortPair endpoint_host_port_pair_;
  188. ProxyServer proxy_;
  189. SpdySessionKey endpoint_spdy_session_key_;
  190. std::unique_ptr<CommonConnectJobParams> common_connect_job_params_;
  191. SSLSocketDataProvider ssl_;
  192. };
  193. SpdyProxyClientSocketTest::SpdyProxyClientSocketTest()
  194. : connect_data_(SYNCHRONOUS, OK),
  195. user_agent_(kUserAgent),
  196. url_(kRequestUrl),
  197. proxy_host_port_(kProxyHost, kProxyPort),
  198. endpoint_host_port_pair_(kOriginHost, kOriginPort),
  199. proxy_(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
  200. endpoint_spdy_session_key_(endpoint_host_port_pair_,
  201. proxy_,
  202. PRIVACY_MODE_DISABLED,
  203. SpdySessionKey::IsProxySession::kFalse,
  204. SocketTag(),
  205. NetworkIsolationKey(),
  206. SecureDnsPolicy::kAllow),
  207. ssl_(SYNCHRONOUS, OK) {
  208. session_deps_.net_log = NetLog::Get();
  209. }
  210. SpdyProxyClientSocketTest::~SpdyProxyClientSocketTest() {
  211. if (data_) {
  212. EXPECT_TRUE(data_->AllWriteDataConsumed());
  213. EXPECT_TRUE(data_->AllReadDataConsumed());
  214. }
  215. }
  216. void SpdyProxyClientSocketTest::TearDown() {
  217. if (session_)
  218. session_->spdy_session_pool()->CloseAllSessions();
  219. // Empty the current queue.
  220. base::RunLoop().RunUntilIdle();
  221. PlatformTest::TearDown();
  222. }
  223. void SpdyProxyClientSocketTest::Initialize(base::span<const MockRead> reads,
  224. base::span<const MockWrite> writes) {
  225. data_ = std::make_unique<SequencedSocketData>(reads, writes);
  226. data_->set_connect_data(connect_data_);
  227. session_deps_.socket_factory->AddSocketDataProvider(data_.get());
  228. ssl_.ssl_info.cert =
  229. ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  230. ASSERT_TRUE(ssl_.ssl_info.cert);
  231. ssl_.next_proto = NextProto::kProtoHTTP2;
  232. session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
  233. session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
  234. common_connect_job_params_ = std::make_unique<CommonConnectJobParams>(
  235. session_->CreateCommonConnectJobParams());
  236. // Creates the SPDY session and stream.
  237. spdy_session_ = CreateSpdyProxySession(
  238. url::SchemeHostPort(url_), session_.get(), endpoint_spdy_session_key_,
  239. common_connect_job_params_.get());
  240. base::WeakPtr<SpdyStream> spdy_stream(
  241. CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url_,
  242. LOWEST, net_log_with_source_));
  243. ASSERT_TRUE(spdy_stream.get() != nullptr);
  244. // Create the SpdyProxyClientSocket.
  245. sock_ = std::make_unique<SpdyProxyClientSocket>(
  246. spdy_stream, ProxyServer(ProxyServer::SCHEME_HTTPS, proxy_host_port_),
  247. user_agent_, endpoint_host_port_pair_, net_log_with_source_,
  248. base::MakeRefCounted<HttpAuthController>(
  249. HttpAuth::AUTH_PROXY, GURL("https://" + proxy_host_port_.ToString()),
  250. NetworkIsolationKey(), session_->http_auth_cache(),
  251. session_->http_auth_handler_factory(), session_->host_resolver()),
  252. // Testing with the proxy delegate is in HttpProxyConnectJobTest.
  253. nullptr);
  254. }
  255. scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer(
  256. const char* data, int size) {
  257. scoped_refptr<IOBufferWithSize> buf =
  258. base::MakeRefCounted<IOBufferWithSize>(size);
  259. memcpy(buf->data(), data, size);
  260. return buf;
  261. }
  262. void SpdyProxyClientSocketTest::AssertConnectSucceeds() {
  263. ASSERT_THAT(sock_->Connect(read_callback_.callback()),
  264. IsError(ERR_IO_PENDING));
  265. ASSERT_THAT(read_callback_.WaitForResult(), IsOk());
  266. }
  267. void SpdyProxyClientSocketTest::AssertConnectFails(int result) {
  268. ASSERT_THAT(sock_->Connect(read_callback_.callback()),
  269. IsError(ERR_IO_PENDING));
  270. ASSERT_EQ(result, read_callback_.WaitForResult());
  271. }
  272. void SpdyProxyClientSocketTest::AssertConnectionEstablished() {
  273. const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  274. ASSERT_TRUE(response != nullptr);
  275. ASSERT_EQ(200, response->headers->response_code());
  276. // Although the underlying HTTP/2 connection uses TLS and negotiates ALPN, the
  277. // tunnel itself is a TCP connection to the origin and should not report these
  278. // values.
  279. net::SSLInfo ssl_info;
  280. EXPECT_FALSE(sock_->GetSSLInfo(&ssl_info));
  281. EXPECT_FALSE(sock_->WasAlpnNegotiated());
  282. EXPECT_EQ(sock_->GetNegotiatedProtocol(), NextProto::kProtoUnknown);
  283. }
  284. void SpdyProxyClientSocketTest::AssertSyncReadEquals(const char* data,
  285. int len) {
  286. scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
  287. if (use_read_if_ready()) {
  288. ASSERT_EQ(len,
  289. sock_->ReadIfReady(buf.get(), len, CompletionOnceCallback()));
  290. } else {
  291. ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionOnceCallback()));
  292. }
  293. ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
  294. ASSERT_TRUE(sock_->IsConnected());
  295. }
  296. void SpdyProxyClientSocketTest::AssertSyncReadEOF() {
  297. if (use_read_if_ready()) {
  298. ASSERT_EQ(0, sock_->ReadIfReady(nullptr, 1, read_callback_.callback()));
  299. } else {
  300. ASSERT_EQ(0, sock_->Read(nullptr, 1, read_callback_.callback()));
  301. }
  302. }
  303. void SpdyProxyClientSocketTest::AssertAsyncReadEquals(const char* data,
  304. int len,
  305. bool fin) {
  306. // Issue the read, which will be completed asynchronously
  307. scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
  308. if (use_read_if_ready()) {
  309. ASSERT_EQ(ERR_IO_PENDING,
  310. sock_->ReadIfReady(buf.get(), len, read_callback_.callback()));
  311. } else {
  312. ASSERT_EQ(ERR_IO_PENDING,
  313. sock_->Read(buf.get(), len, read_callback_.callback()));
  314. }
  315. EXPECT_TRUE(sock_->IsConnected());
  316. ResumeAndRun();
  317. if (use_read_if_ready()) {
  318. EXPECT_EQ(OK, read_callback_.WaitForResult());
  319. ASSERT_EQ(len,
  320. sock_->ReadIfReady(buf.get(), len, read_callback_.callback()));
  321. } else {
  322. EXPECT_EQ(len, read_callback_.WaitForResult());
  323. }
  324. if (fin) {
  325. EXPECT_FALSE(sock_->IsConnected());
  326. } else {
  327. EXPECT_TRUE(sock_->IsConnected());
  328. }
  329. ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
  330. }
  331. void SpdyProxyClientSocketTest::AssertReadStarts(const char* data, int len) {
  332. // Issue the read, which will be completed asynchronously.
  333. read_buf_ = base::MakeRefCounted<IOBuffer>(len);
  334. if (use_read_if_ready()) {
  335. ASSERT_EQ(ERR_IO_PENDING, sock_->ReadIfReady(read_buf_.get(), len,
  336. read_callback_.callback()));
  337. } else {
  338. ASSERT_EQ(ERR_IO_PENDING,
  339. sock_->Read(read_buf_.get(), len, read_callback_.callback()));
  340. }
  341. EXPECT_TRUE(sock_->IsConnected());
  342. }
  343. void SpdyProxyClientSocketTest::AssertReadReturns(const char* data, int len) {
  344. EXPECT_TRUE(sock_->IsConnected());
  345. // Now the read will return
  346. if (use_read_if_ready()) {
  347. EXPECT_EQ(OK, read_callback_.WaitForResult());
  348. ASSERT_EQ(len, sock_->ReadIfReady(read_buf_.get(), len,
  349. read_callback_.callback()));
  350. } else {
  351. EXPECT_EQ(len, read_callback_.WaitForResult());
  352. }
  353. ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
  354. }
  355. void SpdyProxyClientSocketTest::AssertAsyncWriteSucceeds(const char* data,
  356. int len) {
  357. AssertWriteReturns(data, len, ERR_IO_PENDING);
  358. AssertWriteLength(len);
  359. }
  360. void SpdyProxyClientSocketTest::AssertWriteReturns(const char* data,
  361. int len,
  362. int rv) {
  363. scoped_refptr<IOBufferWithSize> buf(CreateBuffer(data, len));
  364. EXPECT_EQ(rv, sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
  365. TRAFFIC_ANNOTATION_FOR_TESTS));
  366. }
  367. void SpdyProxyClientSocketTest::AssertWriteLength(int len) {
  368. EXPECT_EQ(len, write_callback_.WaitForResult());
  369. }
  370. void SpdyProxyClientSocketTest::PopulateConnectRequestIR(
  371. spdy::Http2HeaderBlock* block) {
  372. (*block)[spdy::kHttp2MethodHeader] = "CONNECT";
  373. (*block)[spdy::kHttp2AuthorityHeader] = kOriginHostPort;
  374. (*block)["user-agent"] = kUserAgent;
  375. }
  376. void SpdyProxyClientSocketTest::PopulateConnectReplyIR(
  377. spdy::Http2HeaderBlock* block,
  378. const char* status) {
  379. (*block)[spdy::kHttp2StatusHeader] = status;
  380. }
  381. // Constructs a standard SPDY HEADERS frame for a CONNECT request.
  382. spdy::SpdySerializedFrame
  383. SpdyProxyClientSocketTest::ConstructConnectRequestFrame(
  384. RequestPriority priority) {
  385. spdy::Http2HeaderBlock block;
  386. PopulateConnectRequestIR(&block);
  387. return spdy_util_.ConstructSpdyHeaders(kStreamId, std::move(block), priority,
  388. false);
  389. }
  390. // Constructs a SPDY HEADERS frame for a CONNECT request which includes
  391. // Proxy-Authorization headers.
  392. spdy::SpdySerializedFrame
  393. SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
  394. spdy::Http2HeaderBlock block;
  395. PopulateConnectRequestIR(&block);
  396. block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
  397. return spdy_util_.ConstructSpdyHeaders(kStreamId, std::move(block), LOWEST,
  398. false);
  399. }
  400. // Constructs a standard SPDY HEADERS frame to match the SPDY CONNECT.
  401. spdy::SpdySerializedFrame
  402. SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
  403. spdy::Http2HeaderBlock block;
  404. PopulateConnectReplyIR(&block, "200");
  405. return spdy_util_.ConstructSpdyReply(kStreamId, std::move(block));
  406. }
  407. // Constructs a standard SPDY HEADERS frame to match the SPDY CONNECT,
  408. // including Proxy-Authenticate headers.
  409. spdy::SpdySerializedFrame
  410. SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
  411. spdy::Http2HeaderBlock block;
  412. PopulateConnectReplyIR(&block, "407");
  413. block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
  414. return spdy_util_.ConstructSpdyReply(kStreamId, std::move(block));
  415. }
  416. // Constructs a SPDY HEADERS frame with an HTTP 302 redirect.
  417. spdy::SpdySerializedFrame
  418. SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
  419. spdy::Http2HeaderBlock block;
  420. PopulateConnectReplyIR(&block, "302");
  421. block["location"] = kRedirectUrl;
  422. block["set-cookie"] = "foo=bar";
  423. return spdy_util_.ConstructSpdyReply(kStreamId, std::move(block));
  424. }
  425. // Constructs a SPDY HEADERS frame with an HTTP 500 error.
  426. spdy::SpdySerializedFrame
  427. SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
  428. spdy::Http2HeaderBlock block;
  429. PopulateConnectReplyIR(&block, "500");
  430. return spdy_util_.ConstructSpdyReply(kStreamId, std::move(block));
  431. }
  432. spdy::SpdySerializedFrame SpdyProxyClientSocketTest::ConstructBodyFrame(
  433. const char* data,
  434. int length,
  435. bool fin) {
  436. return spdy_util_.ConstructSpdyDataFrame(
  437. kStreamId, base::StringPiece(data, length), fin);
  438. }
  439. // ----------- Connect
  440. INSTANTIATE_TEST_SUITE_P(All,
  441. SpdyProxyClientSocketTest,
  442. ::testing::Bool());
  443. TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
  444. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  445. MockWrite writes[] = {
  446. CreateMockWrite(conn, 0, SYNCHRONOUS),
  447. };
  448. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  449. MockRead reads[] = {
  450. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  451. };
  452. Initialize(reads, writes);
  453. ASSERT_FALSE(sock_->IsConnected());
  454. AssertConnectSucceeds();
  455. AssertConnectionEstablished();
  456. }
  457. TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
  458. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  459. MockWrite writes[] = {
  460. CreateMockWrite(conn, 0, SYNCHRONOUS),
  461. };
  462. spdy::SpdySerializedFrame resp(ConstructConnectAuthReplyFrame());
  463. MockRead reads[] = {
  464. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  465. };
  466. Initialize(reads, writes);
  467. AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
  468. const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  469. ASSERT_TRUE(response != nullptr);
  470. ASSERT_EQ(407, response->headers->response_code());
  471. }
  472. TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
  473. spdy::SpdySerializedFrame conn(ConstructConnectAuthRequestFrame());
  474. MockWrite writes[] = {
  475. CreateMockWrite(conn, 0, SYNCHRONOUS),
  476. };
  477. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  478. MockRead reads[] = {
  479. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  480. };
  481. Initialize(reads, writes);
  482. AddAuthToCache();
  483. AssertConnectSucceeds();
  484. AssertConnectionEstablished();
  485. }
  486. TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
  487. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  488. spdy::SpdySerializedFrame rst(
  489. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  490. MockWrite writes[] = {
  491. CreateMockWrite(conn, 0, SYNCHRONOUS),
  492. };
  493. spdy::SpdySerializedFrame resp(ConstructConnectRedirectReplyFrame());
  494. MockRead reads[] = {
  495. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  496. };
  497. Initialize(reads, writes);
  498. AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
  499. const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  500. ASSERT_TRUE(response != nullptr);
  501. const HttpResponseHeaders* headers = response->headers.get();
  502. ASSERT_EQ(302, headers->response_code());
  503. ASSERT_TRUE(headers->HasHeader("set-cookie"));
  504. std::string location;
  505. ASSERT_TRUE(headers->IsRedirect(&location));
  506. ASSERT_EQ(location, kRedirectUrl);
  507. // Let the RST_STREAM write while |rst| is in-scope.
  508. base::RunLoop().RunUntilIdle();
  509. }
  510. TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
  511. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  512. MockWrite writes[] = {
  513. CreateMockWrite(conn, 0, SYNCHRONOUS),
  514. };
  515. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  516. MockRead reads[] = {
  517. MockRead(ASYNC, 0, 1), // EOF
  518. };
  519. Initialize(reads, writes);
  520. ASSERT_FALSE(sock_->IsConnected());
  521. AssertConnectFails(ERR_CONNECTION_CLOSED);
  522. ASSERT_FALSE(sock_->IsConnected());
  523. }
  524. TEST_P(SpdyProxyClientSocketTest, SetStreamPriority) {
  525. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame(LOWEST));
  526. MockWrite writes[] = {
  527. CreateMockWrite(conn, 0, SYNCHRONOUS),
  528. };
  529. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  530. MockRead reads[] = {
  531. CreateMockRead(resp, 1, ASYNC),
  532. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  533. };
  534. Initialize(reads, writes);
  535. // Set the stream priority. Since a connection was already established, it's
  536. // too late to adjust the HTTP2 stream's priority, and the request is ignored.
  537. sock_->SetStreamPriority(HIGHEST);
  538. AssertConnectSucceeds();
  539. }
  540. // ----------- WasEverUsed
  541. TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
  542. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  543. spdy::SpdySerializedFrame rst(
  544. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  545. MockWrite writes[] = {
  546. CreateMockWrite(conn, 0, SYNCHRONOUS), CreateMockWrite(rst, 3),
  547. };
  548. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  549. MockRead reads[] = {
  550. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  551. };
  552. Initialize(reads, writes);
  553. EXPECT_FALSE(sock_->WasEverUsed());
  554. AssertConnectSucceeds();
  555. EXPECT_TRUE(sock_->WasEverUsed());
  556. sock_->Disconnect();
  557. EXPECT_TRUE(sock_->WasEverUsed());
  558. // Let the RST_STREAM write while |rst| is in-scope.
  559. base::RunLoop().RunUntilIdle();
  560. }
  561. // ----------- GetPeerAddress
  562. TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
  563. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  564. MockWrite writes[] = {
  565. CreateMockWrite(conn, 0, SYNCHRONOUS),
  566. };
  567. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  568. MockRead reads[] = {
  569. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  570. MockRead(ASYNC, 0, 3), // EOF
  571. };
  572. Initialize(reads, writes);
  573. IPEndPoint addr;
  574. EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
  575. AssertConnectSucceeds();
  576. EXPECT_TRUE(sock_->IsConnected());
  577. EXPECT_THAT(sock_->GetPeerAddress(&addr), IsOk());
  578. ResumeAndRun();
  579. EXPECT_FALSE(sock_->IsConnected());
  580. EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
  581. sock_->Disconnect();
  582. EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
  583. }
  584. // ----------- Write
  585. TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
  586. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  587. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  588. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  589. MockWrite writes[] = {
  590. CreateMockWrite(conn, 0, SYNCHRONOUS),
  591. CreateMockWrite(msg1, 3, SYNCHRONOUS),
  592. CreateMockWrite(msg2, 4, SYNCHRONOUS),
  593. };
  594. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  595. MockRead reads[] = {
  596. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  597. };
  598. Initialize(reads, writes);
  599. AssertConnectSucceeds();
  600. AssertAsyncWriteSucceeds(kMsg1, kLen1);
  601. AssertAsyncWriteSucceeds(kMsg2, kLen2);
  602. }
  603. TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
  604. std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
  605. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  606. spdy::SpdySerializedFrame chunk(
  607. ConstructBodyFrame(chunk_data.data(), chunk_data.length()));
  608. MockWrite writes[] = {CreateMockWrite(conn, 0, SYNCHRONOUS),
  609. CreateMockWrite(chunk, 3, SYNCHRONOUS),
  610. CreateMockWrite(chunk, 4, SYNCHRONOUS),
  611. CreateMockWrite(chunk, 5, SYNCHRONOUS)};
  612. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  613. MockRead reads[] = {
  614. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  615. };
  616. Initialize(reads, writes);
  617. AssertConnectSucceeds();
  618. std::string big_data(kMaxSpdyFrameChunkSize * 3, 'x');
  619. scoped_refptr<IOBufferWithSize> buf(CreateBuffer(big_data.data(),
  620. big_data.length()));
  621. EXPECT_EQ(ERR_IO_PENDING,
  622. sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
  623. TRAFFIC_ANNOTATION_FOR_TESTS));
  624. EXPECT_EQ(buf->size(), write_callback_.WaitForResult());
  625. }
  626. // ----------- Read
  627. TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
  628. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  629. MockWrite writes[] = {
  630. CreateMockWrite(conn, 0, SYNCHRONOUS),
  631. };
  632. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  633. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  634. MockRead reads[] = {
  635. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  636. CreateMockRead(msg1, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
  637. };
  638. Initialize(reads, writes);
  639. AssertConnectSucceeds();
  640. // SpdySession consumes the next read and sends it to sock_ to be buffered.
  641. ResumeAndRun();
  642. AssertSyncReadEquals(kMsg1, kLen1);
  643. }
  644. TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
  645. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  646. MockWrite writes[] = {
  647. CreateMockWrite(conn, 0, SYNCHRONOUS),
  648. };
  649. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  650. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  651. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  652. MockRead reads[] = {
  653. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  654. CreateMockRead(msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4),
  655. CreateMockRead(msg2, 5, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
  656. };
  657. Initialize(reads, writes);
  658. AssertConnectSucceeds();
  659. // SpdySession consumes the next read and sends it to sock_ to be buffered.
  660. ResumeAndRun();
  661. AssertSyncReadEquals(kMsg1, kLen1);
  662. // SpdySession consumes the next read and sends it to sock_ to be buffered.
  663. ResumeAndRun();
  664. AssertSyncReadEquals(kMsg2, kLen2);
  665. }
  666. TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
  667. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  668. MockWrite writes[] = {
  669. CreateMockWrite(conn, 0, SYNCHRONOUS),
  670. };
  671. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  672. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  673. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  674. MockRead reads[] = {
  675. CreateMockRead(resp, 1, ASYNC),
  676. MockRead(ASYNC, ERR_IO_PENDING, 2),
  677. CreateMockRead(msg1, 3, ASYNC),
  678. CreateMockRead(msg2, 4, ASYNC),
  679. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
  680. };
  681. Initialize(reads, writes);
  682. AssertConnectSucceeds();
  683. // SpdySession consumes the next two reads and sends then to sock_ to be
  684. // buffered.
  685. ResumeAndRun();
  686. AssertSyncReadEquals(kMsg1, kLen1);
  687. AssertSyncReadEquals(kMsg2, kLen2);
  688. }
  689. TEST_P(SpdyProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
  690. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  691. MockWrite writes[] = {
  692. CreateMockWrite(conn, 0, SYNCHRONOUS),
  693. };
  694. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  695. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  696. spdy::SpdySerializedFrame msg3(ConstructBodyFrame(kMsg3, kLen3));
  697. MockRead reads[] = {
  698. CreateMockRead(resp, 1, ASYNC),
  699. MockRead(ASYNC, ERR_IO_PENDING, 2),
  700. CreateMockRead(msg3, 3, ASYNC),
  701. CreateMockRead(msg3, 4, ASYNC),
  702. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
  703. };
  704. Initialize(reads, writes);
  705. AssertConnectSucceeds();
  706. // SpdySession consumes the next two reads and sends then to sock_ to be
  707. // buffered.
  708. ResumeAndRun();
  709. // The payload from two data frames, each with kMsg3 will be combined
  710. // together into a single read().
  711. AssertSyncReadEquals(kMsg33, kLen33);
  712. }
  713. TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
  714. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  715. MockWrite writes[] = {
  716. CreateMockWrite(conn, 0, SYNCHRONOUS),
  717. };
  718. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  719. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  720. spdy::SpdySerializedFrame msg3(ConstructBodyFrame(kMsg3, kLen3));
  721. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  722. MockRead reads[] = {
  723. CreateMockRead(resp, 1, ASYNC),
  724. MockRead(ASYNC, ERR_IO_PENDING, 2),
  725. CreateMockRead(msg1, 3, ASYNC),
  726. CreateMockRead(msg3, 4, ASYNC),
  727. CreateMockRead(msg3, 5, ASYNC),
  728. CreateMockRead(msg2, 6, ASYNC),
  729. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 7),
  730. };
  731. Initialize(reads, writes);
  732. AssertConnectSucceeds();
  733. // SpdySession consumes the next four reads and sends then to sock_ to be
  734. // buffered.
  735. ResumeAndRun();
  736. AssertSyncReadEquals(kMsg1, kLen1);
  737. // The payload from two data frames, each with kMsg3 will be combined
  738. // together into a single read().
  739. AssertSyncReadEquals(kMsg33, kLen33);
  740. AssertSyncReadEquals(kMsg2, kLen2);
  741. }
  742. TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
  743. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  744. MockWrite writes[] = {
  745. CreateMockWrite(conn, 0, SYNCHRONOUS),
  746. };
  747. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  748. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  749. spdy::SpdySerializedFrame msg33(ConstructBodyFrame(kMsg33, kLen33));
  750. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  751. MockRead reads[] = {
  752. CreateMockRead(resp, 1, ASYNC),
  753. MockRead(ASYNC, ERR_IO_PENDING, 2),
  754. CreateMockRead(msg1, 3, ASYNC),
  755. CreateMockRead(msg33, 4, ASYNC),
  756. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
  757. };
  758. Initialize(reads, writes);
  759. AssertConnectSucceeds();
  760. // SpdySession consumes the next two reads and sends then to sock_ to be
  761. // buffered.
  762. ResumeAndRun();
  763. AssertSyncReadEquals(kMsg1, kLen1);
  764. // The payload from the single large data frame will be read across
  765. // two different reads.
  766. AssertSyncReadEquals(kMsg3, kLen3);
  767. AssertSyncReadEquals(kMsg3, kLen3);
  768. }
  769. TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
  770. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  771. MockWrite writes[] = {
  772. CreateMockWrite(conn, 0, SYNCHRONOUS),
  773. };
  774. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  775. spdy::SpdySerializedFrame msg333(ConstructBodyFrame(kMsg333, kLen333));
  776. MockRead reads[] = {
  777. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  778. CreateMockRead(msg333, 3, ASYNC),
  779. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
  780. };
  781. Initialize(reads, writes);
  782. AssertConnectSucceeds();
  783. // SpdySession consumes the next read and sends it to sock_ to be buffered.
  784. ResumeAndRun();
  785. // The payload from the single large data frame will be read across
  786. // two different reads.
  787. AssertSyncReadEquals(kMsg33, kLen33);
  788. // Now attempt to do a read of more data than remains buffered
  789. AssertSyncReadEquals(kMsg3, kLen3);
  790. ASSERT_TRUE(sock_->IsConnected());
  791. }
  792. TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
  793. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  794. MockWrite writes[] = {
  795. CreateMockWrite(conn, 0, SYNCHRONOUS),
  796. };
  797. spdy::SpdySerializedFrame resp(ConstructConnectAuthReplyFrame());
  798. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  799. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  800. MockRead reads[] = {
  801. CreateMockRead(resp, 1, ASYNC),
  802. MockRead(ASYNC, ERR_IO_PENDING, 2),
  803. CreateMockRead(msg1, 3, ASYNC),
  804. CreateMockRead(msg2, 4, ASYNC),
  805. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
  806. };
  807. Initialize(reads, writes);
  808. AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
  809. // SpdySession consumes the next two reads and sends then to sock_ to be
  810. // buffered.
  811. ResumeAndRun();
  812. AssertSyncReadEquals(kMsg1, kLen1);
  813. AssertSyncReadEquals(kMsg2, kLen2);
  814. }
  815. TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
  816. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  817. MockWrite writes[] = {
  818. CreateMockWrite(conn, 0, SYNCHRONOUS),
  819. };
  820. spdy::SpdySerializedFrame resp(ConstructConnectErrorReplyFrame());
  821. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  822. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  823. MockRead reads[] = {
  824. CreateMockRead(resp, 1, ASYNC), CreateMockRead(msg1, 2, SYNCHRONOUS),
  825. CreateMockRead(msg2, 3, SYNCHRONOUS), MockRead(SYNCHRONOUS, 0, 4), // EOF
  826. };
  827. Initialize(reads, writes);
  828. AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
  829. }
  830. TEST_P(SpdyProxyClientSocketTest, SocketDestroyedWhenReadIsPending) {
  831. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  832. MockWrite writes[] = {CreateMockWrite(conn, 0, SYNCHRONOUS)};
  833. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  834. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  835. MockRead reads[] = {
  836. CreateMockRead(resp, 1, ASYNC), CreateMockRead(msg1, 2, ASYNC),
  837. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
  838. };
  839. Initialize(reads, writes);
  840. AssertConnectSucceeds();
  841. // Make Read()/ReadIfReady() pending.
  842. AssertReadStarts(kMsg1, kLen1);
  843. // Destroying socket.
  844. sock_ = nullptr;
  845. // Read data is not consumed.
  846. EXPECT_TRUE(data_->AllWriteDataConsumed());
  847. EXPECT_FALSE(data_->AllReadDataConsumed());
  848. // Reset |data_| so the test destructor doesn't check it.
  849. data_ = nullptr;
  850. }
  851. // ----------- Reads and Writes
  852. TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
  853. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  854. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  855. MockWrite writes[] = {
  856. CreateMockWrite(conn, 0, SYNCHRONOUS),
  857. CreateMockWrite(msg2, 4, SYNCHRONOUS),
  858. };
  859. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  860. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  861. spdy::SpdySerializedFrame msg3(ConstructBodyFrame(kMsg3, kLen3));
  862. MockRead reads[] = {
  863. CreateMockRead(resp, 1, ASYNC),
  864. MockRead(ASYNC, ERR_IO_PENDING, 2),
  865. CreateMockRead(msg1, 3, ASYNC), // sync read
  866. MockRead(ASYNC, ERR_IO_PENDING, 5),
  867. CreateMockRead(msg3, 6, ASYNC), // async read
  868. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 7),
  869. };
  870. Initialize(reads, writes);
  871. AssertConnectSucceeds();
  872. ResumeAndRun();
  873. AssertSyncReadEquals(kMsg1, kLen1);
  874. AssertReadStarts(kMsg3, kLen3);
  875. // Read should block until after the write succeeds.
  876. AssertAsyncWriteSucceeds(kMsg2, kLen2); // Advances past paused read.
  877. ASSERT_FALSE(read_callback_.have_result());
  878. ResumeAndRun();
  879. // Now the read will return.
  880. AssertReadReturns(kMsg3, kLen3);
  881. }
  882. TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
  883. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  884. spdy::SpdySerializedFrame msg2(ConstructBodyFrame(kMsg2, kLen2));
  885. MockWrite writes[] = {
  886. CreateMockWrite(conn, 0, SYNCHRONOUS),
  887. MockWrite(ASYNC, ERR_IO_PENDING, 7), CreateMockWrite(msg2, 8, ASYNC),
  888. };
  889. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  890. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  891. spdy::SpdySerializedFrame msg3(ConstructBodyFrame(kMsg3, kLen3));
  892. MockRead reads[] = {
  893. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  894. CreateMockRead(msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4),
  895. CreateMockRead(msg3, 5, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
  896. };
  897. Initialize(reads, writes);
  898. AssertConnectSucceeds();
  899. ResumeAndRun();
  900. AssertSyncReadEquals(kMsg1, kLen1);
  901. // Write should block until the read completes
  902. AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
  903. AssertAsyncReadEquals(kMsg3, kLen3);
  904. ASSERT_FALSE(write_callback_.have_result());
  905. // Now the write will complete
  906. ResumeAndRun();
  907. AssertWriteLength(kLen2);
  908. }
  909. // ----------- Reading/Writing on Closed socket
  910. // Reading from an already closed socket should return 0
  911. TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
  912. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  913. MockWrite writes[] = {
  914. CreateMockWrite(conn, 0, SYNCHRONOUS),
  915. };
  916. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  917. MockRead reads[] = {
  918. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  919. MockRead(ASYNC, 0, 3), // EOF
  920. };
  921. Initialize(reads, writes);
  922. AssertConnectSucceeds();
  923. ResumeAndRun();
  924. ASSERT_FALSE(sock_->IsConnected());
  925. AssertSyncReadEOF();
  926. AssertSyncReadEOF();
  927. AssertSyncReadEOF();
  928. ASSERT_FALSE(sock_->IsConnectedAndIdle());
  929. }
  930. // Read pending when socket is closed should return 0
  931. TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
  932. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  933. MockWrite writes[] = {
  934. CreateMockWrite(conn, 0, SYNCHRONOUS),
  935. };
  936. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  937. MockRead reads[] = {
  938. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  939. MockRead(ASYNC, 0, 3), // EOF
  940. };
  941. Initialize(reads, writes);
  942. AssertConnectSucceeds();
  943. AssertReadStarts(kMsg1, kLen1);
  944. ResumeAndRun();
  945. ASSERT_EQ(0, read_callback_.WaitForResult());
  946. }
  947. // Reading from a disconnected socket is an error
  948. TEST_P(SpdyProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
  949. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  950. spdy::SpdySerializedFrame rst(
  951. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  952. MockWrite writes[] = {
  953. CreateMockWrite(conn, 0, SYNCHRONOUS), CreateMockWrite(rst, 3),
  954. };
  955. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  956. MockRead reads[] = {
  957. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  958. };
  959. Initialize(reads, writes);
  960. AssertConnectSucceeds();
  961. sock_->Disconnect();
  962. if (use_read_if_ready()) {
  963. ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
  964. sock_->ReadIfReady(nullptr, 1, CompletionOnceCallback()));
  965. } else {
  966. ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
  967. sock_->Read(nullptr, 1, CompletionOnceCallback()));
  968. }
  969. // Let the RST_STREAM write while |rst| is in-scope.
  970. base::RunLoop().RunUntilIdle();
  971. }
  972. // Reading buffered data from an already closed socket should return
  973. // buffered data, then 0.
  974. TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
  975. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  976. MockWrite writes[] = {
  977. CreateMockWrite(conn, 0, SYNCHRONOUS),
  978. };
  979. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  980. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  981. MockRead reads[] = {
  982. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  983. CreateMockRead(msg1, 3, ASYNC), MockRead(ASYNC, 0, 4), // EOF
  984. };
  985. Initialize(reads, writes);
  986. AssertConnectSucceeds();
  987. ResumeAndRun();
  988. ASSERT_FALSE(sock_->IsConnected());
  989. scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kLen1);
  990. ASSERT_EQ(kLen1, sock_->Read(buf.get(), kLen1, CompletionOnceCallback()));
  991. ASSERT_EQ(std::string(kMsg1, kLen1), std::string(buf->data(), kLen1));
  992. ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
  993. ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
  994. sock_->Disconnect();
  995. ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
  996. sock_->Read(nullptr, 1, CompletionOnceCallback()));
  997. }
  998. // Calling Write() on a closed socket is an error
  999. TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
  1000. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1001. MockWrite writes[] = {
  1002. CreateMockWrite(conn, 0, SYNCHRONOUS),
  1003. };
  1004. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1005. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  1006. MockRead reads[] = {
  1007. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  1008. MockRead(ASYNC, 0, 3), // EOF
  1009. };
  1010. Initialize(reads, writes);
  1011. AssertConnectSucceeds();
  1012. // Read EOF which will close the stream.
  1013. ResumeAndRun();
  1014. scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
  1015. EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
  1016. sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
  1017. TRAFFIC_ANNOTATION_FOR_TESTS));
  1018. }
  1019. // Calling Write() on a disconnected socket is an error.
  1020. TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
  1021. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1022. spdy::SpdySerializedFrame rst(
  1023. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  1024. MockWrite writes[] = {
  1025. CreateMockWrite(conn, 0, SYNCHRONOUS), CreateMockWrite(rst, 3),
  1026. };
  1027. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1028. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  1029. MockRead reads[] = {
  1030. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  1031. };
  1032. Initialize(reads, writes);
  1033. AssertConnectSucceeds();
  1034. sock_->Disconnect();
  1035. scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
  1036. EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED,
  1037. sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
  1038. TRAFFIC_ANNOTATION_FOR_TESTS));
  1039. // Let the RST_STREAM write while |rst| is in-scope.
  1040. base::RunLoop().RunUntilIdle();
  1041. }
  1042. // If the socket is closed with a pending Write(), the callback
  1043. // should be called with ERR_CONNECTION_CLOSED.
  1044. TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
  1045. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1046. MockWrite writes[] = {
  1047. CreateMockWrite(conn, 0, SYNCHRONOUS),
  1048. MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 3),
  1049. };
  1050. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1051. MockRead reads[] = {
  1052. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  1053. };
  1054. Initialize(reads, writes);
  1055. AssertConnectSucceeds();
  1056. EXPECT_TRUE(sock_->IsConnected());
  1057. scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
  1058. EXPECT_EQ(ERR_IO_PENDING,
  1059. sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
  1060. TRAFFIC_ANNOTATION_FOR_TESTS));
  1061. // Make sure the write actually starts.
  1062. base::RunLoop().RunUntilIdle();
  1063. CloseSpdySession(ERR_ABORTED, std::string());
  1064. EXPECT_THAT(write_callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
  1065. }
  1066. // If the socket is Disconnected with a pending Write(), the callback
  1067. // should not be called.
  1068. TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
  1069. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1070. spdy::SpdySerializedFrame rst(
  1071. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  1072. MockWrite writes[] = {
  1073. CreateMockWrite(conn, 0, SYNCHRONOUS), CreateMockWrite(rst, 3),
  1074. };
  1075. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1076. MockRead reads[] = {
  1077. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  1078. };
  1079. Initialize(reads, writes);
  1080. AssertConnectSucceeds();
  1081. EXPECT_TRUE(sock_->IsConnected());
  1082. scoped_refptr<IOBufferWithSize> buf(CreateBuffer(kMsg1, kLen1));
  1083. EXPECT_EQ(ERR_IO_PENDING,
  1084. sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
  1085. TRAFFIC_ANNOTATION_FOR_TESTS));
  1086. sock_->Disconnect();
  1087. EXPECT_FALSE(sock_->IsConnected());
  1088. EXPECT_FALSE(write_callback_.have_result());
  1089. // Let the RST_STREAM write while |rst| is in-scope.
  1090. base::RunLoop().RunUntilIdle();
  1091. }
  1092. // If the socket is Disconnected with a pending Read(), the callback
  1093. // should not be called.
  1094. TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
  1095. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1096. spdy::SpdySerializedFrame rst(
  1097. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  1098. MockWrite writes[] = {
  1099. CreateMockWrite(conn, 0, SYNCHRONOUS), CreateMockWrite(rst, 3),
  1100. };
  1101. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1102. MockRead reads[] = {
  1103. CreateMockRead(resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
  1104. };
  1105. Initialize(reads, writes);
  1106. AssertConnectSucceeds();
  1107. EXPECT_TRUE(sock_->IsConnected());
  1108. scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kLen1);
  1109. ASSERT_EQ(ERR_IO_PENDING,
  1110. sock_->Read(buf.get(), kLen1, read_callback_.callback()));
  1111. sock_->Disconnect();
  1112. EXPECT_FALSE(sock_->IsConnected());
  1113. EXPECT_FALSE(read_callback_.have_result());
  1114. // Let the RST_STREAM write while |rst| is in-scope.
  1115. base::RunLoop().RunUntilIdle();
  1116. }
  1117. // If the socket is Reset when both a read and write are pending,
  1118. // both should be called back.
  1119. TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
  1120. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1121. MockWrite writes[] = {
  1122. CreateMockWrite(conn, 0, SYNCHRONOUS),
  1123. };
  1124. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1125. spdy::SpdySerializedFrame rst(
  1126. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  1127. MockRead reads[] = {
  1128. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  1129. CreateMockRead(rst, 3, ASYNC), MockRead(ASYNC, 0, 4) // EOF
  1130. };
  1131. Initialize(reads, writes);
  1132. AssertConnectSucceeds();
  1133. EXPECT_TRUE(sock_->IsConnected());
  1134. scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(kLen1);
  1135. ASSERT_EQ(ERR_IO_PENDING,
  1136. sock_->Read(read_buf.get(), kLen1, read_callback_.callback()));
  1137. scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
  1138. EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf.get(), write_buf->size(),
  1139. write_callback_.callback(),
  1140. TRAFFIC_ANNOTATION_FOR_TESTS));
  1141. ResumeAndRun();
  1142. EXPECT_TRUE(sock_.get());
  1143. EXPECT_TRUE(read_callback_.have_result());
  1144. EXPECT_TRUE(write_callback_.have_result());
  1145. // Let the RST_STREAM write while |rst| is in-scope.
  1146. base::RunLoop().RunUntilIdle();
  1147. }
  1148. // Makes sure the proxy client socket's source gets the expected NetLog events
  1149. // and only the expected NetLog events (No SpdySession events).
  1150. TEST_P(SpdyProxyClientSocketTest, NetLog) {
  1151. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1152. spdy::SpdySerializedFrame rst(
  1153. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  1154. MockWrite writes[] = {
  1155. CreateMockWrite(conn, 0, SYNCHRONOUS), CreateMockWrite(rst, 5),
  1156. };
  1157. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1158. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  1159. MockRead reads[] = {
  1160. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  1161. CreateMockRead(msg1, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
  1162. };
  1163. Initialize(reads, writes);
  1164. AssertConnectSucceeds();
  1165. // SpdySession consumes the next read and sends it to sock_ to be buffered.
  1166. ResumeAndRun();
  1167. AssertSyncReadEquals(kMsg1, kLen1);
  1168. NetLogSource sock_source = sock_->NetLog().source();
  1169. sock_.reset();
  1170. auto entry_list = net_log_observer_.GetEntriesForSource(sock_source);
  1171. ASSERT_EQ(entry_list.size(), 10u);
  1172. EXPECT_TRUE(
  1173. LogContainsBeginEvent(entry_list, 0, NetLogEventType::SOCKET_ALIVE));
  1174. EXPECT_TRUE(LogContainsEvent(entry_list, 1,
  1175. NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
  1176. NetLogEventPhase::NONE));
  1177. EXPECT_TRUE(LogContainsBeginEvent(
  1178. entry_list, 2, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
  1179. EXPECT_TRUE(LogContainsEvent(
  1180. entry_list, 3, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
  1181. NetLogEventPhase::NONE));
  1182. EXPECT_TRUE(LogContainsEndEvent(
  1183. entry_list, 4, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
  1184. EXPECT_TRUE(LogContainsBeginEvent(
  1185. entry_list, 5, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
  1186. EXPECT_TRUE(LogContainsEvent(
  1187. entry_list, 6,
  1188. NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
  1189. NetLogEventPhase::NONE));
  1190. EXPECT_TRUE(LogContainsEndEvent(
  1191. entry_list, 7, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
  1192. EXPECT_TRUE(LogContainsEvent(entry_list, 8,
  1193. NetLogEventType::SOCKET_BYTES_RECEIVED,
  1194. NetLogEventPhase::NONE));
  1195. EXPECT_TRUE(
  1196. LogContainsEndEvent(entry_list, 9, NetLogEventType::SOCKET_ALIVE));
  1197. // Let the RST_STREAM write while |rst| is in-scope.
  1198. base::RunLoop().RunUntilIdle();
  1199. }
  1200. // A helper class that will delete |sock| when the callback is invoked.
  1201. class DeleteSockCallback : public TestCompletionCallbackBase {
  1202. public:
  1203. explicit DeleteSockCallback(std::unique_ptr<SpdyProxyClientSocket>* sock)
  1204. : sock_(sock) {}
  1205. DeleteSockCallback(const DeleteSockCallback&) = delete;
  1206. DeleteSockCallback& operator=(const DeleteSockCallback&) = delete;
  1207. ~DeleteSockCallback() override = default;
  1208. CompletionOnceCallback callback() {
  1209. return base::BindOnce(&DeleteSockCallback::OnComplete,
  1210. base::Unretained(this));
  1211. }
  1212. private:
  1213. void OnComplete(int result) {
  1214. sock_->reset(nullptr);
  1215. SetResult(result);
  1216. }
  1217. raw_ptr<std::unique_ptr<SpdyProxyClientSocket>> sock_;
  1218. };
  1219. // If the socket is Reset when both a read and write are pending, and the
  1220. // read callback causes the socket to be deleted, the write callback should
  1221. // not be called.
  1222. TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
  1223. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1224. MockWrite writes[] = {
  1225. CreateMockWrite(conn, 0, SYNCHRONOUS),
  1226. };
  1227. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1228. spdy::SpdySerializedFrame rst(
  1229. spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  1230. MockRead reads[] = {
  1231. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  1232. CreateMockRead(rst, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
  1233. };
  1234. Initialize(reads, writes);
  1235. AssertConnectSucceeds();
  1236. EXPECT_TRUE(sock_->IsConnected());
  1237. DeleteSockCallback read_callback(&sock_);
  1238. scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(kLen1);
  1239. ASSERT_EQ(ERR_IO_PENDING,
  1240. sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
  1241. scoped_refptr<IOBufferWithSize> write_buf(CreateBuffer(kMsg1, kLen1));
  1242. EXPECT_EQ(ERR_IO_PENDING, sock_->Write(write_buf.get(), write_buf->size(),
  1243. write_callback_.callback(),
  1244. TRAFFIC_ANNOTATION_FOR_TESTS));
  1245. ResumeAndRun();
  1246. EXPECT_FALSE(sock_.get());
  1247. EXPECT_TRUE(read_callback.have_result());
  1248. EXPECT_FALSE(write_callback_.have_result());
  1249. // Let the RST_STREAM write while |rst| is in-scope.
  1250. base::RunLoop().RunUntilIdle();
  1251. }
  1252. // ----------- Canceling a ReadIfReady
  1253. TEST_P(SpdyProxyClientSocketTest, CancelReadIfReady) {
  1254. // Not relevant if not ReadIfReady().
  1255. if (!use_read_if_ready())
  1256. return;
  1257. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1258. MockWrite writes[] = {CreateMockWrite(conn, 0, SYNCHRONOUS)};
  1259. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1260. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  1261. spdy::SpdySerializedFrame msg3(ConstructBodyFrame(kMsg3, kLen3));
  1262. MockRead reads[] = {
  1263. CreateMockRead(resp, 1, ASYNC), CreateMockRead(msg1, 2, ASYNC),
  1264. CreateMockRead(msg3, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
  1265. };
  1266. Initialize(reads, writes);
  1267. AssertConnectSucceeds();
  1268. AssertReadStarts(kMsg1, kLen1);
  1269. EXPECT_EQ(OK, sock_->CancelReadIfReady());
  1270. // Perform ReadIfReady again should succeed after cancelation.
  1271. AssertReadStarts(kMsg1, kLen1);
  1272. AssertReadReturns(kMsg1, kLen1);
  1273. AssertReadStarts(kMsg3, kLen3);
  1274. AssertReadReturns(kMsg3, kLen3);
  1275. // Canceling ReadIfReady() when none is in progress is an no-op.
  1276. EXPECT_EQ(OK, sock_->CancelReadIfReady());
  1277. }
  1278. // ----------- Handling END_STREAM from the peer
  1279. TEST_P(SpdyProxyClientSocketTest, HandleEndStreamAsEOF) {
  1280. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1281. spdy::SpdySerializedFrame end_stream(
  1282. ConstructBodyFrame(/*data=*/nullptr, /*length=*/0, /*fin=*/true));
  1283. MockWrite writes[] = {
  1284. CreateMockWrite(conn, 0, SYNCHRONOUS),
  1285. CreateMockWrite(end_stream, 7, SYNCHRONOUS),
  1286. };
  1287. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1288. spdy::SpdySerializedFrame msg1(ConstructBodyFrame(kMsg1, kLen1));
  1289. spdy::SpdySerializedFrame msg2(
  1290. ConstructBodyFrame(kMsg2, kLen2, /*fin=*/true));
  1291. MockRead reads[] = {
  1292. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  1293. CreateMockRead(msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4),
  1294. CreateMockRead(msg2, 5, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6),
  1295. };
  1296. Initialize(reads, writes);
  1297. AssertConnectSucceeds();
  1298. AssertAsyncReadEquals(kMsg1, kLen1);
  1299. AssertAsyncReadEquals(kMsg2, kLen2, /*fin=*/true);
  1300. }
  1301. TEST_P(SpdyProxyClientSocketTest, SendEndStreamAfterWrite) {
  1302. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1303. spdy::SpdySerializedFrame write_msg(ConstructBodyFrame(kMsg1, kLen1));
  1304. spdy::SpdySerializedFrame end_stream(
  1305. ConstructBodyFrame(/*data=*/nullptr, /*length=*/0, /*fin=*/true));
  1306. MockWrite writes[] = {
  1307. CreateMockWrite(conn, 0, SYNCHRONOUS),
  1308. CreateMockWrite(write_msg, 4, ASYNC),
  1309. CreateMockWrite(end_stream, 6, ASYNC),
  1310. };
  1311. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1312. spdy::SpdySerializedFrame read_msg(
  1313. ConstructBodyFrame(kMsg2, kLen2, /*fin=*/true));
  1314. MockRead reads[] = {
  1315. CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
  1316. CreateMockRead(read_msg, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 5),
  1317. MockRead(SYNCHRONOUS, 0, 7),
  1318. };
  1319. Initialize(reads, writes);
  1320. AssertConnectSucceeds();
  1321. AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
  1322. AssertAsyncReadEquals(kMsg2, kLen2, /*fin=*/false);
  1323. ResumeAndRun();
  1324. AssertWriteLength(kLen1);
  1325. AssertSyncReadEOF();
  1326. }
  1327. // Regression test for https://crbug.com/1320256
  1328. TEST_P(SpdyProxyClientSocketTest, WriteAfterStreamEndSent) {
  1329. spdy::SpdySerializedFrame conn(ConstructConnectRequestFrame());
  1330. MockWrite writes[] = {
  1331. CreateMockWrite(conn, 0, SYNCHRONOUS),
  1332. // The following mock write blocks SpdyStream::SendData() in
  1333. // SpdyProxyClientSocket::MaybeSendEndStream().
  1334. MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 5),
  1335. };
  1336. spdy::SpdySerializedFrame resp(ConstructConnectReplyFrame());
  1337. spdy::SpdySerializedFrame read_msg(
  1338. ConstructBodyFrame(kMsg1, kLen1, /*fin=*/true));
  1339. MockRead reads[] = {
  1340. CreateMockRead(resp, 1, ASYNC),
  1341. MockRead(ASYNC, ERR_IO_PENDING, 2),
  1342. CreateMockRead(read_msg, 3, ASYNC),
  1343. MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
  1344. };
  1345. Initialize(reads, writes);
  1346. AssertConnectSucceeds();
  1347. AssertAsyncReadEquals(kMsg1, kLen1);
  1348. AssertWriteReturns(kMsg2, kLen2, ERR_CONNECTION_CLOSED);
  1349. }
  1350. } // namespace net