blob: 1cd72102fb27e9598cb90c390c8aeb7f6be86adb [file] [log] [blame]
[email protected]a2006ece2010-04-23 16:44:021// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]f7984fc62009-06-22 23:26:445#include "net/socket/ssl_client_socket.h"
6
initial.commit586acc5fe2008-07-26 22:42:527#include "net/base/address_list.h"
initial.commit586acc5fe2008-07-26 22:42:528#include "net/base/host_resolver.h"
[email protected]597cf6e2009-05-29 09:43:269#include "net/base/io_buffer.h"
[email protected]9e743cd2010-03-16 07:03:5310#include "net/base/net_log.h"
11#include "net/base/net_log_unittest.h"
[email protected]7b822b2b2008-08-05 00:15:4512#include "net/base/net_errors.h"
[email protected]aaead502008-10-15 00:20:1113#include "net/base/ssl_config_service.h"
initial.commit586acc5fe2008-07-26 22:42:5214#include "net/base/test_completion_callback.h"
[email protected]f7984fc62009-06-22 23:26:4415#include "net/socket/client_socket_factory.h"
[email protected]39afe642010-04-29 14:55:1816#include "net/socket/socket_test_util.h"
[email protected]f7984fc62009-06-22 23:26:4417#include "net/socket/tcp_client_socket.h"
[email protected]1b9565c2010-07-21 01:19:3118#include "net/test/test_server.h"
initial.commit586acc5fe2008-07-26 22:42:5219#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1520#include "testing/platform_test.h"
initial.commit586acc5fe2008-07-26 22:42:5221
22//-----------------------------------------------------------------------------
23
[email protected]aaead502008-10-15 00:20:1124const net::SSLConfig kDefaultSSLConfig;
[email protected]c5949a32008-10-08 17:28:2325
[email protected]b75523f2008-10-17 14:49:0726class SSLClientSocketTest : public PlatformTest {
[email protected]aaead502008-10-15 00:20:1127 public:
28 SSLClientSocketTest()
[email protected]73c45322010-10-01 23:57:5429 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) {
[email protected]73e0bba2009-02-19 22:57:0930 }
31
[email protected]aaead502008-10-15 00:20:1132 protected:
33 net::ClientSocketFactory* socket_factory_;
initial.commit586acc5fe2008-07-26 22:42:5234};
35
initial.commit586acc5fe2008-07-26 22:42:5236//-----------------------------------------------------------------------------
37
[email protected]6a47ac82010-10-08 14:39:3038// LogContainsSSLConnectEndEvent returns true if the given index in the given
39// log is an SSL connect end event. The NSS sockets will cork in an attempt to
40// merge the first application data record with the Finished message when false
41// starting. However, in order to avoid the server timing out the handshake,
42// they'll give up waiting for application data and send the Finished after a
43// timeout. This means that an SSL connect end event may appear as a socket
44// write.
45static bool LogContainsSSLConnectEndEvent(
46 const net::CapturingNetLog::EntryList& log, int i) {
[email protected]7f2fff12010-10-09 18:42:1147 return net::LogContainsEndEvent(log, -1, net::NetLog::TYPE_SSL_CONNECT) ||
48 net::LogContainsEvent(log, -1, net::NetLog::TYPE_SOCKET_BYTES_SENT,
49 net::NetLog::PHASE_NONE);
[email protected]6a47ac82010-10-08 14:39:3050};
51
[email protected]010e27e2009-08-27 17:49:4152TEST_F(SSLClientSocketTest, Connect) {
[email protected]95409e12010-08-17 20:07:1153 net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
54 ASSERT_TRUE(test_server.Start());
[email protected]73e0bba2009-02-19 22:57:0955
initial.commit586acc5fe2008-07-26 22:42:5256 net::AddressList addr;
[email protected]95409e12010-08-17 20:07:1157 ASSERT_TRUE(test_server.GetAddressList(&addr));
58
initial.commit586acc5fe2008-07-26 22:42:5259 TestCompletionCallback callback;
[email protected]a2006ece2010-04-23 16:44:0260 net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
[email protected]0a0b7682010-08-25 17:08:0761 net::ClientSocket* transport = new net::TCPClientSocket(
62 addr, &log, net::NetLog::Source());
[email protected]95409e12010-08-17 20:07:1163 int rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:3364 if (rv == net::ERR_IO_PENDING)
65 rv = callback.WaitForResult();
66 EXPECT_EQ(net::OK, rv);
67
[email protected]aaead502008-10-15 00:20:1168 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:3369 socket_factory_->CreateSSLClientSocket(transport,
[email protected]7ab5bbd12010-10-19 13:33:2170 test_server.host_port_pair().host(), kDefaultSSLConfig,
71 NULL /* ssl_host_info */));
initial.commit586acc5fe2008-07-26 22:42:5272
[email protected]aaead502008-10-15 00:20:1173 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:5274
[email protected]a2006ece2010-04-23 16:44:0275 rv = sock->Connect(&callback);
[email protected]eb8605c2010-05-21 22:17:4776 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]06650c52010-06-03 00:49:1777 log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT));
[email protected]7b822b2b2008-08-05 00:15:4578 if (rv != net::OK) {
79 ASSERT_EQ(net::ERR_IO_PENDING, rv);
[email protected]73e0bba2009-02-19 22:57:0980 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:4681 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:5382 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
initial.commit586acc5fe2008-07-26 22:42:5283
[email protected]7b822b2b2008-08-05 00:15:4584 rv = callback.WaitForResult();
85 EXPECT_EQ(net::OK, rv);
86 }
initial.commit586acc5fe2008-07-26 22:42:5287
[email protected]aaead502008-10-15 00:20:1188 EXPECT_TRUE(sock->IsConnected());
[email protected]6a47ac82010-10-08 14:39:3089 EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1));
initial.commit586acc5fe2008-07-26 22:42:5290
[email protected]aaead502008-10-15 00:20:1191 sock->Disconnect();
92 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:5293}
94
[email protected]7f2fff12010-10-09 18:42:1195TEST_F(SSLClientSocketTest, ConnectExpired) {
[email protected]347599952010-10-28 11:57:3696 net::TestServer::HTTPSOptions https_options(
97 net::TestServer::HTTPSOptions::CERT_EXPIRED);
98 net::TestServer test_server(https_options, FilePath());
[email protected]95409e12010-08-17 20:07:1199 ASSERT_TRUE(test_server.Start());
[email protected]73e0bba2009-02-19 22:57:09100
initial.commit586acc5fe2008-07-26 22:42:52101 net::AddressList addr;
[email protected]95409e12010-08-17 20:07:11102 ASSERT_TRUE(test_server.GetAddressList(&addr));
103
initial.commit586acc5fe2008-07-26 22:42:52104 TestCompletionCallback callback;
[email protected]a2006ece2010-04-23 16:44:02105 net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
[email protected]0a0b7682010-08-25 17:08:07106 net::ClientSocket* transport = new net::TCPClientSocket(
107 addr, &log, net::NetLog::Source());
[email protected]95409e12010-08-17 20:07:11108 int rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33109 if (rv == net::ERR_IO_PENDING)
110 rv = callback.WaitForResult();
111 EXPECT_EQ(net::OK, rv);
112
[email protected]73e0bba2009-02-19 22:57:09113 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33114 socket_factory_->CreateSSLClientSocket(transport,
[email protected]7ab5bbd12010-10-19 13:33:21115 test_server.host_port_pair().host(), kDefaultSSLConfig,
116 NULL /* ssl_host_info */));
[email protected]73e0bba2009-02-19 22:57:09117
118 EXPECT_FALSE(sock->IsConnected());
119
[email protected]a2006ece2010-04-23 16:44:02120 rv = sock->Connect(&callback);
[email protected]eb8605c2010-05-21 22:17:47121 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]06650c52010-06-03 00:49:17122 log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09123 if (rv != net::OK) {
124 ASSERT_EQ(net::ERR_IO_PENDING, rv);
125 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:46126 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53127 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09128
129 rv = callback.WaitForResult();
130 EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv);
131 }
132
[email protected]bacff652009-03-31 17:50:33133 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
134 // the socket when it encounters an error, whereas other implementations
135 // leave it connected.
[email protected]6a47ac82010-10-08 14:39:30136 EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1));
[email protected]73e0bba2009-02-19 22:57:09137}
138
[email protected]7f2fff12010-10-09 18:42:11139TEST_F(SSLClientSocketTest, ConnectMismatched) {
[email protected]347599952010-10-28 11:57:36140 net::TestServer::HTTPSOptions https_options(
141 net::TestServer::HTTPSOptions::CERT_MISMATCHED_NAME);
142 net::TestServer test_server(https_options, FilePath());
[email protected]95409e12010-08-17 20:07:11143 ASSERT_TRUE(test_server.Start());
[email protected]73e0bba2009-02-19 22:57:09144
145 net::AddressList addr;
[email protected]95409e12010-08-17 20:07:11146 ASSERT_TRUE(test_server.GetAddressList(&addr));
147
[email protected]73e0bba2009-02-19 22:57:09148 TestCompletionCallback callback;
[email protected]a2006ece2010-04-23 16:44:02149 net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
[email protected]0a0b7682010-08-25 17:08:07150 net::ClientSocket* transport = new net::TCPClientSocket(
151 addr, &log, net::NetLog::Source());
[email protected]95409e12010-08-17 20:07:11152 int rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33153 if (rv == net::ERR_IO_PENDING)
154 rv = callback.WaitForResult();
155 EXPECT_EQ(net::OK, rv);
156
[email protected]73e0bba2009-02-19 22:57:09157 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33158 socket_factory_->CreateSSLClientSocket(transport,
[email protected]7ab5bbd12010-10-19 13:33:21159 test_server.host_port_pair().host(), kDefaultSSLConfig,
160 NULL /* ssl_host_info */));
[email protected]73e0bba2009-02-19 22:57:09161
162 EXPECT_FALSE(sock->IsConnected());
163
[email protected]a2006ece2010-04-23 16:44:02164 rv = sock->Connect(&callback);
[email protected]4b32be92010-05-20 03:21:42165
[email protected]eb8605c2010-05-21 22:17:47166 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]06650c52010-06-03 00:49:17167 log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09168 if (rv != net::ERR_CERT_COMMON_NAME_INVALID) {
169 ASSERT_EQ(net::ERR_IO_PENDING, rv);
170 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:46171 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53172 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09173
174 rv = callback.WaitForResult();
175 EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv);
176 }
177
[email protected]bacff652009-03-31 17:50:33178 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
179 // the socket when it encounters an error, whereas other implementations
180 // leave it connected.
[email protected]6a47ac82010-10-08 14:39:30181 EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1));
[email protected]73e0bba2009-02-19 22:57:09182}
183
[email protected]65a3b912010-08-21 05:46:58184// Attempt to connect to a page which requests a client certificate. It should
185// return an error code on connect.
[email protected]2fbd3a72010-10-27 21:20:18186// Flaky: http://crbug.com/54445
[email protected]308a7302010-09-03 21:33:58187TEST_F(SSLClientSocketTest, FLAKY_ConnectClientAuthCertRequested) {
[email protected]347599952010-10-28 11:57:36188 net::TestServer::HTTPSOptions https_options;
189 https_options.request_client_certificate = true;
190 net::TestServer test_server(https_options, FilePath());
[email protected]95409e12010-08-17 20:07:11191 ASSERT_TRUE(test_server.Start());
[email protected]8df162a2010-08-07 01:10:02192
193 net::AddressList addr;
[email protected]95409e12010-08-17 20:07:11194 ASSERT_TRUE(test_server.GetAddressList(&addr));
195
[email protected]8df162a2010-08-07 01:10:02196 TestCompletionCallback callback;
[email protected]8df162a2010-08-07 01:10:02197 net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
[email protected]0a0b7682010-08-25 17:08:07198 net::ClientSocket* transport = new net::TCPClientSocket(
199 addr, &log, net::NetLog::Source());
[email protected]95409e12010-08-17 20:07:11200 int rv = transport->Connect(&callback);
[email protected]8df162a2010-08-07 01:10:02201 if (rv == net::ERR_IO_PENDING)
202 rv = callback.WaitForResult();
203 EXPECT_EQ(net::OK, rv);
204
205 scoped_ptr<net::SSLClientSocket> sock(
206 socket_factory_->CreateSSLClientSocket(transport,
[email protected]7ab5bbd12010-10-19 13:33:21207 test_server.host_port_pair().host(), kDefaultSSLConfig,
208 NULL /* ssl_host_info */));
[email protected]8df162a2010-08-07 01:10:02209
210 EXPECT_FALSE(sock->IsConnected());
211
212 rv = sock->Connect(&callback);
213 EXPECT_TRUE(net::LogContainsBeginEvent(
214 log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT));
215 if (rv != net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
216 ASSERT_EQ(net::ERR_IO_PENDING, rv);
217 EXPECT_FALSE(sock->IsConnected());
218 EXPECT_FALSE(net::LogContainsEndEvent(
219 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
220
221 rv = callback.WaitForResult();
222 EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
223 }
224
225 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
226 // the socket when it encounters an error, whereas other implementations
227 // leave it connected.
[email protected]6a47ac82010-10-08 14:39:30228 EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1));
[email protected]8df162a2010-08-07 01:10:02229}
230
[email protected]65a3b912010-08-21 05:46:58231// Connect to a server requesting optional client authentication. Send it a
232// null certificate. It should allow the connection.
233//
234// TODO(davidben): Also test providing an actual certificate.
235TEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) {
[email protected]347599952010-10-28 11:57:36236 net::TestServer::HTTPSOptions https_options;
237 https_options.request_client_certificate = true;
238 net::TestServer test_server(https_options, FilePath());
[email protected]65a3b912010-08-21 05:46:58239 ASSERT_TRUE(test_server.Start());
240
241 net::AddressList addr;
242 ASSERT_TRUE(test_server.GetAddressList(&addr));
243
244 TestCompletionCallback callback;
245 net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
[email protected]0a0b7682010-08-25 17:08:07246 net::ClientSocket* transport = new net::TCPClientSocket(
247 addr, &log, net::NetLog::Source());
[email protected]65a3b912010-08-21 05:46:58248 int rv = transport->Connect(&callback);
249 if (rv == net::ERR_IO_PENDING)
250 rv = callback.WaitForResult();
251 EXPECT_EQ(net::OK, rv);
252
253 net::SSLConfig ssl_config = kDefaultSSLConfig;
254 ssl_config.send_client_cert = true;
255 ssl_config.client_cert = NULL;
256
257 scoped_ptr<net::SSLClientSocket> sock(
258 socket_factory_->CreateSSLClientSocket(transport,
[email protected]7ab5bbd12010-10-19 13:33:21259 test_server.host_port_pair().host(), ssl_config,
260 NULL /* ssl_host_info */));
[email protected]65a3b912010-08-21 05:46:58261
262 EXPECT_FALSE(sock->IsConnected());
263
264 // Our test server accepts certificate-less connections.
265 // TODO(davidben): Add a test which requires them and verify the error.
266 rv = sock->Connect(&callback);
267 EXPECT_TRUE(net::LogContainsBeginEvent(
268 log.entries(), 5, net::NetLog::TYPE_SSL_CONNECT));
269 if (rv != net::OK) {
270 ASSERT_EQ(net::ERR_IO_PENDING, rv);
271 EXPECT_FALSE(sock->IsConnected());
272 EXPECT_FALSE(net::LogContainsEndEvent(
273 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
274
275 rv = callback.WaitForResult();
276 EXPECT_EQ(net::OK, rv);
277 }
278
279 EXPECT_TRUE(sock->IsConnected());
[email protected]6a47ac82010-10-08 14:39:30280 EXPECT_TRUE(LogContainsSSLConnectEndEvent(log.entries(), -1));
[email protected]65a3b912010-08-21 05:46:58281
282 sock->Disconnect();
283 EXPECT_FALSE(sock->IsConnected());
284}
285
[email protected]b2197852009-02-19 23:27:33286// TODO(wtc): Add unit tests for IsConnectedAndIdle:
287// - Server closes an SSL connection (with a close_notify alert message).
288// - Server closes the underlying TCP connection directly.
289// - Server sends data unexpectedly.
290
[email protected]e3eb8f82010-09-21 15:25:15291TEST_F(SSLClientSocketTest, Read) {
[email protected]95409e12010-08-17 20:07:11292 net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
293 ASSERT_TRUE(test_server.Start());
[email protected]73e0bba2009-02-19 22:57:09294
295 net::AddressList addr;
[email protected]95409e12010-08-17 20:07:11296 ASSERT_TRUE(test_server.GetAddressList(&addr));
297
[email protected]73e0bba2009-02-19 22:57:09298 TestCompletionCallback callback;
[email protected]0a0b7682010-08-25 17:08:07299 net::ClientSocket* transport = new net::TCPClientSocket(
300 addr, NULL, net::NetLog::Source());
[email protected]95409e12010-08-17 20:07:11301 int rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33302 if (rv == net::ERR_IO_PENDING)
303 rv = callback.WaitForResult();
304 EXPECT_EQ(net::OK, rv);
305
[email protected]aaead502008-10-15 00:20:11306 scoped_ptr<net::SSLClientSocket> sock(
[email protected]73c45322010-10-01 23:57:54307 socket_factory_->CreateSSLClientSocket(
308 transport,
309 test_server.host_port_pair().host(),
[email protected]7ab5bbd12010-10-19 13:33:21310 kDefaultSSLConfig,
311 NULL /* ssl_host_info */));
initial.commit586acc5fe2008-07-26 22:42:52312
[email protected]a2006ece2010-04-23 16:44:02313 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45314 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07315 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52316
[email protected]7b822b2b2008-08-05 00:15:45317 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07318 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45319 }
[email protected]b43c97c2008-10-22 19:50:58320 EXPECT_TRUE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52321
[email protected]e3eb8f82010-09-21 15:25:15322 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25323 scoped_refptr<net::IOBuffer> request_buffer =
[email protected]e3eb8f82010-09-21 15:25:15324 new net::IOBuffer(arraysize(request_text) - 1);
325 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
[email protected]ffeb0882009-04-30 21:51:25326
[email protected]e3eb8f82010-09-21 15:25:15327 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52328 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
329
[email protected]914286d62009-12-10 23:06:44330 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52331 rv = callback.WaitForResult();
[email protected]e3eb8f82010-09-21 15:25:15332 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52333
[email protected]ffeb0882009-04-30 21:51:25334 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(4096);
initial.commit586acc5fe2008-07-26 22:42:52335 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25336 rv = sock->Read(buf, 4096, &callback);
initial.commit586acc5fe2008-07-26 22:42:52337 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
338
339 if (rv == net::ERR_IO_PENDING)
340 rv = callback.WaitForResult();
341
[email protected]7b822b2b2008-08-05 00:15:45342 EXPECT_GE(rv, 0);
343 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52344 break;
345 }
346}
347
[email protected]914286d62009-12-10 23:06:44348// Test the full duplex mode, with Read and Write pending at the same time.
349// This test also serves as a regression test for http://crbug.com/29815.
350TEST_F(SSLClientSocketTest, Read_FullDuplex) {
[email protected]95409e12010-08-17 20:07:11351 net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
352 ASSERT_TRUE(test_server.Start());
[email protected]914286d62009-12-10 23:06:44353
354 net::AddressList addr;
[email protected]95409e12010-08-17 20:07:11355 ASSERT_TRUE(test_server.GetAddressList(&addr));
356
[email protected]914286d62009-12-10 23:06:44357 TestCompletionCallback callback; // Used for everything except Write.
358 TestCompletionCallback callback2; // Used for Write only.
359
[email protected]0a0b7682010-08-25 17:08:07360 net::ClientSocket* transport = new net::TCPClientSocket(
361 addr, NULL, net::NetLog::Source());
[email protected]95409e12010-08-17 20:07:11362 int rv = transport->Connect(&callback);
[email protected]914286d62009-12-10 23:06:44363 if (rv == net::ERR_IO_PENDING)
364 rv = callback.WaitForResult();
365 EXPECT_EQ(net::OK, rv);
366
367 scoped_ptr<net::SSLClientSocket> sock(
[email protected]73c45322010-10-01 23:57:54368 socket_factory_->CreateSSLClientSocket(
369 transport,
370 test_server.host_port_pair().host(),
[email protected]7ab5bbd12010-10-19 13:33:21371 kDefaultSSLConfig,
372 NULL /* ssl_host_info */));
[email protected]914286d62009-12-10 23:06:44373
[email protected]a2006ece2010-04-23 16:44:02374 rv = sock->Connect(&callback);
[email protected]914286d62009-12-10 23:06:44375 if (rv != net::OK) {
376 ASSERT_EQ(net::ERR_IO_PENDING, rv);
377
378 rv = callback.WaitForResult();
379 EXPECT_EQ(net::OK, rv);
380 }
381 EXPECT_TRUE(sock->IsConnected());
382
383 // Issue a "hanging" Read first.
384 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(4096);
385 rv = sock->Read(buf, 4096, &callback);
386 // We haven't written the request, so there should be no response yet.
387 ASSERT_EQ(net::ERR_IO_PENDING, rv);
388
389 // Write the request.
390 // The request is padded with a User-Agent header to a size that causes the
391 // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around.
392 // This tests the fix for http://crbug.com/29815.
393 std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
394 for (int i = 0; i < 3800; ++i)
395 request_text.push_back('*');
396 request_text.append("\r\n\r\n");
397 scoped_refptr<net::IOBuffer> request_buffer =
398 new net::StringIOBuffer(request_text);
399
400 rv = sock->Write(request_buffer, request_text.size(), &callback2);
401 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
402
403 if (rv == net::ERR_IO_PENDING)
404 rv = callback2.WaitForResult();
405 EXPECT_EQ(static_cast<int>(request_text.size()), rv);
406
407 // Now get the Read result.
408 rv = callback.WaitForResult();
409 EXPECT_GT(rv, 0);
410}
411
[email protected]010e27e2009-08-27 17:49:41412TEST_F(SSLClientSocketTest, Read_SmallChunks) {
[email protected]95409e12010-08-17 20:07:11413 net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
414 ASSERT_TRUE(test_server.Start());
[email protected]73e0bba2009-02-19 22:57:09415
initial.commit586acc5fe2008-07-26 22:42:52416 net::AddressList addr;
[email protected]95409e12010-08-17 20:07:11417 ASSERT_TRUE(test_server.GetAddressList(&addr));
418
initial.commit586acc5fe2008-07-26 22:42:52419 TestCompletionCallback callback;
[email protected]0a0b7682010-08-25 17:08:07420 net::ClientSocket* transport = new net::TCPClientSocket(
421 addr, NULL, net::NetLog::Source());
[email protected]95409e12010-08-17 20:07:11422 int rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33423 if (rv == net::ERR_IO_PENDING)
424 rv = callback.WaitForResult();
425 EXPECT_EQ(net::OK, rv);
426
[email protected]aaead502008-10-15 00:20:11427 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33428 socket_factory_->CreateSSLClientSocket(transport,
[email protected]7ab5bbd12010-10-19 13:33:21429 test_server.host_port_pair().host(), kDefaultSSLConfig,
430 NULL /* ssl_host_info */));
initial.commit586acc5fe2008-07-26 22:42:52431
[email protected]a2006ece2010-04-23 16:44:02432 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45433 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07434 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52435
[email protected]7b822b2b2008-08-05 00:15:45436 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07437 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45438 }
initial.commit586acc5fe2008-07-26 22:42:52439
440 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25441 scoped_refptr<net::IOBuffer> request_buffer =
442 new net::IOBuffer(arraysize(request_text) - 1);
443 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
444
445 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52446 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
447
[email protected]914286d62009-12-10 23:06:44448 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52449 rv = callback.WaitForResult();
[email protected]914286d62009-12-10 23:06:44450 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52451
[email protected]ffeb0882009-04-30 21:51:25452 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(1);
initial.commit586acc5fe2008-07-26 22:42:52453 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25454 rv = sock->Read(buf, 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52455 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
456
457 if (rv == net::ERR_IO_PENDING)
458 rv = callback.WaitForResult();
459
[email protected]7b822b2b2008-08-05 00:15:45460 EXPECT_GE(rv, 0);
461 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52462 break;
463 }
464}
465
[email protected]010e27e2009-08-27 17:49:41466TEST_F(SSLClientSocketTest, Read_Interrupted) {
[email protected]95409e12010-08-17 20:07:11467 net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
468 ASSERT_TRUE(test_server.Start());
[email protected]73e0bba2009-02-19 22:57:09469
initial.commit586acc5fe2008-07-26 22:42:52470 net::AddressList addr;
[email protected]95409e12010-08-17 20:07:11471 ASSERT_TRUE(test_server.GetAddressList(&addr));
472
initial.commit586acc5fe2008-07-26 22:42:52473 TestCompletionCallback callback;
[email protected]0a0b7682010-08-25 17:08:07474 net::ClientSocket* transport = new net::TCPClientSocket(
475 addr, NULL, net::NetLog::Source());
[email protected]95409e12010-08-17 20:07:11476 int rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33477 if (rv == net::ERR_IO_PENDING)
478 rv = callback.WaitForResult();
479 EXPECT_EQ(net::OK, rv);
480
[email protected]aaead502008-10-15 00:20:11481 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33482 socket_factory_->CreateSSLClientSocket(transport,
[email protected]7ab5bbd12010-10-19 13:33:21483 test_server.host_port_pair().host(), kDefaultSSLConfig,
484 NULL /* ssl_host_info */));
initial.commit586acc5fe2008-07-26 22:42:52485
[email protected]a2006ece2010-04-23 16:44:02486 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45487 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07488 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52489
[email protected]7b822b2b2008-08-05 00:15:45490 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07491 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45492 }
initial.commit586acc5fe2008-07-26 22:42:52493
494 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25495 scoped_refptr<net::IOBuffer> request_buffer =
496 new net::IOBuffer(arraysize(request_text) - 1);
497 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
498
499 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52500 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
501
[email protected]914286d62009-12-10 23:06:44502 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52503 rv = callback.WaitForResult();
[email protected]914286d62009-12-10 23:06:44504 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52505
506 // Do a partial read and then exit. This test should not crash!
[email protected]ffeb0882009-04-30 21:51:25507 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(512);
508 rv = sock->Read(buf, 512, &callback);
[email protected]914286d62009-12-10 23:06:44509 EXPECT_TRUE(rv > 0 || rv == net::ERR_IO_PENDING);
initial.commit586acc5fe2008-07-26 22:42:52510
511 if (rv == net::ERR_IO_PENDING)
512 rv = callback.WaitForResult();
513
[email protected]914286d62009-12-10 23:06:44514 EXPECT_GT(rv, 0);
initial.commit586acc5fe2008-07-26 22:42:52515}
[email protected]39afe642010-04-29 14:55:18516
[email protected]39afe642010-04-29 14:55:18517// Regression test for http://crbug.com/42538
518TEST_F(SSLClientSocketTest, PrematureApplicationData) {
[email protected]95409e12010-08-17 20:07:11519 net::TestServer test_server(net::TestServer::TYPE_HTTPS, FilePath());
520 ASSERT_TRUE(test_server.Start());
521
[email protected]39afe642010-04-29 14:55:18522 net::AddressList addr;
523 TestCompletionCallback callback;
524
525 static const unsigned char application_data[] = {
526 0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b,
527 0xc2, 0xf8, 0xb2, 0xc1, 0x56, 0x42, 0xb9, 0x57, 0x7f, 0xde, 0x87, 0x46,
528 0xf7, 0xa3, 0x52, 0x42, 0x21, 0xf0, 0x13, 0x1c, 0x9c, 0x83, 0x88, 0xd6,
529 0x93, 0x0c, 0xf6, 0x36, 0x30, 0x05, 0x7e, 0x20, 0xb5, 0xb5, 0x73, 0x36,
530 0x53, 0x83, 0x0a, 0xfc, 0x17, 0x63, 0xbf, 0xa0, 0xe4, 0x42, 0x90, 0x0d,
531 0x2f, 0x18, 0x6d, 0x20, 0xd8, 0x36, 0x3f, 0xfc, 0xe6, 0x01, 0xfa, 0x0f,
532 0xa5, 0x75, 0x7f, 0x09, 0x00, 0x04, 0x00, 0x16, 0x03, 0x01, 0x11, 0x57,
533 0x0b, 0x00, 0x11, 0x53, 0x00, 0x11, 0x50, 0x00, 0x06, 0x22, 0x30, 0x82,
534 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
535 0x0a
536 };
537
538 // All reads and writes complete synchronously (async=false).
539 net::MockRead data_reads[] = {
540 net::MockRead(false, reinterpret_cast<const char*>(application_data),
541 arraysize(application_data)),
542 net::MockRead(false, net::OK),
543 };
544
545 net::StaticSocketDataProvider data(data_reads, arraysize(data_reads),
546 NULL, 0);
547
548 net::ClientSocket* transport =
549 new net::MockTCPClientSocket(addr, NULL, &data);
550 int rv = transport->Connect(&callback);
551 if (rv == net::ERR_IO_PENDING)
552 rv = callback.WaitForResult();
553 EXPECT_EQ(net::OK, rv);
554
555 scoped_ptr<net::SSLClientSocket> sock(
556 socket_factory_->CreateSSLClientSocket(
[email protected]7ab5bbd12010-10-19 13:33:21557 transport, test_server.host_port_pair().host(), kDefaultSSLConfig,
558 NULL /* ssl_host_info */));
[email protected]39afe642010-04-29 14:55:18559
560 rv = sock->Connect(&callback);
561 EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
562}