1 // Copyright (c) 2011 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/socket/tcp_client_socket.h"
6
7 #include "base/basictypes.h"
8 #include "net/base/address_list.h"
9 #include "net/base/host_resolver.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/listen_socket.h"
12 #include "net/base/net_log.h"
13 #include "net/base/net_log_unittest.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/base/winsock_init.h"
17 #include "net/socket/client_socket_factory.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/platform_test.h"
20
21 namespace net {
22
23 namespace {
24
25 const char kServerReply[] = "HTTP/1.1 404 Not Found";
26
27 enum ClientSocketTestTypes {
28 TCP,
29 SCTP
30 };
31
32 class TransportClientSocketTest
33 : public ListenSocket::ListenSocketDelegate,
34 public ::testing::TestWithParam<ClientSocketTestTypes> {
35 public:
TransportClientSocketTest()36 TransportClientSocketTest()
37 : listen_port_(0),
38 net_log_(CapturingNetLog::kUnbounded),
39 socket_factory_(ClientSocketFactory::GetDefaultFactory()),
40 close_server_socket_on_next_send_(false) {
41 }
42
~TransportClientSocketTest()43 ~TransportClientSocketTest() {
44 }
45
46 // Implement ListenSocketDelegate methods
DidAccept(ListenSocket * server,ListenSocket * connection)47 virtual void DidAccept(ListenSocket* server, ListenSocket* connection) {
48 connected_sock_ = connection;
49 }
DidRead(ListenSocket *,const char * str,int len)50 virtual void DidRead(ListenSocket*, const char* str, int len) {
51 // TODO(dkegel): this might not be long enough to tickle some bugs.
52 connected_sock_->Send(kServerReply, arraysize(kServerReply) - 1,
53 false /* Don't append line feed */);
54 if (close_server_socket_on_next_send_)
55 CloseServerSocket();
56 }
DidClose(ListenSocket * sock)57 virtual void DidClose(ListenSocket* sock) {}
58
59 // Testcase hooks
60 virtual void SetUp();
61
CloseServerSocket()62 void CloseServerSocket() {
63 // delete the connected_sock_, which will close it.
64 connected_sock_ = NULL;
65 }
66
PauseServerReads()67 void PauseServerReads() {
68 connected_sock_->PauseReads();
69 }
70
ResumeServerReads()71 void ResumeServerReads() {
72 connected_sock_->ResumeReads();
73 }
74
75 int DrainClientSocket(IOBuffer* buf,
76 uint32 buf_len,
77 uint32 bytes_to_read,
78 TestCompletionCallback* callback);
79
80 void SendClientRequest();
81
set_close_server_socket_on_next_send(bool close)82 void set_close_server_socket_on_next_send(bool close) {
83 close_server_socket_on_next_send_ = close;
84 }
85
86 protected:
87 int listen_port_;
88 CapturingNetLog net_log_;
89 ClientSocketFactory* const socket_factory_;
90 scoped_ptr<ClientSocket> sock_;
91
92 private:
93 scoped_refptr<ListenSocket> listen_sock_;
94 scoped_refptr<ListenSocket> connected_sock_;
95 bool close_server_socket_on_next_send_;
96 };
97
SetUp()98 void TransportClientSocketTest::SetUp() {
99 ::testing::TestWithParam<ClientSocketTestTypes>::SetUp();
100
101 // Find a free port to listen on
102 ListenSocket *sock = NULL;
103 int port;
104 // Range of ports to listen on. Shouldn't need to try many.
105 const int kMinPort = 10100;
106 const int kMaxPort = 10200;
107 #if defined(OS_WIN)
108 EnsureWinsockInit();
109 #endif
110 for (port = kMinPort; port < kMaxPort; port++) {
111 sock = ListenSocket::Listen("127.0.0.1", port, this);
112 if (sock)
113 break;
114 }
115 ASSERT_TRUE(sock != NULL);
116 listen_sock_ = sock;
117 listen_port_ = port;
118
119 AddressList addr;
120 scoped_ptr<HostResolver> resolver(
121 CreateSystemHostResolver(HostResolver::kDefaultParallelism,
122 NULL, NULL));
123 HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_));
124 int rv = resolver->Resolve(info, &addr, NULL, NULL, BoundNetLog());
125 CHECK_EQ(rv, OK);
126 sock_.reset(
127 socket_factory_->CreateTransportClientSocket(addr,
128 &net_log_,
129 NetLog::Source()));
130 }
131
DrainClientSocket(IOBuffer * buf,uint32 buf_len,uint32 bytes_to_read,TestCompletionCallback * callback)132 int TransportClientSocketTest::DrainClientSocket(
133 IOBuffer* buf, uint32 buf_len,
134 uint32 bytes_to_read, TestCompletionCallback* callback) {
135 int rv = OK;
136 uint32 bytes_read = 0;
137
138 while (bytes_read < bytes_to_read) {
139 rv = sock_->Read(buf, buf_len, callback);
140 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
141
142 if (rv == ERR_IO_PENDING)
143 rv = callback->WaitForResult();
144
145 EXPECT_GE(rv, 0);
146 bytes_read += rv;
147 }
148
149 return static_cast<int>(bytes_read);
150 }
151
SendClientRequest()152 void TransportClientSocketTest::SendClientRequest() {
153 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
154 scoped_refptr<IOBuffer> request_buffer(
155 new IOBuffer(arraysize(request_text) - 1));
156 TestCompletionCallback callback;
157 int rv;
158
159 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
160 rv = sock_->Write(request_buffer, arraysize(request_text) - 1, &callback);
161 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
162
163 if (rv == ERR_IO_PENDING) {
164 rv = callback.WaitForResult();
165 EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1));
166 }
167 }
168
169 // TODO(leighton): Add SCTP to this list when it is ready.
170 INSTANTIATE_TEST_CASE_P(ClientSocket,
171 TransportClientSocketTest,
172 ::testing::Values(TCP));
173
TEST_P(TransportClientSocketTest,Connect)174 TEST_P(TransportClientSocketTest, Connect) {
175 TestCompletionCallback callback;
176 EXPECT_FALSE(sock_->IsConnected());
177
178 int rv = sock_->Connect(&callback);
179
180 net::CapturingNetLog::EntryList net_log_entries;
181 net_log_.GetEntries(&net_log_entries);
182 EXPECT_TRUE(net::LogContainsBeginEvent(
183 net_log_entries, 0, net::NetLog::TYPE_SOCKET_ALIVE));
184 EXPECT_TRUE(net::LogContainsBeginEvent(
185 net_log_entries, 1, net::NetLog::TYPE_TCP_CONNECT));
186 if (rv != OK) {
187 ASSERT_EQ(rv, ERR_IO_PENDING);
188 rv = callback.WaitForResult();
189 EXPECT_EQ(rv, OK);
190 }
191
192 EXPECT_TRUE(sock_->IsConnected());
193 net_log_.GetEntries(&net_log_entries);
194 EXPECT_TRUE(net::LogContainsEndEvent(
195 net_log_entries, -1, net::NetLog::TYPE_TCP_CONNECT));
196
197 sock_->Disconnect();
198 EXPECT_FALSE(sock_->IsConnected());
199 }
200
TEST_P(TransportClientSocketTest,IsConnected)201 TEST_P(TransportClientSocketTest, IsConnected) {
202 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
203 TestCompletionCallback callback;
204 uint32 bytes_read;
205
206 EXPECT_FALSE(sock_->IsConnected());
207 EXPECT_FALSE(sock_->IsConnectedAndIdle());
208 int rv = sock_->Connect(&callback);
209 if (rv != OK) {
210 ASSERT_EQ(rv, ERR_IO_PENDING);
211 rv = callback.WaitForResult();
212 EXPECT_EQ(rv, OK);
213 }
214 EXPECT_TRUE(sock_->IsConnected());
215 EXPECT_TRUE(sock_->IsConnectedAndIdle());
216
217 // Send the request and wait for the server to respond.
218 SendClientRequest();
219
220 // Drain a single byte so we know we've received some data.
221 bytes_read = DrainClientSocket(buf, 1, 1, &callback);
222 ASSERT_EQ(bytes_read, 1u);
223
224 // Socket should be considered connected, but not idle, due to
225 // pending data.
226 EXPECT_TRUE(sock_->IsConnected());
227 EXPECT_FALSE(sock_->IsConnectedAndIdle());
228
229 bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 2,
230 &callback);
231 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2);
232
233 // After draining the data, the socket should be back to connected
234 // and idle.
235 EXPECT_TRUE(sock_->IsConnected());
236 EXPECT_TRUE(sock_->IsConnectedAndIdle());
237
238 // This time close the server socket immediately after the server response.
239 set_close_server_socket_on_next_send(true);
240 SendClientRequest();
241
242 bytes_read = DrainClientSocket(buf, 1, 1, &callback);
243 ASSERT_EQ(bytes_read, 1u);
244
245 // As above because of data.
246 EXPECT_TRUE(sock_->IsConnected());
247 EXPECT_FALSE(sock_->IsConnectedAndIdle());
248
249 bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 2,
250 &callback);
251 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2);
252
253 // Once the data is drained, the socket should now be seen as
254 // closed.
255 EXPECT_FALSE(sock_->IsConnected());
256 EXPECT_FALSE(sock_->IsConnectedAndIdle());
257 }
258
TEST_P(TransportClientSocketTest,Read)259 TEST_P(TransportClientSocketTest, Read) {
260 TestCompletionCallback callback;
261 int rv = sock_->Connect(&callback);
262 if (rv != OK) {
263 ASSERT_EQ(rv, ERR_IO_PENDING);
264
265 rv = callback.WaitForResult();
266 EXPECT_EQ(rv, OK);
267 }
268 SendClientRequest();
269
270 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
271 uint32 bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 1,
272 &callback);
273 ASSERT_EQ(bytes_read, arraysize(kServerReply) - 1);
274
275 // All data has been read now. Read once more to force an ERR_IO_PENDING, and
276 // then close the server socket, and note the close.
277
278 rv = sock_->Read(buf, 4096, &callback);
279 ASSERT_EQ(ERR_IO_PENDING, rv);
280 CloseServerSocket();
281 EXPECT_EQ(0, callback.WaitForResult());
282 }
283
TEST_P(TransportClientSocketTest,Read_SmallChunks)284 TEST_P(TransportClientSocketTest, Read_SmallChunks) {
285 TestCompletionCallback callback;
286 int rv = sock_->Connect(&callback);
287 if (rv != OK) {
288 ASSERT_EQ(rv, ERR_IO_PENDING);
289
290 rv = callback.WaitForResult();
291 EXPECT_EQ(rv, OK);
292 }
293 SendClientRequest();
294
295 scoped_refptr<IOBuffer> buf(new IOBuffer(1));
296 uint32 bytes_read = 0;
297 while (bytes_read < arraysize(kServerReply) - 1) {
298 rv = sock_->Read(buf, 1, &callback);
299 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
300
301 if (rv == ERR_IO_PENDING)
302 rv = callback.WaitForResult();
303
304 ASSERT_EQ(1, rv);
305 bytes_read += rv;
306 }
307
308 // All data has been read now. Read once more to force an ERR_IO_PENDING, and
309 // then close the server socket, and note the close.
310
311 rv = sock_->Read(buf, 1, &callback);
312 ASSERT_EQ(ERR_IO_PENDING, rv);
313 CloseServerSocket();
314 EXPECT_EQ(0, callback.WaitForResult());
315 }
316
TEST_P(TransportClientSocketTest,Read_Interrupted)317 TEST_P(TransportClientSocketTest, Read_Interrupted) {
318 TestCompletionCallback callback;
319 int rv = sock_->Connect(&callback);
320 if (rv != OK) {
321 ASSERT_EQ(ERR_IO_PENDING, rv);
322
323 rv = callback.WaitForResult();
324 EXPECT_EQ(rv, OK);
325 }
326 SendClientRequest();
327
328 // Do a partial read and then exit. This test should not crash!
329 scoped_refptr<IOBuffer> buf(new IOBuffer(16));
330 rv = sock_->Read(buf, 16, &callback);
331 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
332
333 if (rv == ERR_IO_PENDING)
334 rv = callback.WaitForResult();
335
336 EXPECT_NE(0, rv);
337 }
338
TEST_P(TransportClientSocketTest,DISABLED_FullDuplex_ReadFirst)339 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_ReadFirst) {
340 TestCompletionCallback callback;
341 int rv = sock_->Connect(&callback);
342 if (rv != OK) {
343 ASSERT_EQ(rv, ERR_IO_PENDING);
344
345 rv = callback.WaitForResult();
346 EXPECT_EQ(rv, OK);
347 }
348
349 // Read first. There's no data, so it should return ERR_IO_PENDING.
350 const int kBufLen = 4096;
351 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
352 rv = sock_->Read(buf, kBufLen, &callback);
353 EXPECT_EQ(ERR_IO_PENDING, rv);
354
355 PauseServerReads();
356 const int kWriteBufLen = 64 * 1024;
357 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
358 char* request_data = request_buffer->data();
359 memset(request_data, 'A', kWriteBufLen);
360 TestCompletionCallback write_callback;
361
362 while (true) {
363 rv = sock_->Write(request_buffer, kWriteBufLen, &write_callback);
364 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
365
366 if (rv == ERR_IO_PENDING) {
367 ResumeServerReads();
368 rv = write_callback.WaitForResult();
369 break;
370 }
371 }
372
373 // At this point, both read and write have returned ERR_IO_PENDING, and the
374 // write callback has executed. We wait for the read callback to run now to
375 // make sure that the socket can handle full duplex communications.
376
377 rv = callback.WaitForResult();
378 EXPECT_GE(rv, 0);
379 }
380
TEST_P(TransportClientSocketTest,DISABLED_FullDuplex_WriteFirst)381 TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_WriteFirst) {
382 TestCompletionCallback callback;
383 int rv = sock_->Connect(&callback);
384 if (rv != OK) {
385 ASSERT_EQ(ERR_IO_PENDING, rv);
386
387 rv = callback.WaitForResult();
388 EXPECT_EQ(OK, rv);
389 }
390
391 PauseServerReads();
392 const int kWriteBufLen = 64 * 1024;
393 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
394 char* request_data = request_buffer->data();
395 memset(request_data, 'A', kWriteBufLen);
396 TestCompletionCallback write_callback;
397
398 while (true) {
399 rv = sock_->Write(request_buffer, kWriteBufLen, &write_callback);
400 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
401
402 if (rv == ERR_IO_PENDING)
403 break;
404 }
405
406 // Now we have the Write() blocked on ERR_IO_PENDING. It's time to force the
407 // Read() to block on ERR_IO_PENDING too.
408
409 const int kBufLen = 4096;
410 scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
411 while (true) {
412 rv = sock_->Read(buf, kBufLen, &callback);
413 ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
414 if (rv == ERR_IO_PENDING)
415 break;
416 }
417
418 // At this point, both read and write have returned ERR_IO_PENDING. Now we
419 // run the write and read callbacks to make sure they can handle full duplex
420 // communications.
421
422 ResumeServerReads();
423 rv = write_callback.WaitForResult();
424 EXPECT_GE(rv, 0);
425
426 // It's possible the read is blocked because it's already read all the data.
427 // Close the server socket, so there will at least be a 0-byte read.
428 CloseServerSocket();
429
430 rv = callback.WaitForResult();
431 EXPECT_GE(rv, 0);
432 }
433
434 } // namespace
435
436 } // namespace net
437