blob: 7b297f81521f7181847810f9028d5ea4b8ec6555 [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/ssl_test_util.h"
18#include "net/socket/tcp_client_socket.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]d13c3272010-02-04 00:24:5129 : resolver_(net::CreateSystemHostResolver(NULL)),
[email protected]b59ff372009-07-15 22:04:3230 socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) {
[email protected]73e0bba2009-02-19 22:57:0931 }
32
33 void StartOKServer() {
34 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
35 server_.kHostName, server_.kOKHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2236 FilePath(), server_.GetOKCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0937 ASSERT_TRUE(success);
38 }
39
40 void StartMismatchedServer() {
41 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
42 server_.kMismatchedHostName, server_.kOKHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2243 FilePath(), server_.GetOKCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0944 ASSERT_TRUE(success);
45 }
46
47 void StartExpiredServer() {
48 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
49 server_.kHostName, server_.kBadHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2250 FilePath(), server_.GetExpiredCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0951 ASSERT_TRUE(success);
[email protected]aaead502008-10-15 00:20:1152 }
[email protected]471822ca2009-01-29 11:32:2653
[email protected]aaead502008-10-15 00:20:1154 protected:
[email protected]b59ff372009-07-15 22:04:3255 scoped_refptr<net::HostResolver> resolver_;
[email protected]aaead502008-10-15 00:20:1156 net::ClientSocketFactory* socket_factory_;
[email protected]73e0bba2009-02-19 22:57:0957 net::TestServerLauncher server_;
initial.commit586acc5fe2008-07-26 22:42:5258};
59
initial.commit586acc5fe2008-07-26 22:42:5260//-----------------------------------------------------------------------------
61
[email protected]010e27e2009-08-27 17:49:4162TEST_F(SSLClientSocketTest, Connect) {
[email protected]73e0bba2009-02-19 22:57:0963 StartOKServer();
64
initial.commit586acc5fe2008-07-26 22:42:5265 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:5266 TestCompletionCallback callback;
67
[email protected]2884a462009-06-15 05:08:4268 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]5a1d7ca2010-04-28 20:12:2769 int rv = resolver_->Resolve(info, &addr, NULL, NULL, net::BoundNetLog());
initial.commit586acc5fe2008-07-26 22:42:5270 EXPECT_EQ(net::OK, rv);
71
[email protected]a2006ece2010-04-23 16:44:0272 net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
73 net::ClientSocket* transport = new net::TCPClientSocket(addr, &log);
74 rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:3375 if (rv == net::ERR_IO_PENDING)
76 rv = callback.WaitForResult();
77 EXPECT_EQ(net::OK, rv);
78
[email protected]aaead502008-10-15 00:20:1179 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:3380 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:0981 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:5282
[email protected]aaead502008-10-15 00:20:1183 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:5284
[email protected]a2006ece2010-04-23 16:44:0285 rv = sock->Connect(&callback);
[email protected]e9002a92010-01-29 07:10:4686 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]a2006ece2010-04-23 16:44:0287 log.entries(), 2, net::NetLog::TYPE_SSL_CONNECT));
[email protected]7b822b2b2008-08-05 00:15:4588 if (rv != net::OK) {
89 ASSERT_EQ(net::ERR_IO_PENDING, rv);
[email protected]73e0bba2009-02-19 22:57:0990 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:4691 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:5392 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
initial.commit586acc5fe2008-07-26 22:42:5293
[email protected]7b822b2b2008-08-05 00:15:4594 rv = callback.WaitForResult();
95 EXPECT_EQ(net::OK, rv);
96 }
initial.commit586acc5fe2008-07-26 22:42:5297
[email protected]aaead502008-10-15 00:20:1198 EXPECT_TRUE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:4699 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53100 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
initial.commit586acc5fe2008-07-26 22:42:52101
[email protected]aaead502008-10-15 00:20:11102 sock->Disconnect();
103 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52104}
105
[email protected]010e27e2009-08-27 17:49:41106TEST_F(SSLClientSocketTest, ConnectExpired) {
[email protected]73e0bba2009-02-19 22:57:09107 StartExpiredServer();
108
initial.commit586acc5fe2008-07-26 22:42:52109 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52110 TestCompletionCallback callback;
111
[email protected]2884a462009-06-15 05:08:42112 net::HostResolver::RequestInfo info(server_.kHostName, server_.kBadHTTPSPort);
[email protected]5a1d7ca2010-04-28 20:12:27113 int rv = resolver_->Resolve(info, &addr, NULL, NULL, net::BoundNetLog());
[email protected]73e0bba2009-02-19 22:57:09114 EXPECT_EQ(net::OK, rv);
115
[email protected]a2006ece2010-04-23 16:44:02116 net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
117 net::ClientSocket* transport = new net::TCPClientSocket(addr, &log);
118 rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33119 if (rv == net::ERR_IO_PENDING)
120 rv = callback.WaitForResult();
121 EXPECT_EQ(net::OK, rv);
122
[email protected]73e0bba2009-02-19 22:57:09123 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33124 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09125 server_.kHostName, kDefaultSSLConfig));
126
127 EXPECT_FALSE(sock->IsConnected());
128
[email protected]a2006ece2010-04-23 16:44:02129 rv = sock->Connect(&callback);
[email protected]e9002a92010-01-29 07:10:46130 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]a2006ece2010-04-23 16:44:02131 log.entries(), 2, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09132 if (rv != net::OK) {
133 ASSERT_EQ(net::ERR_IO_PENDING, rv);
134 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:46135 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53136 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09137
138 rv = callback.WaitForResult();
139 EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv);
140 }
141
[email protected]bacff652009-03-31 17:50:33142 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
143 // the socket when it encounters an error, whereas other implementations
144 // leave it connected.
[email protected]5a05c47a2009-11-02 23:25:19145
[email protected]e9002a92010-01-29 07:10:46146 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53147 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09148}
149
[email protected]010e27e2009-08-27 17:49:41150TEST_F(SSLClientSocketTest, ConnectMismatched) {
[email protected]73e0bba2009-02-19 22:57:09151 StartMismatchedServer();
152
153 net::AddressList addr;
[email protected]73e0bba2009-02-19 22:57:09154 TestCompletionCallback callback;
155
[email protected]2884a462009-06-15 05:08:42156 net::HostResolver::RequestInfo info(server_.kMismatchedHostName,
157 server_.kOKHTTPSPort);
[email protected]5a1d7ca2010-04-28 20:12:27158 int rv = resolver_->Resolve(info, &addr, NULL, NULL, net::BoundNetLog());
[email protected]73e0bba2009-02-19 22:57:09159 EXPECT_EQ(net::OK, rv);
160
[email protected]a2006ece2010-04-23 16:44:02161 net::CapturingNetLog log(net::CapturingNetLog::kUnbounded);
162 net::ClientSocket* transport = new net::TCPClientSocket(addr, &log);
163 rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33164 if (rv == net::ERR_IO_PENDING)
165 rv = callback.WaitForResult();
166 EXPECT_EQ(net::OK, rv);
167
[email protected]73e0bba2009-02-19 22:57:09168 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33169 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09170 server_.kMismatchedHostName, kDefaultSSLConfig));
171
172 EXPECT_FALSE(sock->IsConnected());
173
[email protected]a2006ece2010-04-23 16:44:02174 rv = sock->Connect(&callback);
[email protected]e9002a92010-01-29 07:10:46175 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]a2006ece2010-04-23 16:44:02176 log.entries(), 2, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09177 if (rv != net::ERR_CERT_COMMON_NAME_INVALID) {
178 ASSERT_EQ(net::ERR_IO_PENDING, rv);
179 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:46180 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53181 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09182
183 rv = callback.WaitForResult();
184 EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv);
185 }
186
[email protected]bacff652009-03-31 17:50:33187 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
188 // the socket when it encounters an error, whereas other implementations
189 // leave it connected.
[email protected]5a05c47a2009-11-02 23:25:19190
[email protected]e9002a92010-01-29 07:10:46191 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53192 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09193}
194
[email protected]b2197852009-02-19 23:27:33195// TODO(wtc): Add unit tests for IsConnectedAndIdle:
196// - Server closes an SSL connection (with a close_notify alert message).
197// - Server closes the underlying TCP connection directly.
198// - Server sends data unexpectedly.
199
[email protected]010e27e2009-08-27 17:49:41200TEST_F(SSLClientSocketTest, Read) {
[email protected]73e0bba2009-02-19 22:57:09201 StartOKServer();
202
203 net::AddressList addr;
[email protected]73e0bba2009-02-19 22:57:09204 TestCompletionCallback callback;
205
[email protected]2884a462009-06-15 05:08:42206 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]5a1d7ca2010-04-28 20:12:27207 int rv = resolver_->Resolve(info, &addr, &callback, NULL, net::BoundNetLog());
[email protected]b75523f2008-10-17 14:49:07208 EXPECT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52209
210 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07211 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52212
[email protected]a2006ece2010-04-23 16:44:02213 net::ClientSocket* transport = new net::TCPClientSocket(addr, NULL);
214 rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33215 if (rv == net::ERR_IO_PENDING)
216 rv = callback.WaitForResult();
217 EXPECT_EQ(net::OK, rv);
218
[email protected]aaead502008-10-15 00:20:11219 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33220 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09221 server_.kHostName,
222 kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52223
[email protected]a2006ece2010-04-23 16:44:02224 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45225 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07226 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52227
[email protected]7b822b2b2008-08-05 00:15:45228 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07229 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45230 }
[email protected]b43c97c2008-10-22 19:50:58231 EXPECT_TRUE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52232
233 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25234 scoped_refptr<net::IOBuffer> request_buffer =
235 new net::IOBuffer(arraysize(request_text) - 1);
236 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
237
238 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52239 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
240
[email protected]914286d62009-12-10 23:06:44241 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52242 rv = callback.WaitForResult();
[email protected]914286d62009-12-10 23:06:44243 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52244
[email protected]ffeb0882009-04-30 21:51:25245 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(4096);
initial.commit586acc5fe2008-07-26 22:42:52246 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25247 rv = sock->Read(buf, 4096, &callback);
initial.commit586acc5fe2008-07-26 22:42:52248 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
249
250 if (rv == net::ERR_IO_PENDING)
251 rv = callback.WaitForResult();
252
[email protected]7b822b2b2008-08-05 00:15:45253 EXPECT_GE(rv, 0);
254 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52255 break;
256 }
257}
258
[email protected]914286d62009-12-10 23:06:44259// Test the full duplex mode, with Read and Write pending at the same time.
260// This test also serves as a regression test for http://crbug.com/29815.
261TEST_F(SSLClientSocketTest, Read_FullDuplex) {
262 StartOKServer();
263
264 net::AddressList addr;
265 TestCompletionCallback callback; // Used for everything except Write.
266 TestCompletionCallback callback2; // Used for Write only.
267
268 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]5a1d7ca2010-04-28 20:12:27269 int rv = resolver_->Resolve(info, &addr, &callback, NULL, net::BoundNetLog());
[email protected]914286d62009-12-10 23:06:44270 EXPECT_EQ(net::ERR_IO_PENDING, rv);
271
272 rv = callback.WaitForResult();
273 EXPECT_EQ(net::OK, rv);
274
[email protected]a2006ece2010-04-23 16:44:02275 net::ClientSocket* transport = new net::TCPClientSocket(addr, NULL);
276 rv = transport->Connect(&callback);
[email protected]914286d62009-12-10 23:06:44277 if (rv == net::ERR_IO_PENDING)
278 rv = callback.WaitForResult();
279 EXPECT_EQ(net::OK, rv);
280
281 scoped_ptr<net::SSLClientSocket> sock(
282 socket_factory_->CreateSSLClientSocket(transport,
283 server_.kHostName,
284 kDefaultSSLConfig));
285
[email protected]a2006ece2010-04-23 16:44:02286 rv = sock->Connect(&callback);
[email protected]914286d62009-12-10 23:06:44287 if (rv != net::OK) {
288 ASSERT_EQ(net::ERR_IO_PENDING, rv);
289
290 rv = callback.WaitForResult();
291 EXPECT_EQ(net::OK, rv);
292 }
293 EXPECT_TRUE(sock->IsConnected());
294
295 // Issue a "hanging" Read first.
296 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(4096);
297 rv = sock->Read(buf, 4096, &callback);
298 // We haven't written the request, so there should be no response yet.
299 ASSERT_EQ(net::ERR_IO_PENDING, rv);
300
301 // Write the request.
302 // The request is padded with a User-Agent header to a size that causes the
303 // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around.
304 // This tests the fix for http://crbug.com/29815.
305 std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
306 for (int i = 0; i < 3800; ++i)
307 request_text.push_back('*');
308 request_text.append("\r\n\r\n");
309 scoped_refptr<net::IOBuffer> request_buffer =
310 new net::StringIOBuffer(request_text);
311
312 rv = sock->Write(request_buffer, request_text.size(), &callback2);
313 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
314
315 if (rv == net::ERR_IO_PENDING)
316 rv = callback2.WaitForResult();
317 EXPECT_EQ(static_cast<int>(request_text.size()), rv);
318
319 // Now get the Read result.
320 rv = callback.WaitForResult();
321 EXPECT_GT(rv, 0);
322}
323
[email protected]010e27e2009-08-27 17:49:41324TEST_F(SSLClientSocketTest, Read_SmallChunks) {
[email protected]73e0bba2009-02-19 22:57:09325 StartOKServer();
326
initial.commit586acc5fe2008-07-26 22:42:52327 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52328 TestCompletionCallback callback;
329
[email protected]2884a462009-06-15 05:08:42330 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]5a1d7ca2010-04-28 20:12:27331 int rv = resolver_->Resolve(info, &addr, NULL, NULL, net::BoundNetLog());
[email protected]b75523f2008-10-17 14:49:07332 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52333
[email protected]a2006ece2010-04-23 16:44:02334 net::ClientSocket* transport = new net::TCPClientSocket(addr, NULL);
335 rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33336 if (rv == net::ERR_IO_PENDING)
337 rv = callback.WaitForResult();
338 EXPECT_EQ(net::OK, rv);
339
[email protected]aaead502008-10-15 00:20:11340 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33341 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09342 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52343
[email protected]a2006ece2010-04-23 16:44:02344 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45345 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07346 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52347
[email protected]7b822b2b2008-08-05 00:15:45348 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07349 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45350 }
initial.commit586acc5fe2008-07-26 22:42:52351
352 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25353 scoped_refptr<net::IOBuffer> request_buffer =
354 new net::IOBuffer(arraysize(request_text) - 1);
355 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
356
357 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52358 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
359
[email protected]914286d62009-12-10 23:06:44360 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52361 rv = callback.WaitForResult();
[email protected]914286d62009-12-10 23:06:44362 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52363
[email protected]ffeb0882009-04-30 21:51:25364 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(1);
initial.commit586acc5fe2008-07-26 22:42:52365 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25366 rv = sock->Read(buf, 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52367 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
368
369 if (rv == net::ERR_IO_PENDING)
370 rv = callback.WaitForResult();
371
[email protected]7b822b2b2008-08-05 00:15:45372 EXPECT_GE(rv, 0);
373 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52374 break;
375 }
376}
377
[email protected]010e27e2009-08-27 17:49:41378TEST_F(SSLClientSocketTest, Read_Interrupted) {
[email protected]73e0bba2009-02-19 22:57:09379 StartOKServer();
380
initial.commit586acc5fe2008-07-26 22:42:52381 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52382 TestCompletionCallback callback;
383
[email protected]2884a462009-06-15 05:08:42384 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]5a1d7ca2010-04-28 20:12:27385 int rv = resolver_->Resolve(info, &addr, NULL, NULL, net::BoundNetLog());
[email protected]b75523f2008-10-17 14:49:07386 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52387
[email protected]a2006ece2010-04-23 16:44:02388 net::ClientSocket* transport = new net::TCPClientSocket(addr, NULL);
389 rv = transport->Connect(&callback);
[email protected]bacff652009-03-31 17:50:33390 if (rv == net::ERR_IO_PENDING)
391 rv = callback.WaitForResult();
392 EXPECT_EQ(net::OK, rv);
393
[email protected]aaead502008-10-15 00:20:11394 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33395 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09396 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52397
[email protected]a2006ece2010-04-23 16:44:02398 rv = sock->Connect(&callback);
[email protected]7b822b2b2008-08-05 00:15:45399 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07400 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52401
[email protected]7b822b2b2008-08-05 00:15:45402 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07403 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45404 }
initial.commit586acc5fe2008-07-26 22:42:52405
406 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25407 scoped_refptr<net::IOBuffer> request_buffer =
408 new net::IOBuffer(arraysize(request_text) - 1);
409 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
410
411 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52412 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
413
[email protected]914286d62009-12-10 23:06:44414 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52415 rv = callback.WaitForResult();
[email protected]914286d62009-12-10 23:06:44416 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52417
418 // Do a partial read and then exit. This test should not crash!
[email protected]ffeb0882009-04-30 21:51:25419 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(512);
420 rv = sock->Read(buf, 512, &callback);
[email protected]914286d62009-12-10 23:06:44421 EXPECT_TRUE(rv > 0 || rv == net::ERR_IO_PENDING);
initial.commit586acc5fe2008-07-26 22:42:52422
423 if (rv == net::ERR_IO_PENDING)
424 rv = callback.WaitForResult();
425
[email protected]914286d62009-12-10 23:06:44426 EXPECT_GT(rv, 0);
initial.commit586acc5fe2008-07-26 22:42:52427}
[email protected]39afe642010-04-29 14:55:18428
429#if !defined(OS_WIN)
430// Regression test for http://crbug.com/42538
431TEST_F(SSLClientSocketTest, PrematureApplicationData) {
432 net::AddressList addr;
433 TestCompletionCallback callback;
434
435 static const unsigned char application_data[] = {
436 0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b,
437 0xc2, 0xf8, 0xb2, 0xc1, 0x56, 0x42, 0xb9, 0x57, 0x7f, 0xde, 0x87, 0x46,
438 0xf7, 0xa3, 0x52, 0x42, 0x21, 0xf0, 0x13, 0x1c, 0x9c, 0x83, 0x88, 0xd6,
439 0x93, 0x0c, 0xf6, 0x36, 0x30, 0x05, 0x7e, 0x20, 0xb5, 0xb5, 0x73, 0x36,
440 0x53, 0x83, 0x0a, 0xfc, 0x17, 0x63, 0xbf, 0xa0, 0xe4, 0x42, 0x90, 0x0d,
441 0x2f, 0x18, 0x6d, 0x20, 0xd8, 0x36, 0x3f, 0xfc, 0xe6, 0x01, 0xfa, 0x0f,
442 0xa5, 0x75, 0x7f, 0x09, 0x00, 0x04, 0x00, 0x16, 0x03, 0x01, 0x11, 0x57,
443 0x0b, 0x00, 0x11, 0x53, 0x00, 0x11, 0x50, 0x00, 0x06, 0x22, 0x30, 0x82,
444 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
445 0x0a
446 };
447
448 // All reads and writes complete synchronously (async=false).
449 net::MockRead data_reads[] = {
450 net::MockRead(false, reinterpret_cast<const char*>(application_data),
451 arraysize(application_data)),
452 net::MockRead(false, net::OK),
453 };
454
455 net::StaticSocketDataProvider data(data_reads, arraysize(data_reads),
456 NULL, 0);
457
458 net::ClientSocket* transport =
459 new net::MockTCPClientSocket(addr, NULL, &data);
460 int rv = transport->Connect(&callback);
461 if (rv == net::ERR_IO_PENDING)
462 rv = callback.WaitForResult();
463 EXPECT_EQ(net::OK, rv);
464
465 scoped_ptr<net::SSLClientSocket> sock(
466 socket_factory_->CreateSSLClientSocket(
467 transport, server_.kHostName, kDefaultSSLConfig));
468
469 rv = sock->Connect(&callback);
470 EXPECT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
471}
472#endif // !defined(OS_WIN)