ssl_client_socket_pool_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright (c) 2012 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/http/http_proxy_client_socket_pool.h"
6
7#include "base/callback.h"
8#include "base/compiler_specific.h"
9#include "base/strings/string_util.h"
10#include "base/strings/utf_string_conversions.h"
11#include "base/time/time.h"
12#include "net/base/auth.h"
13#include "net/base/load_timing_info.h"
14#include "net/base/load_timing_info_test_util.h"
15#include "net/base/net_errors.h"
16#include "net/base/test_completion_callback.h"
17#include "net/cert/cert_verifier.h"
18#include "net/dns/mock_host_resolver.h"
19#include "net/http/http_auth_handler_factory.h"
20#include "net/http/http_network_session.h"
21#include "net/http/http_request_headers.h"
22#include "net/http/http_response_headers.h"
23#include "net/http/http_server_properties_impl.h"
24#include "net/proxy/proxy_service.h"
25#include "net/socket/client_socket_handle.h"
26#include "net/socket/client_socket_pool_histograms.h"
27#include "net/socket/next_proto.h"
28#include "net/socket/socket_test_util.h"
29#include "net/spdy/spdy_session.h"
30#include "net/spdy/spdy_session_pool.h"
31#include "net/spdy/spdy_test_util_common.h"
32#include "net/ssl/ssl_config_service_defaults.h"
33#include "net/test/test_certificate_data.h"
34#include "testing/gtest/include/gtest/gtest.h"
35
36namespace net {
37
38namespace {
39
40const int kMaxSockets = 32;
41const int kMaxSocketsPerGroup = 6;
42
43// Make sure |handle|'s load times are set correctly.  DNS and connect start
44// times comes from mock client sockets in these tests, so primarily serves to
45// check those times were copied, and ssl times / connect end are set correctly.
46void TestLoadTimingInfo(const ClientSocketHandle& handle) {
47  LoadTimingInfo load_timing_info;
48  EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
49
50  EXPECT_FALSE(load_timing_info.socket_reused);
51  // None of these tests use a NetLog.
52  EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
53
54  ExpectConnectTimingHasTimes(
55      load_timing_info.connect_timing,
56      CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
57  ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
58}
59
60// Just like TestLoadTimingInfo, except DNS times are expected to be null, for
61// tests over proxies that do DNS lookups themselves.
62void TestLoadTimingInfoNoDns(const ClientSocketHandle& handle) {
63  LoadTimingInfo load_timing_info;
64  EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
65
66  // None of these tests use a NetLog.
67  EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
68
69  EXPECT_FALSE(load_timing_info.socket_reused);
70
71  ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
72                              CONNECT_TIMING_HAS_SSL_TIMES);
73  ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
74}
75
76class SSLClientSocketPoolTest
77    : public testing::Test,
78      public ::testing::WithParamInterface<NextProto> {
79 protected:
80  SSLClientSocketPoolTest()
81      : proxy_service_(ProxyService::CreateDirect()),
82        ssl_config_service_(new SSLConfigServiceDefaults),
83        http_auth_handler_factory_(
84            HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
85        session_(CreateNetworkSession()),
86        direct_transport_socket_params_(
87            new TransportSocketParams(HostPortPair("host", 443),
88                                      false,
89                                      false,
90                                      OnHostResolutionCallback())),
91        transport_histograms_("MockTCP"),
92        transport_socket_pool_(kMaxSockets,
93                               kMaxSocketsPerGroup,
94                               &transport_histograms_,
95                               &socket_factory_),
96        proxy_transport_socket_params_(
97            new TransportSocketParams(HostPortPair("proxy", 443),
98                                      false,
99                                      false,
100                                      OnHostResolutionCallback())),
101        socks_socket_params_(
102            new SOCKSSocketParams(proxy_transport_socket_params_,
103                                  true,
104                                  HostPortPair("sockshost", 443))),
105        socks_histograms_("MockSOCKS"),
106        socks_socket_pool_(kMaxSockets,
107                           kMaxSocketsPerGroup,
108                           &socks_histograms_,
109                           &transport_socket_pool_),
110        http_proxy_socket_params_(
111            new HttpProxySocketParams(proxy_transport_socket_params_,
112                                      NULL,
113                                      GURL("http://host"),
114                                      std::string(),
115                                      HostPortPair("host", 80),
116                                      session_->http_auth_cache(),
117                                      session_->http_auth_handler_factory(),
118                                      session_->spdy_session_pool(),
119                                      true)),
120        http_proxy_histograms_("MockHttpProxy"),
121        http_proxy_socket_pool_(kMaxSockets,
122                                kMaxSocketsPerGroup,
123                                &http_proxy_histograms_,
124                                &host_resolver_,
125                                &transport_socket_pool_,
126                                NULL,
127                                NULL) {
128    scoped_refptr<SSLConfigService> ssl_config_service(
129        new SSLConfigServiceDefaults);
130    ssl_config_service->GetSSLConfig(&ssl_config_);
131  }
132
133  void CreatePool(bool transport_pool, bool http_proxy_pool, bool socks_pool) {
134    ssl_histograms_.reset(new ClientSocketPoolHistograms("SSLUnitTest"));
135    pool_.reset(new SSLClientSocketPool(
136        kMaxSockets,
137        kMaxSocketsPerGroup,
138        ssl_histograms_.get(),
139        NULL /* host_resolver */,
140        NULL /* cert_verifier */,
141        NULL /* server_bound_cert_service */,
142        NULL /* transport_security_state */,
143        NULL /* cert_transparency_verifier */,
144        std::string() /* ssl_session_cache_shard */,
145        &socket_factory_,
146        transport_pool ? &transport_socket_pool_ : NULL,
147        socks_pool ? &socks_socket_pool_ : NULL,
148        http_proxy_pool ? &http_proxy_socket_pool_ : NULL,
149        NULL,
150        NULL));
151  }
152
153  scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy,
154                                           bool want_spdy_over_npn) {
155    return make_scoped_refptr(new SSLSocketParams(
156        proxy == ProxyServer::SCHEME_DIRECT ? direct_transport_socket_params_
157                                            : NULL,
158        proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : NULL,
159        proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : NULL,
160        HostPortPair("host", 443),
161        ssl_config_,
162        kPrivacyModeDisabled,
163        0,
164        false,
165        want_spdy_over_npn));
166  }
167
168  void AddAuthToCache() {
169    const base::string16 kFoo(ASCIIToUTF16("foo"));
170    const base::string16 kBar(ASCIIToUTF16("bar"));
171    session_->http_auth_cache()->Add(GURL("http://proxy:443/"),
172                                     "MyRealm1",
173                                     HttpAuth::AUTH_SCHEME_BASIC,
174                                     "Basic realm=MyRealm1",
175                                     AuthCredentials(kFoo, kBar),
176                                     "/");
177  }
178
179  HttpNetworkSession* CreateNetworkSession() {
180    HttpNetworkSession::Params params;
181    params.host_resolver = &host_resolver_;
182    params.cert_verifier = cert_verifier_.get();
183    params.transport_security_state = transport_security_state_.get();
184    params.proxy_service = proxy_service_.get();
185    params.client_socket_factory = &socket_factory_;
186    params.ssl_config_service = ssl_config_service_.get();
187    params.http_auth_handler_factory = http_auth_handler_factory_.get();
188    params.http_server_properties =
189        http_server_properties_.GetWeakPtr();
190    params.enable_spdy_compression = false;
191    params.spdy_default_protocol = GetParam();
192    return new HttpNetworkSession(params);
193  }
194
195  void TestIPPoolingDisabled(SSLSocketDataProvider* ssl);
196
197  MockClientSocketFactory socket_factory_;
198  MockCachingHostResolver host_resolver_;
199  scoped_ptr<CertVerifier> cert_verifier_;
200  scoped_ptr<TransportSecurityState> transport_security_state_;
201  const scoped_ptr<ProxyService> proxy_service_;
202  const scoped_refptr<SSLConfigService> ssl_config_service_;
203  const scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
204  HttpServerPropertiesImpl http_server_properties_;
205  const scoped_refptr<HttpNetworkSession> session_;
206
207  scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
208  ClientSocketPoolHistograms transport_histograms_;
209  MockTransportClientSocketPool transport_socket_pool_;
210
211  scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
212
213  scoped_refptr<SOCKSSocketParams> socks_socket_params_;
214  ClientSocketPoolHistograms socks_histograms_;
215  MockSOCKSClientSocketPool socks_socket_pool_;
216
217  scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
218  ClientSocketPoolHistograms http_proxy_histograms_;
219  HttpProxyClientSocketPool http_proxy_socket_pool_;
220
221  SSLConfig ssl_config_;
222  scoped_ptr<ClientSocketPoolHistograms> ssl_histograms_;
223  scoped_ptr<SSLClientSocketPool> pool_;
224};
225
226INSTANTIATE_TEST_CASE_P(
227    NextProto,
228    SSLClientSocketPoolTest,
229    testing::Values(kProtoDeprecatedSPDY2,
230                    kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
231                    kProtoHTTP2Draft04));
232
233TEST_P(SSLClientSocketPoolTest, TCPFail) {
234  StaticSocketDataProvider data;
235  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
236  socket_factory_.AddSocketDataProvider(&data);
237
238  CreatePool(true /* tcp pool */, false, false);
239  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
240                                                    false);
241
242  ClientSocketHandle handle;
243  int rv = handle.Init("a", params, MEDIUM, CompletionCallback(), pool_.get(),
244                       BoundNetLog());
245  EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
246  EXPECT_FALSE(handle.is_initialized());
247  EXPECT_FALSE(handle.socket());
248  EXPECT_FALSE(handle.is_ssl_error());
249}
250
251TEST_P(SSLClientSocketPoolTest, TCPFailAsync) {
252  StaticSocketDataProvider data;
253  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
254  socket_factory_.AddSocketDataProvider(&data);
255
256  CreatePool(true /* tcp pool */, false, false);
257  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
258                                                    false);
259
260  ClientSocketHandle handle;
261  TestCompletionCallback callback;
262  int rv = handle.Init(
263      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
264  EXPECT_EQ(ERR_IO_PENDING, rv);
265  EXPECT_FALSE(handle.is_initialized());
266  EXPECT_FALSE(handle.socket());
267
268  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
269  EXPECT_FALSE(handle.is_initialized());
270  EXPECT_FALSE(handle.socket());
271  EXPECT_FALSE(handle.is_ssl_error());
272}
273
274TEST_P(SSLClientSocketPoolTest, BasicDirect) {
275  StaticSocketDataProvider data;
276  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
277  socket_factory_.AddSocketDataProvider(&data);
278  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
279  socket_factory_.AddSSLSocketDataProvider(&ssl);
280
281  CreatePool(true /* tcp pool */, false, false);
282  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
283                                                    false);
284
285  ClientSocketHandle handle;
286  TestCompletionCallback callback;
287  int rv = handle.Init(
288      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
289  EXPECT_EQ(OK, rv);
290  EXPECT_TRUE(handle.is_initialized());
291  EXPECT_TRUE(handle.socket());
292  TestLoadTimingInfo(handle);
293}
294
295// Make sure that SSLConnectJob passes on its priority to its
296// socket request on Init (for the DIRECT case).
297TEST_P(SSLClientSocketPoolTest, SetSocketRequestPriorityOnInitDirect) {
298  CreatePool(true /* tcp pool */, false, false);
299  scoped_refptr<SSLSocketParams> params =
300      SSLParams(ProxyServer::SCHEME_DIRECT, false);
301
302  for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
303    RequestPriority priority = static_cast<RequestPriority>(i);
304    StaticSocketDataProvider data;
305    data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
306    socket_factory_.AddSocketDataProvider(&data);
307    SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
308    socket_factory_.AddSSLSocketDataProvider(&ssl);
309
310    ClientSocketHandle handle;
311    TestCompletionCallback callback;
312    EXPECT_EQ(OK, handle.Init("a", params, priority, callback.callback(),
313                              pool_.get(), BoundNetLog()));
314    EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
315    handle.socket()->Disconnect();
316  }
317}
318
319TEST_P(SSLClientSocketPoolTest, BasicDirectAsync) {
320  StaticSocketDataProvider data;
321  socket_factory_.AddSocketDataProvider(&data);
322  SSLSocketDataProvider ssl(ASYNC, OK);
323  socket_factory_.AddSSLSocketDataProvider(&ssl);
324
325  CreatePool(true /* tcp pool */, false, false);
326  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
327                                                    false);
328
329  ClientSocketHandle handle;
330  TestCompletionCallback callback;
331  int rv = handle.Init(
332      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
333  EXPECT_EQ(ERR_IO_PENDING, rv);
334  EXPECT_FALSE(handle.is_initialized());
335  EXPECT_FALSE(handle.socket());
336
337  EXPECT_EQ(OK, callback.WaitForResult());
338  EXPECT_TRUE(handle.is_initialized());
339  EXPECT_TRUE(handle.socket());
340  TestLoadTimingInfo(handle);
341}
342
343TEST_P(SSLClientSocketPoolTest, DirectCertError) {
344  StaticSocketDataProvider data;
345  socket_factory_.AddSocketDataProvider(&data);
346  SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
347  socket_factory_.AddSSLSocketDataProvider(&ssl);
348
349  CreatePool(true /* tcp pool */, false, false);
350  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
351                                                    false);
352
353  ClientSocketHandle handle;
354  TestCompletionCallback callback;
355  int rv = handle.Init(
356      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
357  EXPECT_EQ(ERR_IO_PENDING, rv);
358  EXPECT_FALSE(handle.is_initialized());
359  EXPECT_FALSE(handle.socket());
360
361  EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, callback.WaitForResult());
362  EXPECT_TRUE(handle.is_initialized());
363  EXPECT_TRUE(handle.socket());
364  TestLoadTimingInfo(handle);
365}
366
367TEST_P(SSLClientSocketPoolTest, DirectSSLError) {
368  StaticSocketDataProvider data;
369  socket_factory_.AddSocketDataProvider(&data);
370  SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR);
371  socket_factory_.AddSSLSocketDataProvider(&ssl);
372
373  CreatePool(true /* tcp pool */, false, false);
374  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
375                                                    false);
376
377  ClientSocketHandle handle;
378  TestCompletionCallback callback;
379  int rv = handle.Init(
380      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
381  EXPECT_EQ(ERR_IO_PENDING, rv);
382  EXPECT_FALSE(handle.is_initialized());
383  EXPECT_FALSE(handle.socket());
384
385  EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, callback.WaitForResult());
386  EXPECT_FALSE(handle.is_initialized());
387  EXPECT_FALSE(handle.socket());
388  EXPECT_TRUE(handle.is_ssl_error());
389}
390
391TEST_P(SSLClientSocketPoolTest, DirectWithNPN) {
392  StaticSocketDataProvider data;
393  socket_factory_.AddSocketDataProvider(&data);
394  SSLSocketDataProvider ssl(ASYNC, OK);
395  ssl.SetNextProto(kProtoHTTP11);
396  socket_factory_.AddSSLSocketDataProvider(&ssl);
397
398  CreatePool(true /* tcp pool */, false, false);
399  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
400                                                    false);
401
402  ClientSocketHandle handle;
403  TestCompletionCallback callback;
404  int rv = handle.Init(
405      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
406  EXPECT_EQ(ERR_IO_PENDING, rv);
407  EXPECT_FALSE(handle.is_initialized());
408  EXPECT_FALSE(handle.socket());
409
410  EXPECT_EQ(OK, callback.WaitForResult());
411  EXPECT_TRUE(handle.is_initialized());
412  EXPECT_TRUE(handle.socket());
413  TestLoadTimingInfo(handle);
414  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
415  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
416}
417
418TEST_P(SSLClientSocketPoolTest, DirectNoSPDY) {
419  StaticSocketDataProvider data;
420  socket_factory_.AddSocketDataProvider(&data);
421  SSLSocketDataProvider ssl(ASYNC, OK);
422  ssl.SetNextProto(kProtoHTTP11);
423  socket_factory_.AddSSLSocketDataProvider(&ssl);
424
425  CreatePool(true /* tcp pool */, false, false);
426  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
427                                                    true);
428
429  ClientSocketHandle handle;
430  TestCompletionCallback callback;
431  int rv = handle.Init(
432      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
433  EXPECT_EQ(ERR_IO_PENDING, rv);
434  EXPECT_FALSE(handle.is_initialized());
435  EXPECT_FALSE(handle.socket());
436
437  EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.WaitForResult());
438  EXPECT_FALSE(handle.is_initialized());
439  EXPECT_FALSE(handle.socket());
440  EXPECT_TRUE(handle.is_ssl_error());
441}
442
443TEST_P(SSLClientSocketPoolTest, DirectGotSPDY) {
444  StaticSocketDataProvider data;
445  socket_factory_.AddSocketDataProvider(&data);
446  SSLSocketDataProvider ssl(ASYNC, OK);
447  ssl.SetNextProto(GetParam());
448  socket_factory_.AddSSLSocketDataProvider(&ssl);
449
450  CreatePool(true /* tcp pool */, false, false);
451  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
452                                                    true);
453
454  ClientSocketHandle handle;
455  TestCompletionCallback callback;
456  int rv = handle.Init(
457      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
458  EXPECT_EQ(ERR_IO_PENDING, rv);
459  EXPECT_FALSE(handle.is_initialized());
460  EXPECT_FALSE(handle.socket());
461
462  EXPECT_EQ(OK, callback.WaitForResult());
463  EXPECT_TRUE(handle.is_initialized());
464  EXPECT_TRUE(handle.socket());
465  TestLoadTimingInfo(handle);
466
467  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
468  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
469  std::string proto;
470  std::string server_protos;
471  ssl_socket->GetNextProto(&proto, &server_protos);
472  EXPECT_EQ(GetParam(), SSLClientSocket::NextProtoFromString(proto));
473}
474
475TEST_P(SSLClientSocketPoolTest, DirectGotBonusSPDY) {
476  StaticSocketDataProvider data;
477  socket_factory_.AddSocketDataProvider(&data);
478  SSLSocketDataProvider ssl(ASYNC, OK);
479  ssl.SetNextProto(GetParam());
480  socket_factory_.AddSSLSocketDataProvider(&ssl);
481
482  CreatePool(true /* tcp pool */, false, false);
483  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
484                                                    true);
485
486  ClientSocketHandle handle;
487  TestCompletionCallback callback;
488  int rv = handle.Init(
489      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
490  EXPECT_EQ(ERR_IO_PENDING, rv);
491  EXPECT_FALSE(handle.is_initialized());
492  EXPECT_FALSE(handle.socket());
493
494  EXPECT_EQ(OK, callback.WaitForResult());
495  EXPECT_TRUE(handle.is_initialized());
496  EXPECT_TRUE(handle.socket());
497  TestLoadTimingInfo(handle);
498
499  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
500  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
501  std::string proto;
502  std::string server_protos;
503  ssl_socket->GetNextProto(&proto, &server_protos);
504  EXPECT_EQ(GetParam(), SSLClientSocket::NextProtoFromString(proto));
505}
506
507TEST_P(SSLClientSocketPoolTest, SOCKSFail) {
508  StaticSocketDataProvider data;
509  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
510  socket_factory_.AddSocketDataProvider(&data);
511
512  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
513  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
514                                                    false);
515
516  ClientSocketHandle handle;
517  TestCompletionCallback callback;
518  int rv = handle.Init(
519      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
520  EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
521  EXPECT_FALSE(handle.is_initialized());
522  EXPECT_FALSE(handle.socket());
523  EXPECT_FALSE(handle.is_ssl_error());
524}
525
526TEST_P(SSLClientSocketPoolTest, SOCKSFailAsync) {
527  StaticSocketDataProvider data;
528  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
529  socket_factory_.AddSocketDataProvider(&data);
530
531  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
532  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
533                                                    false);
534
535  ClientSocketHandle handle;
536  TestCompletionCallback callback;
537  int rv = handle.Init(
538      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
539  EXPECT_EQ(ERR_IO_PENDING, rv);
540  EXPECT_FALSE(handle.is_initialized());
541  EXPECT_FALSE(handle.socket());
542
543  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
544  EXPECT_FALSE(handle.is_initialized());
545  EXPECT_FALSE(handle.socket());
546  EXPECT_FALSE(handle.is_ssl_error());
547}
548
549TEST_P(SSLClientSocketPoolTest, SOCKSBasic) {
550  StaticSocketDataProvider data;
551  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
552  socket_factory_.AddSocketDataProvider(&data);
553  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
554  socket_factory_.AddSSLSocketDataProvider(&ssl);
555
556  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
557  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
558                                                    false);
559
560  ClientSocketHandle handle;
561  TestCompletionCallback callback;
562  int rv = handle.Init(
563      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
564  EXPECT_EQ(OK, rv);
565  EXPECT_TRUE(handle.is_initialized());
566  EXPECT_TRUE(handle.socket());
567  // SOCKS5 generally has no DNS times, but the mock SOCKS5 sockets used here
568  // don't go through the real logic, unlike in the HTTP proxy tests.
569  TestLoadTimingInfo(handle);
570}
571
572// Make sure that SSLConnectJob passes on its priority to its
573// transport socket on Init (for the SOCKS_PROXY case).
574TEST_P(SSLClientSocketPoolTest, SetTransportPriorityOnInitSOCKS) {
575  StaticSocketDataProvider data;
576  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
577  socket_factory_.AddSocketDataProvider(&data);
578  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
579  socket_factory_.AddSSLSocketDataProvider(&ssl);
580
581  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
582  scoped_refptr<SSLSocketParams> params =
583      SSLParams(ProxyServer::SCHEME_SOCKS5, false);
584
585  ClientSocketHandle handle;
586  TestCompletionCallback callback;
587  EXPECT_EQ(OK, handle.Init("a", params, HIGHEST, callback.callback(),
588                            pool_.get(), BoundNetLog()));
589  EXPECT_EQ(HIGHEST, transport_socket_pool_.last_request_priority());
590}
591
592TEST_P(SSLClientSocketPoolTest, SOCKSBasicAsync) {
593  StaticSocketDataProvider data;
594  socket_factory_.AddSocketDataProvider(&data);
595  SSLSocketDataProvider ssl(ASYNC, OK);
596  socket_factory_.AddSSLSocketDataProvider(&ssl);
597
598  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
599  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
600                                                    false);
601
602  ClientSocketHandle handle;
603  TestCompletionCallback callback;
604  int rv = handle.Init(
605      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
606  EXPECT_EQ(ERR_IO_PENDING, rv);
607  EXPECT_FALSE(handle.is_initialized());
608  EXPECT_FALSE(handle.socket());
609
610  EXPECT_EQ(OK, callback.WaitForResult());
611  EXPECT_TRUE(handle.is_initialized());
612  EXPECT_TRUE(handle.socket());
613  // SOCKS5 generally has no DNS times, but the mock SOCKS5 sockets used here
614  // don't go through the real logic, unlike in the HTTP proxy tests.
615  TestLoadTimingInfo(handle);
616}
617
618TEST_P(SSLClientSocketPoolTest, HttpProxyFail) {
619  StaticSocketDataProvider data;
620  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
621  socket_factory_.AddSocketDataProvider(&data);
622
623  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
624  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
625                                                    false);
626
627  ClientSocketHandle handle;
628  TestCompletionCallback callback;
629  int rv = handle.Init(
630      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
631  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
632  EXPECT_FALSE(handle.is_initialized());
633  EXPECT_FALSE(handle.socket());
634  EXPECT_FALSE(handle.is_ssl_error());
635}
636
637TEST_P(SSLClientSocketPoolTest, HttpProxyFailAsync) {
638  StaticSocketDataProvider data;
639  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
640  socket_factory_.AddSocketDataProvider(&data);
641
642  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
643  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
644                                                    false);
645
646  ClientSocketHandle handle;
647  TestCompletionCallback callback;
648  int rv = handle.Init(
649      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
650  EXPECT_EQ(ERR_IO_PENDING, rv);
651  EXPECT_FALSE(handle.is_initialized());
652  EXPECT_FALSE(handle.socket());
653
654  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback.WaitForResult());
655  EXPECT_FALSE(handle.is_initialized());
656  EXPECT_FALSE(handle.socket());
657  EXPECT_FALSE(handle.is_ssl_error());
658}
659
660TEST_P(SSLClientSocketPoolTest, HttpProxyBasic) {
661  MockWrite writes[] = {
662      MockWrite(SYNCHRONOUS,
663                "CONNECT host:80 HTTP/1.1\r\n"
664                "Host: host\r\n"
665                "Proxy-Connection: keep-alive\r\n"
666                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
667  };
668  MockRead reads[] = {
669      MockRead(SYNCHRONOUS, "HTTP/1.1 200 Connection Established\r\n\r\n"),
670  };
671  StaticSocketDataProvider data(reads, arraysize(reads), writes,
672                                arraysize(writes));
673  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
674  socket_factory_.AddSocketDataProvider(&data);
675  AddAuthToCache();
676  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
677  socket_factory_.AddSSLSocketDataProvider(&ssl);
678
679  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
680  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
681                                                    false);
682
683  ClientSocketHandle handle;
684  TestCompletionCallback callback;
685  int rv = handle.Init(
686      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
687  EXPECT_EQ(OK, rv);
688  EXPECT_TRUE(handle.is_initialized());
689  EXPECT_TRUE(handle.socket());
690  TestLoadTimingInfoNoDns(handle);
691}
692
693// Make sure that SSLConnectJob passes on its priority to its
694// transport socket on Init (for the HTTP_PROXY case).
695TEST_P(SSLClientSocketPoolTest, SetTransportPriorityOnInitHTTP) {
696  MockWrite writes[] = {
697      MockWrite(SYNCHRONOUS,
698                "CONNECT host:80 HTTP/1.1\r\n"
699                "Host: host\r\n"
700                "Proxy-Connection: keep-alive\r\n"
701                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
702  };
703  MockRead reads[] = {
704      MockRead(SYNCHRONOUS, "HTTP/1.1 200 Connection Established\r\n\r\n"),
705  };
706  StaticSocketDataProvider data(reads, arraysize(reads), writes,
707                                arraysize(writes));
708  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
709  socket_factory_.AddSocketDataProvider(&data);
710  AddAuthToCache();
711  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
712  socket_factory_.AddSSLSocketDataProvider(&ssl);
713
714  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
715  scoped_refptr<SSLSocketParams> params =
716      SSLParams(ProxyServer::SCHEME_HTTP, false);
717
718  ClientSocketHandle handle;
719  TestCompletionCallback callback;
720  EXPECT_EQ(OK, handle.Init("a", params, HIGHEST, callback.callback(),
721                            pool_.get(), BoundNetLog()));
722  EXPECT_EQ(HIGHEST, transport_socket_pool_.last_request_priority());
723}
724
725TEST_P(SSLClientSocketPoolTest, HttpProxyBasicAsync) {
726  MockWrite writes[] = {
727      MockWrite("CONNECT host:80 HTTP/1.1\r\n"
728                "Host: host\r\n"
729                "Proxy-Connection: keep-alive\r\n"
730                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
731  };
732  MockRead reads[] = {
733      MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
734  };
735  StaticSocketDataProvider data(reads, arraysize(reads), writes,
736                                arraysize(writes));
737  socket_factory_.AddSocketDataProvider(&data);
738  AddAuthToCache();
739  SSLSocketDataProvider ssl(ASYNC, OK);
740  socket_factory_.AddSSLSocketDataProvider(&ssl);
741
742  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
743  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
744                                                    false);
745
746  ClientSocketHandle handle;
747  TestCompletionCallback callback;
748  int rv = handle.Init(
749      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
750  EXPECT_EQ(ERR_IO_PENDING, rv);
751  EXPECT_FALSE(handle.is_initialized());
752  EXPECT_FALSE(handle.socket());
753
754  EXPECT_EQ(OK, callback.WaitForResult());
755  EXPECT_TRUE(handle.is_initialized());
756  EXPECT_TRUE(handle.socket());
757  TestLoadTimingInfoNoDns(handle);
758}
759
760TEST_P(SSLClientSocketPoolTest, NeedProxyAuth) {
761  MockWrite writes[] = {
762      MockWrite("CONNECT host:80 HTTP/1.1\r\n"
763                "Host: host\r\n"
764                "Proxy-Connection: keep-alive\r\n\r\n"),
765  };
766  MockRead reads[] = {
767      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
768      MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
769      MockRead("Content-Length: 10\r\n\r\n"),
770      MockRead("0123456789"),
771  };
772  StaticSocketDataProvider data(reads, arraysize(reads), writes,
773                                arraysize(writes));
774  socket_factory_.AddSocketDataProvider(&data);
775  SSLSocketDataProvider ssl(ASYNC, OK);
776  socket_factory_.AddSSLSocketDataProvider(&ssl);
777
778  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
779  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
780                                                    false);
781
782  ClientSocketHandle handle;
783  TestCompletionCallback callback;
784  int rv = handle.Init(
785      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
786  EXPECT_EQ(ERR_IO_PENDING, rv);
787  EXPECT_FALSE(handle.is_initialized());
788  EXPECT_FALSE(handle.socket());
789
790  EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
791  EXPECT_FALSE(handle.is_initialized());
792  EXPECT_FALSE(handle.socket());
793  EXPECT_FALSE(handle.is_ssl_error());
794  const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
795  EXPECT_EQ(tunnel_info.headers->response_code(), 407);
796  scoped_ptr<ClientSocketHandle> tunnel_handle(
797      handle.release_pending_http_proxy_connection());
798  EXPECT_TRUE(tunnel_handle->socket());
799  EXPECT_FALSE(tunnel_handle->socket()->IsConnected());
800}
801
802TEST_P(SSLClientSocketPoolTest, IPPooling) {
803  const int kTestPort = 80;
804  struct TestHosts {
805    std::string name;
806    std::string iplist;
807    SpdySessionKey key;
808    AddressList addresses;
809  } test_hosts[] = {
810    { "www.webkit.org",    "192.0.2.33,192.168.0.1,192.168.0.5" },
811    { "code.google.com",   "192.168.0.2,192.168.0.3,192.168.0.5" },
812    { "js.webkit.org",     "192.168.0.4,192.168.0.1,192.0.2.33" },
813  };
814
815  host_resolver_.set_synchronous_mode(true);
816  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
817    host_resolver_.rules()->AddIPLiteralRule(
818        test_hosts[i].name, test_hosts[i].iplist, std::string());
819
820    // This test requires that the HostResolver cache be populated.  Normal
821    // code would have done this already, but we do it manually.
822    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
823    host_resolver_.Resolve(info,
824                           DEFAULT_PRIORITY,
825                           &test_hosts[i].addresses,
826                           CompletionCallback(),
827                           NULL,
828                           BoundNetLog());
829
830    // Setup a SpdySessionKey
831    test_hosts[i].key = SpdySessionKey(
832        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(),
833        kPrivacyModeDisabled);
834  }
835
836  MockRead reads[] = {
837      MockRead(ASYNC, ERR_IO_PENDING),
838  };
839  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
840  socket_factory_.AddSocketDataProvider(&data);
841  SSLSocketDataProvider ssl(ASYNC, OK);
842  ssl.cert = X509Certificate::CreateFromBytes(
843      reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der));
844  ssl.SetNextProto(GetParam());
845  socket_factory_.AddSSLSocketDataProvider(&ssl);
846
847  CreatePool(true /* tcp pool */, false, false);
848  base::WeakPtr<SpdySession> spdy_session =
849      CreateSecureSpdySession(session_, test_hosts[0].key, BoundNetLog());
850
851  EXPECT_TRUE(
852      HasSpdySession(session_->spdy_session_pool(), test_hosts[0].key));
853  EXPECT_FALSE(
854      HasSpdySession(session_->spdy_session_pool(), test_hosts[1].key));
855  EXPECT_TRUE(
856      HasSpdySession(session_->spdy_session_pool(), test_hosts[2].key));
857
858  session_->spdy_session_pool()->CloseAllSessions();
859}
860
861void SSLClientSocketPoolTest::TestIPPoolingDisabled(
862    SSLSocketDataProvider* ssl) {
863  const int kTestPort = 80;
864  struct TestHosts {
865    std::string name;
866    std::string iplist;
867    SpdySessionKey key;
868    AddressList addresses;
869  } test_hosts[] = {
870    { "www.webkit.org",    "192.0.2.33,192.168.0.1,192.168.0.5" },
871    { "js.webkit.com",     "192.168.0.4,192.168.0.1,192.0.2.33" },
872  };
873
874  TestCompletionCallback callback;
875  int rv;
876  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
877    host_resolver_.rules()->AddIPLiteralRule(
878        test_hosts[i].name, test_hosts[i].iplist, std::string());
879
880    // This test requires that the HostResolver cache be populated.  Normal
881    // code would have done this already, but we do it manually.
882    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
883    rv = host_resolver_.Resolve(info,
884                                DEFAULT_PRIORITY,
885                                &test_hosts[i].addresses,
886                                callback.callback(),
887                                NULL,
888                                BoundNetLog());
889    EXPECT_EQ(OK, callback.GetResult(rv));
890
891    // Setup a SpdySessionKey
892    test_hosts[i].key = SpdySessionKey(
893        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(),
894        kPrivacyModeDisabled);
895  }
896
897  MockRead reads[] = {
898      MockRead(ASYNC, ERR_IO_PENDING),
899  };
900  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
901  socket_factory_.AddSocketDataProvider(&data);
902  socket_factory_.AddSSLSocketDataProvider(ssl);
903
904  CreatePool(true /* tcp pool */, false, false);
905  base::WeakPtr<SpdySession> spdy_session =
906      CreateSecureSpdySession(session_, test_hosts[0].key, BoundNetLog());
907
908  EXPECT_TRUE(
909      HasSpdySession(session_->spdy_session_pool(), test_hosts[0].key));
910  EXPECT_FALSE(
911      HasSpdySession(session_->spdy_session_pool(), test_hosts[1].key));
912
913  session_->spdy_session_pool()->CloseAllSessions();
914}
915
916// Verifies that an SSL connection with client authentication disables SPDY IP
917// pooling.
918TEST_P(SSLClientSocketPoolTest, IPPoolingClientCert) {
919  SSLSocketDataProvider ssl(ASYNC, OK);
920  ssl.cert = X509Certificate::CreateFromBytes(
921      reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der));
922  ssl.client_cert_sent = true;
923  ssl.SetNextProto(GetParam());
924  TestIPPoolingDisabled(&ssl);
925}
926
927// Verifies that an SSL connection with channel ID disables SPDY IP pooling.
928TEST_P(SSLClientSocketPoolTest, IPPoolingChannelID) {
929  SSLSocketDataProvider ssl(ASYNC, OK);
930  ssl.channel_id_sent = true;
931  ssl.SetNextProto(GetParam());
932  TestIPPoolingDisabled(&ssl);
933}
934
935// It would be nice to also test the timeouts in SSLClientSocketPool.
936
937}  // namespace
938
939}  // namespace net
940