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

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

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