blob: 4984fc708bc28e5363e1aea53ae835b902ce51c8 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
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"
16#include "net/socket/ssl_test_util.h"
17#include "net/socket/tcp_client_socket.h"
initial.commit586acc5fe2008-07-26 22:42:5218#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1519#include "testing/platform_test.h"
initial.commit586acc5fe2008-07-26 22:42:5220
21//-----------------------------------------------------------------------------
22
[email protected]aaead502008-10-15 00:20:1123const net::SSLConfig kDefaultSSLConfig;
[email protected]c5949a32008-10-08 17:28:2324
[email protected]b75523f2008-10-17 14:49:0725class SSLClientSocketTest : public PlatformTest {
[email protected]aaead502008-10-15 00:20:1126 public:
27 SSLClientSocketTest()
[email protected]d13c3272010-02-04 00:24:5128 : resolver_(net::CreateSystemHostResolver(NULL)),
[email protected]b59ff372009-07-15 22:04:3229 socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) {
[email protected]73e0bba2009-02-19 22:57:0930 }
31
32 void StartOKServer() {
33 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
34 server_.kHostName, server_.kOKHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2235 FilePath(), server_.GetOKCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0936 ASSERT_TRUE(success);
37 }
38
39 void StartMismatchedServer() {
40 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
41 server_.kMismatchedHostName, server_.kOKHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2242 FilePath(), server_.GetOKCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0943 ASSERT_TRUE(success);
44 }
45
46 void StartExpiredServer() {
47 bool success = server_.Start(net::TestServerLauncher::ProtoHTTP,
48 server_.kHostName, server_.kBadHTTPSPort,
[email protected]deb27ae2009-04-10 02:37:2249 FilePath(), server_.GetExpiredCertPath(), std::wstring());
[email protected]73e0bba2009-02-19 22:57:0950 ASSERT_TRUE(success);
[email protected]aaead502008-10-15 00:20:1151 }
[email protected]471822ca2009-01-29 11:32:2652
[email protected]aaead502008-10-15 00:20:1153 protected:
[email protected]b59ff372009-07-15 22:04:3254 scoped_refptr<net::HostResolver> resolver_;
[email protected]aaead502008-10-15 00:20:1155 net::ClientSocketFactory* socket_factory_;
[email protected]73e0bba2009-02-19 22:57:0956 net::TestServerLauncher server_;
initial.commit586acc5fe2008-07-26 22:42:5257};
58
initial.commit586acc5fe2008-07-26 22:42:5259//-----------------------------------------------------------------------------
60
[email protected]010e27e2009-08-27 17:49:4161TEST_F(SSLClientSocketTest, Connect) {
[email protected]73e0bba2009-02-19 22:57:0962 StartOKServer();
63
initial.commit586acc5fe2008-07-26 22:42:5264 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:5265 TestCompletionCallback callback;
66
[email protected]2884a462009-06-15 05:08:4267 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:4668 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
initial.commit586acc5fe2008-07-26 22:42:5269 EXPECT_EQ(net::OK, rv);
70
[email protected]bacff652009-03-31 17:50:3371 net::ClientSocket *transport = new net::TCPClientSocket(addr);
[email protected]5a05c47a2009-11-02 23:25:1972 rv = transport->Connect(&callback, NULL);
[email protected]bacff652009-03-31 17:50:3373 if (rv == net::ERR_IO_PENDING)
74 rv = callback.WaitForResult();
75 EXPECT_EQ(net::OK, rv);
76
[email protected]aaead502008-10-15 00:20:1177 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:3378 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:0979 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:5280
[email protected]aaead502008-10-15 00:20:1181 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:5282
[email protected]9e743cd2010-03-16 07:03:5383 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
84 rv = sock->Connect(&callback, log.bound());
[email protected]e9002a92010-01-29 07:10:4685 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:5386 log.entries(), 0, net::NetLog::TYPE_SSL_CONNECT));
[email protected]7b822b2b2008-08-05 00:15:4587 if (rv != net::OK) {
88 ASSERT_EQ(net::ERR_IO_PENDING, rv);
[email protected]73e0bba2009-02-19 22:57:0989 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:4690 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:5391 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
initial.commit586acc5fe2008-07-26 22:42:5292
[email protected]7b822b2b2008-08-05 00:15:4593 rv = callback.WaitForResult();
94 EXPECT_EQ(net::OK, rv);
95 }
initial.commit586acc5fe2008-07-26 22:42:5296
[email protected]aaead502008-10-15 00:20:1197 EXPECT_TRUE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:4698 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:5399 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
initial.commit586acc5fe2008-07-26 22:42:52100
[email protected]aaead502008-10-15 00:20:11101 sock->Disconnect();
102 EXPECT_FALSE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52103}
104
[email protected]010e27e2009-08-27 17:49:41105TEST_F(SSLClientSocketTest, ConnectExpired) {
[email protected]73e0bba2009-02-19 22:57:09106 StartExpiredServer();
107
initial.commit586acc5fe2008-07-26 22:42:52108 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52109 TestCompletionCallback callback;
110
[email protected]2884a462009-06-15 05:08:42111 net::HostResolver::RequestInfo info(server_.kHostName, server_.kBadHTTPSPort);
[email protected]684970b2009-08-14 04:54:46112 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
[email protected]73e0bba2009-02-19 22:57:09113 EXPECT_EQ(net::OK, rv);
114
[email protected]bacff652009-03-31 17:50:33115 net::ClientSocket *transport = new net::TCPClientSocket(addr);
[email protected]5a05c47a2009-11-02 23:25:19116 rv = transport->Connect(&callback, NULL);
[email protected]bacff652009-03-31 17:50:33117 if (rv == net::ERR_IO_PENDING)
118 rv = callback.WaitForResult();
119 EXPECT_EQ(net::OK, rv);
120
[email protected]73e0bba2009-02-19 22:57:09121 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33122 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09123 server_.kHostName, kDefaultSSLConfig));
124
125 EXPECT_FALSE(sock->IsConnected());
126
[email protected]9e743cd2010-03-16 07:03:53127 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
128 rv = sock->Connect(&callback, log.bound());
[email protected]e9002a92010-01-29 07:10:46129 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53130 log.entries(), 0, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09131 if (rv != net::OK) {
132 ASSERT_EQ(net::ERR_IO_PENDING, rv);
133 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:46134 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53135 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09136
137 rv = callback.WaitForResult();
138 EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv);
139 }
140
[email protected]bacff652009-03-31 17:50:33141 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
142 // the socket when it encounters an error, whereas other implementations
143 // leave it connected.
[email protected]5a05c47a2009-11-02 23:25:19144
[email protected]e9002a92010-01-29 07:10:46145 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53146 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09147}
148
[email protected]010e27e2009-08-27 17:49:41149TEST_F(SSLClientSocketTest, ConnectMismatched) {
[email protected]73e0bba2009-02-19 22:57:09150 StartMismatchedServer();
151
152 net::AddressList addr;
[email protected]73e0bba2009-02-19 22:57:09153 TestCompletionCallback callback;
154
[email protected]2884a462009-06-15 05:08:42155 net::HostResolver::RequestInfo info(server_.kMismatchedHostName,
156 server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:46157 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
[email protected]73e0bba2009-02-19 22:57:09158 EXPECT_EQ(net::OK, rv);
159
[email protected]bacff652009-03-31 17:50:33160 net::ClientSocket *transport = new net::TCPClientSocket(addr);
[email protected]5a05c47a2009-11-02 23:25:19161 rv = transport->Connect(&callback, NULL);
[email protected]bacff652009-03-31 17:50:33162 if (rv == net::ERR_IO_PENDING)
163 rv = callback.WaitForResult();
164 EXPECT_EQ(net::OK, rv);
165
[email protected]73e0bba2009-02-19 22:57:09166 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33167 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09168 server_.kMismatchedHostName, kDefaultSSLConfig));
169
170 EXPECT_FALSE(sock->IsConnected());
171
[email protected]9e743cd2010-03-16 07:03:53172 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
173 rv = sock->Connect(&callback, log.bound());
[email protected]e9002a92010-01-29 07:10:46174 EXPECT_TRUE(net::LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53175 log.entries(), 0, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09176 if (rv != net::ERR_CERT_COMMON_NAME_INVALID) {
177 ASSERT_EQ(net::ERR_IO_PENDING, rv);
178 EXPECT_FALSE(sock->IsConnected());
[email protected]e9002a92010-01-29 07:10:46179 EXPECT_FALSE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53180 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09181
182 rv = callback.WaitForResult();
183 EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv);
184 }
185
[email protected]bacff652009-03-31 17:50:33186 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
187 // the socket when it encounters an error, whereas other implementations
188 // leave it connected.
[email protected]5a05c47a2009-11-02 23:25:19189
[email protected]e9002a92010-01-29 07:10:46190 EXPECT_TRUE(net::LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53191 log.entries(), -1, net::NetLog::TYPE_SSL_CONNECT));
[email protected]73e0bba2009-02-19 22:57:09192}
193
[email protected]b2197852009-02-19 23:27:33194// TODO(wtc): Add unit tests for IsConnectedAndIdle:
195// - Server closes an SSL connection (with a close_notify alert message).
196// - Server closes the underlying TCP connection directly.
197// - Server sends data unexpectedly.
198
[email protected]010e27e2009-08-27 17:49:41199TEST_F(SSLClientSocketTest, Read) {
[email protected]73e0bba2009-02-19 22:57:09200 StartOKServer();
201
202 net::AddressList addr;
[email protected]73e0bba2009-02-19 22:57:09203 TestCompletionCallback callback;
204
[email protected]2884a462009-06-15 05:08:42205 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:46206 int rv = resolver_->Resolve(info, &addr, &callback, NULL, NULL);
[email protected]b75523f2008-10-17 14:49:07207 EXPECT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52208
209 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07210 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52211
[email protected]bacff652009-03-31 17:50:33212 net::ClientSocket *transport = new net::TCPClientSocket(addr);
[email protected]5a05c47a2009-11-02 23:25:19213 rv = transport->Connect(&callback, NULL);
[email protected]bacff652009-03-31 17:50:33214 if (rv == net::ERR_IO_PENDING)
215 rv = callback.WaitForResult();
216 EXPECT_EQ(net::OK, rv);
217
[email protected]aaead502008-10-15 00:20:11218 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33219 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09220 server_.kHostName,
221 kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52222
[email protected]5a05c47a2009-11-02 23:25:19223 rv = sock->Connect(&callback, NULL);
[email protected]7b822b2b2008-08-05 00:15:45224 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07225 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52226
[email protected]7b822b2b2008-08-05 00:15:45227 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07228 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45229 }
[email protected]b43c97c2008-10-22 19:50:58230 EXPECT_TRUE(sock->IsConnected());
initial.commit586acc5fe2008-07-26 22:42:52231
232 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25233 scoped_refptr<net::IOBuffer> request_buffer =
234 new net::IOBuffer(arraysize(request_text) - 1);
235 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
236
237 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52238 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
239
[email protected]914286d62009-12-10 23:06:44240 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52241 rv = callback.WaitForResult();
[email protected]914286d62009-12-10 23:06:44242 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52243
[email protected]ffeb0882009-04-30 21:51:25244 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(4096);
initial.commit586acc5fe2008-07-26 22:42:52245 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25246 rv = sock->Read(buf, 4096, &callback);
initial.commit586acc5fe2008-07-26 22:42:52247 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
248
249 if (rv == net::ERR_IO_PENDING)
250 rv = callback.WaitForResult();
251
[email protected]7b822b2b2008-08-05 00:15:45252 EXPECT_GE(rv, 0);
253 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52254 break;
255 }
256}
257
[email protected]914286d62009-12-10 23:06:44258// Test the full duplex mode, with Read and Write pending at the same time.
259// This test also serves as a regression test for http://crbug.com/29815.
260TEST_F(SSLClientSocketTest, Read_FullDuplex) {
261 StartOKServer();
262
263 net::AddressList addr;
264 TestCompletionCallback callback; // Used for everything except Write.
265 TestCompletionCallback callback2; // Used for Write only.
266
267 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
268 int rv = resolver_->Resolve(info, &addr, &callback, NULL, NULL);
269 EXPECT_EQ(net::ERR_IO_PENDING, rv);
270
271 rv = callback.WaitForResult();
272 EXPECT_EQ(net::OK, rv);
273
274 net::ClientSocket *transport = new net::TCPClientSocket(addr);
275 rv = transport->Connect(&callback, NULL);
276 if (rv == net::ERR_IO_PENDING)
277 rv = callback.WaitForResult();
278 EXPECT_EQ(net::OK, rv);
279
280 scoped_ptr<net::SSLClientSocket> sock(
281 socket_factory_->CreateSSLClientSocket(transport,
282 server_.kHostName,
283 kDefaultSSLConfig));
284
285 rv = sock->Connect(&callback, NULL);
286 if (rv != net::OK) {
287 ASSERT_EQ(net::ERR_IO_PENDING, rv);
288
289 rv = callback.WaitForResult();
290 EXPECT_EQ(net::OK, rv);
291 }
292 EXPECT_TRUE(sock->IsConnected());
293
294 // Issue a "hanging" Read first.
295 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(4096);
296 rv = sock->Read(buf, 4096, &callback);
297 // We haven't written the request, so there should be no response yet.
298 ASSERT_EQ(net::ERR_IO_PENDING, rv);
299
300 // Write the request.
301 // The request is padded with a User-Agent header to a size that causes the
302 // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around.
303 // This tests the fix for http://crbug.com/29815.
304 std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
305 for (int i = 0; i < 3800; ++i)
306 request_text.push_back('*');
307 request_text.append("\r\n\r\n");
308 scoped_refptr<net::IOBuffer> request_buffer =
309 new net::StringIOBuffer(request_text);
310
311 rv = sock->Write(request_buffer, request_text.size(), &callback2);
312 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
313
314 if (rv == net::ERR_IO_PENDING)
315 rv = callback2.WaitForResult();
316 EXPECT_EQ(static_cast<int>(request_text.size()), rv);
317
318 // Now get the Read result.
319 rv = callback.WaitForResult();
320 EXPECT_GT(rv, 0);
321}
322
[email protected]010e27e2009-08-27 17:49:41323TEST_F(SSLClientSocketTest, Read_SmallChunks) {
[email protected]73e0bba2009-02-19 22:57:09324 StartOKServer();
325
initial.commit586acc5fe2008-07-26 22:42:52326 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52327 TestCompletionCallback callback;
328
[email protected]2884a462009-06-15 05:08:42329 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:46330 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
[email protected]b75523f2008-10-17 14:49:07331 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52332
[email protected]bacff652009-03-31 17:50:33333 net::ClientSocket *transport = new net::TCPClientSocket(addr);
[email protected]5a05c47a2009-11-02 23:25:19334 rv = transport->Connect(&callback, NULL);
[email protected]bacff652009-03-31 17:50:33335 if (rv == net::ERR_IO_PENDING)
336 rv = callback.WaitForResult();
337 EXPECT_EQ(net::OK, rv);
338
[email protected]aaead502008-10-15 00:20:11339 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33340 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09341 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52342
[email protected]5a05c47a2009-11-02 23:25:19343 rv = sock->Connect(&callback, NULL);
[email protected]7b822b2b2008-08-05 00:15:45344 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07345 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52346
[email protected]7b822b2b2008-08-05 00:15:45347 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07348 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45349 }
initial.commit586acc5fe2008-07-26 22:42:52350
351 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25352 scoped_refptr<net::IOBuffer> request_buffer =
353 new net::IOBuffer(arraysize(request_text) - 1);
354 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
355
356 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52357 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
358
[email protected]914286d62009-12-10 23:06:44359 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52360 rv = callback.WaitForResult();
[email protected]914286d62009-12-10 23:06:44361 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52362
[email protected]ffeb0882009-04-30 21:51:25363 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(1);
initial.commit586acc5fe2008-07-26 22:42:52364 for (;;) {
[email protected]ffeb0882009-04-30 21:51:25365 rv = sock->Read(buf, 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52366 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
367
368 if (rv == net::ERR_IO_PENDING)
369 rv = callback.WaitForResult();
370
[email protected]7b822b2b2008-08-05 00:15:45371 EXPECT_GE(rv, 0);
372 if (rv <= 0)
initial.commit586acc5fe2008-07-26 22:42:52373 break;
374 }
375}
376
[email protected]010e27e2009-08-27 17:49:41377TEST_F(SSLClientSocketTest, Read_Interrupted) {
[email protected]73e0bba2009-02-19 22:57:09378 StartOKServer();
379
initial.commit586acc5fe2008-07-26 22:42:52380 net::AddressList addr;
initial.commit586acc5fe2008-07-26 22:42:52381 TestCompletionCallback callback;
382
[email protected]2884a462009-06-15 05:08:42383 net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
[email protected]684970b2009-08-14 04:54:46384 int rv = resolver_->Resolve(info, &addr, NULL, NULL, NULL);
[email protected]b75523f2008-10-17 14:49:07385 EXPECT_EQ(net::OK, rv);
initial.commit586acc5fe2008-07-26 22:42:52386
[email protected]bacff652009-03-31 17:50:33387 net::ClientSocket *transport = new net::TCPClientSocket(addr);
[email protected]5a05c47a2009-11-02 23:25:19388 rv = transport->Connect(&callback, NULL);
[email protected]bacff652009-03-31 17:50:33389 if (rv == net::ERR_IO_PENDING)
390 rv = callback.WaitForResult();
391 EXPECT_EQ(net::OK, rv);
392
[email protected]aaead502008-10-15 00:20:11393 scoped_ptr<net::SSLClientSocket> sock(
[email protected]bacff652009-03-31 17:50:33394 socket_factory_->CreateSSLClientSocket(transport,
[email protected]73e0bba2009-02-19 22:57:09395 server_.kHostName, kDefaultSSLConfig));
initial.commit586acc5fe2008-07-26 22:42:52396
[email protected]5a05c47a2009-11-02 23:25:19397 rv = sock->Connect(&callback, NULL);
[email protected]7b822b2b2008-08-05 00:15:45398 if (rv != net::OK) {
[email protected]b75523f2008-10-17 14:49:07399 ASSERT_EQ(net::ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52400
[email protected]7b822b2b2008-08-05 00:15:45401 rv = callback.WaitForResult();
[email protected]b75523f2008-10-17 14:49:07402 EXPECT_EQ(net::OK, rv);
[email protected]7b822b2b2008-08-05 00:15:45403 }
initial.commit586acc5fe2008-07-26 22:42:52404
405 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
[email protected]ffeb0882009-04-30 21:51:25406 scoped_refptr<net::IOBuffer> request_buffer =
407 new net::IOBuffer(arraysize(request_text) - 1);
408 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
409
410 rv = sock->Write(request_buffer, arraysize(request_text) - 1, &callback);
initial.commit586acc5fe2008-07-26 22:42:52411 EXPECT_TRUE(rv >= 0 || rv == net::ERR_IO_PENDING);
412
[email protected]914286d62009-12-10 23:06:44413 if (rv == net::ERR_IO_PENDING)
initial.commit586acc5fe2008-07-26 22:42:52414 rv = callback.WaitForResult();
[email protected]914286d62009-12-10 23:06:44415 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
initial.commit586acc5fe2008-07-26 22:42:52416
417 // Do a partial read and then exit. This test should not crash!
[email protected]ffeb0882009-04-30 21:51:25418 scoped_refptr<net::IOBuffer> buf = new net::IOBuffer(512);
419 rv = sock->Read(buf, 512, &callback);
[email protected]914286d62009-12-10 23:06:44420 EXPECT_TRUE(rv > 0 || rv == net::ERR_IO_PENDING);
initial.commit586acc5fe2008-07-26 22:42:52421
422 if (rv == net::ERR_IO_PENDING)
423 rv = callback.WaitForResult();
424
[email protected]914286d62009-12-10 23:06:44425 EXPECT_GT(rv, 0);
initial.commit586acc5fe2008-07-26 22:42:52426}