Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(375)

Side by Side Diff: net/spdy/spdy_proxy_client_socket_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698