• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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