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                                      MEDIUM,
89                                      false,
90                                      false,
91                                      OnHostResolutionCallback())),
92        transport_histograms_("MockTCP"),
93        transport_socket_pool_(kMaxSockets,
94                               kMaxSocketsPerGroup,
95                               &transport_histograms_,
96                               &socket_factory_),
97        proxy_transport_socket_params_(
98            new TransportSocketParams(HostPortPair("proxy", 443),
99                                      MEDIUM,
100                                      false,
101                                      false,
102                                      OnHostResolutionCallback())),
103        socks_socket_params_(
104            new SOCKSSocketParams(proxy_transport_socket_params_,
105                                  true,
106                                  HostPortPair("sockshost", 443),
107                                  MEDIUM)),
108        socks_histograms_("MockSOCKS"),
109        socks_socket_pool_(kMaxSockets,
110                           kMaxSocketsPerGroup,
111                           &socks_histograms_,
112                           &transport_socket_pool_),
113        http_proxy_socket_params_(
114            new HttpProxySocketParams(proxy_transport_socket_params_,
115                                      NULL,
116                                      GURL("http://host"),
117                                      std::string(),
118                                      HostPortPair("host", 80),
119                                      session_->http_auth_cache(),
120                                      session_->http_auth_handler_factory(),
121                                      session_->spdy_session_pool(),
122                                      true)),
123        http_proxy_histograms_("MockHttpProxy"),
124        http_proxy_socket_pool_(kMaxSockets,
125                                kMaxSocketsPerGroup,
126                                &http_proxy_histograms_,
127                                &host_resolver_,
128                                &transport_socket_pool_,
129                                NULL,
130                                NULL) {
131    scoped_refptr<SSLConfigService> ssl_config_service(
132        new SSLConfigServiceDefaults);
133    ssl_config_service->GetSSLConfig(&ssl_config_);
134  }
135
136  void CreatePool(bool transport_pool, bool http_proxy_pool, bool socks_pool) {
137    ssl_histograms_.reset(new ClientSocketPoolHistograms("SSLUnitTest"));
138    pool_.reset(new SSLClientSocketPool(
139        kMaxSockets,
140        kMaxSocketsPerGroup,
141        ssl_histograms_.get(),
142        NULL /* host_resolver */,
143        NULL /* cert_verifier */,
144        NULL /* server_bound_cert_service */,
145        NULL /* transport_security_state */,
146        std::string() /* ssl_session_cache_shard */,
147        &socket_factory_,
148        transport_pool ? &transport_socket_pool_ : NULL,
149        socks_pool ? &socks_socket_pool_ : NULL,
150        http_proxy_pool ? &http_proxy_socket_pool_ : NULL,
151        NULL,
152        NULL));
153  }
154
155  scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy,
156                                           bool want_spdy_over_npn) {
157    return make_scoped_refptr(new SSLSocketParams(
158        proxy == ProxyServer::SCHEME_DIRECT ? direct_transport_socket_params_
159                                            : NULL,
160        proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : NULL,
161        proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : NULL,
162        proxy,
163        HostPortPair("host", 443),
164        ssl_config_,
165        kPrivacyModeDisabled,
166        0,
167        false,
168        want_spdy_over_npn));
169  }
170
171  void AddAuthToCache() {
172    const base::string16 kFoo(ASCIIToUTF16("foo"));
173    const base::string16 kBar(ASCIIToUTF16("bar"));
174    session_->http_auth_cache()->Add(GURL("http://proxy:443/"),
175                                     "MyRealm1",
176                                     HttpAuth::AUTH_SCHEME_BASIC,
177                                     "Basic realm=MyRealm1",
178                                     AuthCredentials(kFoo, kBar),
179                                     "/");
180  }
181
182  HttpNetworkSession* CreateNetworkSession() {
183    HttpNetworkSession::Params params;
184    params.host_resolver = &host_resolver_;
185    params.cert_verifier = cert_verifier_.get();
186    params.transport_security_state = transport_security_state_.get();
187    params.proxy_service = proxy_service_.get();
188    params.client_socket_factory = &socket_factory_;
189    params.ssl_config_service = ssl_config_service_.get();
190    params.http_auth_handler_factory = http_auth_handler_factory_.get();
191    params.http_server_properties =
192        http_server_properties_.GetWeakPtr();
193    params.enable_spdy_compression = false;
194    params.spdy_default_protocol = GetParam();
195    return new HttpNetworkSession(params);
196  }
197
198  void TestIPPoolingDisabled(SSLSocketDataProvider* ssl);
199
200  MockClientSocketFactory socket_factory_;
201  MockCachingHostResolver host_resolver_;
202  scoped_ptr<CertVerifier> cert_verifier_;
203  scoped_ptr<TransportSecurityState> transport_security_state_;
204  const scoped_ptr<ProxyService> proxy_service_;
205  const scoped_refptr<SSLConfigService> ssl_config_service_;
206  const scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
207  HttpServerPropertiesImpl http_server_properties_;
208  const scoped_refptr<HttpNetworkSession> session_;
209
210  scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
211  ClientSocketPoolHistograms transport_histograms_;
212  MockTransportClientSocketPool transport_socket_pool_;
213
214  scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
215
216  scoped_refptr<SOCKSSocketParams> socks_socket_params_;
217  ClientSocketPoolHistograms socks_histograms_;
218  MockSOCKSClientSocketPool socks_socket_pool_;
219
220  scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
221  ClientSocketPoolHistograms http_proxy_histograms_;
222  HttpProxyClientSocketPool http_proxy_socket_pool_;
223
224  SSLConfig ssl_config_;
225  scoped_ptr<ClientSocketPoolHistograms> ssl_histograms_;
226  scoped_ptr<SSLClientSocketPool> pool_;
227};
228
229INSTANTIATE_TEST_CASE_P(
230    NextProto,
231    SSLClientSocketPoolTest,
232    testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
233                    kProtoHTTP2Draft04));
234
235TEST_P(SSLClientSocketPoolTest, TCPFail) {
236  StaticSocketDataProvider data;
237  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
238  socket_factory_.AddSocketDataProvider(&data);
239
240  CreatePool(true /* tcp pool */, false, false);
241  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
242                                                    false);
243
244  ClientSocketHandle handle;
245  int rv = handle.Init("a", params, MEDIUM, CompletionCallback(), pool_.get(),
246                       BoundNetLog());
247  EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
248  EXPECT_FALSE(handle.is_initialized());
249  EXPECT_FALSE(handle.socket());
250  EXPECT_FALSE(handle.is_ssl_error());
251}
252
253TEST_P(SSLClientSocketPoolTest, TCPFailAsync) {
254  StaticSocketDataProvider data;
255  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
256  socket_factory_.AddSocketDataProvider(&data);
257
258  CreatePool(true /* tcp pool */, false, false);
259  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
260                                                    false);
261
262  ClientSocketHandle handle;
263  TestCompletionCallback callback;
264  int rv = handle.Init(
265      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
266  EXPECT_EQ(ERR_IO_PENDING, rv);
267  EXPECT_FALSE(handle.is_initialized());
268  EXPECT_FALSE(handle.socket());
269
270  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
271  EXPECT_FALSE(handle.is_initialized());
272  EXPECT_FALSE(handle.socket());
273  EXPECT_FALSE(handle.is_ssl_error());
274}
275
276TEST_P(SSLClientSocketPoolTest, BasicDirect) {
277  StaticSocketDataProvider data;
278  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
279  socket_factory_.AddSocketDataProvider(&data);
280  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
281  socket_factory_.AddSSLSocketDataProvider(&ssl);
282
283  CreatePool(true /* tcp pool */, false, false);
284  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
285                                                    false);
286
287  ClientSocketHandle handle;
288  TestCompletionCallback callback;
289  int rv = handle.Init(
290      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
291  EXPECT_EQ(OK, rv);
292  EXPECT_TRUE(handle.is_initialized());
293  EXPECT_TRUE(handle.socket());
294  TestLoadTimingInfo(handle);
295}
296
297TEST_P(SSLClientSocketPoolTest, BasicDirectAsync) {
298  StaticSocketDataProvider data;
299  socket_factory_.AddSocketDataProvider(&data);
300  SSLSocketDataProvider ssl(ASYNC, OK);
301  socket_factory_.AddSSLSocketDataProvider(&ssl);
302
303  CreatePool(true /* tcp pool */, false, false);
304  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
305                                                    false);
306
307  ClientSocketHandle handle;
308  TestCompletionCallback callback;
309  int rv = handle.Init(
310      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
311  EXPECT_EQ(ERR_IO_PENDING, rv);
312  EXPECT_FALSE(handle.is_initialized());
313  EXPECT_FALSE(handle.socket());
314
315  EXPECT_EQ(OK, callback.WaitForResult());
316  EXPECT_TRUE(handle.is_initialized());
317  EXPECT_TRUE(handle.socket());
318  TestLoadTimingInfo(handle);
319}
320
321TEST_P(SSLClientSocketPoolTest, DirectCertError) {
322  StaticSocketDataProvider data;
323  socket_factory_.AddSocketDataProvider(&data);
324  SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
325  socket_factory_.AddSSLSocketDataProvider(&ssl);
326
327  CreatePool(true /* tcp pool */, false, false);
328  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
329                                                    false);
330
331  ClientSocketHandle handle;
332  TestCompletionCallback callback;
333  int rv = handle.Init(
334      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
335  EXPECT_EQ(ERR_IO_PENDING, rv);
336  EXPECT_FALSE(handle.is_initialized());
337  EXPECT_FALSE(handle.socket());
338
339  EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, callback.WaitForResult());
340  EXPECT_TRUE(handle.is_initialized());
341  EXPECT_TRUE(handle.socket());
342  TestLoadTimingInfo(handle);
343}
344
345TEST_P(SSLClientSocketPoolTest, DirectSSLError) {
346  StaticSocketDataProvider data;
347  socket_factory_.AddSocketDataProvider(&data);
348  SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR);
349  socket_factory_.AddSSLSocketDataProvider(&ssl);
350
351  CreatePool(true /* tcp pool */, false, false);
352  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
353                                                    false);
354
355  ClientSocketHandle handle;
356  TestCompletionCallback callback;
357  int rv = handle.Init(
358      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
359  EXPECT_EQ(ERR_IO_PENDING, rv);
360  EXPECT_FALSE(handle.is_initialized());
361  EXPECT_FALSE(handle.socket());
362
363  EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, callback.WaitForResult());
364  EXPECT_FALSE(handle.is_initialized());
365  EXPECT_FALSE(handle.socket());
366  EXPECT_TRUE(handle.is_ssl_error());
367}
368
369TEST_P(SSLClientSocketPoolTest, DirectWithNPN) {
370  StaticSocketDataProvider data;
371  socket_factory_.AddSocketDataProvider(&data);
372  SSLSocketDataProvider ssl(ASYNC, OK);
373  ssl.SetNextProto(kProtoHTTP11);
374  socket_factory_.AddSSLSocketDataProvider(&ssl);
375
376  CreatePool(true /* tcp pool */, false, false);
377  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
378                                                    false);
379
380  ClientSocketHandle handle;
381  TestCompletionCallback callback;
382  int rv = handle.Init(
383      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
384  EXPECT_EQ(ERR_IO_PENDING, rv);
385  EXPECT_FALSE(handle.is_initialized());
386  EXPECT_FALSE(handle.socket());
387
388  EXPECT_EQ(OK, callback.WaitForResult());
389  EXPECT_TRUE(handle.is_initialized());
390  EXPECT_TRUE(handle.socket());
391  TestLoadTimingInfo(handle);
392  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
393  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
394}
395
396TEST_P(SSLClientSocketPoolTest, DirectNoSPDY) {
397  StaticSocketDataProvider data;
398  socket_factory_.AddSocketDataProvider(&data);
399  SSLSocketDataProvider ssl(ASYNC, OK);
400  ssl.SetNextProto(kProtoHTTP11);
401  socket_factory_.AddSSLSocketDataProvider(&ssl);
402
403  CreatePool(true /* tcp pool */, false, false);
404  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
405                                                    true);
406
407  ClientSocketHandle handle;
408  TestCompletionCallback callback;
409  int rv = handle.Init(
410      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
411  EXPECT_EQ(ERR_IO_PENDING, rv);
412  EXPECT_FALSE(handle.is_initialized());
413  EXPECT_FALSE(handle.socket());
414
415  EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.WaitForResult());
416  EXPECT_FALSE(handle.is_initialized());
417  EXPECT_FALSE(handle.socket());
418  EXPECT_TRUE(handle.is_ssl_error());
419}
420
421TEST_P(SSLClientSocketPoolTest, DirectGotSPDY) {
422  StaticSocketDataProvider data;
423  socket_factory_.AddSocketDataProvider(&data);
424  SSLSocketDataProvider ssl(ASYNC, OK);
425  ssl.SetNextProto(GetParam());
426  socket_factory_.AddSSLSocketDataProvider(&ssl);
427
428  CreatePool(true /* tcp pool */, false, false);
429  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
430                                                    true);
431
432  ClientSocketHandle handle;
433  TestCompletionCallback callback;
434  int rv = handle.Init(
435      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
436  EXPECT_EQ(ERR_IO_PENDING, rv);
437  EXPECT_FALSE(handle.is_initialized());
438  EXPECT_FALSE(handle.socket());
439
440  EXPECT_EQ(OK, callback.WaitForResult());
441  EXPECT_TRUE(handle.is_initialized());
442  EXPECT_TRUE(handle.socket());
443  TestLoadTimingInfo(handle);
444
445  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
446  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
447  std::string proto;
448  std::string server_protos;
449  ssl_socket->GetNextProto(&proto, &server_protos);
450  EXPECT_EQ(GetParam(), SSLClientSocket::NextProtoFromString(proto));
451}
452
453TEST_P(SSLClientSocketPoolTest, DirectGotBonusSPDY) {
454  StaticSocketDataProvider data;
455  socket_factory_.AddSocketDataProvider(&data);
456  SSLSocketDataProvider ssl(ASYNC, OK);
457  ssl.SetNextProto(GetParam());
458  socket_factory_.AddSSLSocketDataProvider(&ssl);
459
460  CreatePool(true /* tcp pool */, false, false);
461  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
462                                                    true);
463
464  ClientSocketHandle handle;
465  TestCompletionCallback callback;
466  int rv = handle.Init(
467      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
468  EXPECT_EQ(ERR_IO_PENDING, rv);
469  EXPECT_FALSE(handle.is_initialized());
470  EXPECT_FALSE(handle.socket());
471
472  EXPECT_EQ(OK, callback.WaitForResult());
473  EXPECT_TRUE(handle.is_initialized());
474  EXPECT_TRUE(handle.socket());
475  TestLoadTimingInfo(handle);
476
477  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
478  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
479  std::string proto;
480  std::string server_protos;
481  ssl_socket->GetNextProto(&proto, &server_protos);
482  EXPECT_EQ(GetParam(), SSLClientSocket::NextProtoFromString(proto));
483}
484
485TEST_P(SSLClientSocketPoolTest, SOCKSFail) {
486  StaticSocketDataProvider data;
487  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
488  socket_factory_.AddSocketDataProvider(&data);
489
490  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
491  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
492                                                    false);
493
494  ClientSocketHandle handle;
495  TestCompletionCallback callback;
496  int rv = handle.Init(
497      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
498  EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
499  EXPECT_FALSE(handle.is_initialized());
500  EXPECT_FALSE(handle.socket());
501  EXPECT_FALSE(handle.is_ssl_error());
502}
503
504TEST_P(SSLClientSocketPoolTest, SOCKSFailAsync) {
505  StaticSocketDataProvider data;
506  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
507  socket_factory_.AddSocketDataProvider(&data);
508
509  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
510  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
511                                                    false);
512
513  ClientSocketHandle handle;
514  TestCompletionCallback callback;
515  int rv = handle.Init(
516      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
517  EXPECT_EQ(ERR_IO_PENDING, rv);
518  EXPECT_FALSE(handle.is_initialized());
519  EXPECT_FALSE(handle.socket());
520
521  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
522  EXPECT_FALSE(handle.is_initialized());
523  EXPECT_FALSE(handle.socket());
524  EXPECT_FALSE(handle.is_ssl_error());
525}
526
527TEST_P(SSLClientSocketPoolTest, SOCKSBasic) {
528  StaticSocketDataProvider data;
529  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
530  socket_factory_.AddSocketDataProvider(&data);
531  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
532  socket_factory_.AddSSLSocketDataProvider(&ssl);
533
534  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
535  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
536                                                    false);
537
538  ClientSocketHandle handle;
539  TestCompletionCallback callback;
540  int rv = handle.Init(
541      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
542  EXPECT_EQ(OK, rv);
543  EXPECT_TRUE(handle.is_initialized());
544  EXPECT_TRUE(handle.socket());
545  // SOCKS5 generally has no DNS times, but the mock SOCKS5 sockets used here
546  // don't go through the real logic, unlike in the HTTP proxy tests.
547  TestLoadTimingInfo(handle);
548}
549
550TEST_P(SSLClientSocketPoolTest, SOCKSBasicAsync) {
551  StaticSocketDataProvider data;
552  socket_factory_.AddSocketDataProvider(&data);
553  SSLSocketDataProvider ssl(ASYNC, 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(ERR_IO_PENDING, rv);
565  EXPECT_FALSE(handle.is_initialized());
566  EXPECT_FALSE(handle.socket());
567
568  EXPECT_EQ(OK, callback.WaitForResult());
569  EXPECT_TRUE(handle.is_initialized());
570  EXPECT_TRUE(handle.socket());
571  // SOCKS5 generally has no DNS times, but the mock SOCKS5 sockets used here
572  // don't go through the real logic, unlike in the HTTP proxy tests.
573  TestLoadTimingInfo(handle);
574}
575
576TEST_P(SSLClientSocketPoolTest, HttpProxyFail) {
577  StaticSocketDataProvider data;
578  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
579  socket_factory_.AddSocketDataProvider(&data);
580
581  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
582  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
583                                                    false);
584
585  ClientSocketHandle handle;
586  TestCompletionCallback callback;
587  int rv = handle.Init(
588      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
589  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
590  EXPECT_FALSE(handle.is_initialized());
591  EXPECT_FALSE(handle.socket());
592  EXPECT_FALSE(handle.is_ssl_error());
593}
594
595TEST_P(SSLClientSocketPoolTest, HttpProxyFailAsync) {
596  StaticSocketDataProvider data;
597  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
598  socket_factory_.AddSocketDataProvider(&data);
599
600  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
601  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
602                                                    false);
603
604  ClientSocketHandle handle;
605  TestCompletionCallback callback;
606  int rv = handle.Init(
607      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
608  EXPECT_EQ(ERR_IO_PENDING, rv);
609  EXPECT_FALSE(handle.is_initialized());
610  EXPECT_FALSE(handle.socket());
611
612  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback.WaitForResult());
613  EXPECT_FALSE(handle.is_initialized());
614  EXPECT_FALSE(handle.socket());
615  EXPECT_FALSE(handle.is_ssl_error());
616}
617
618TEST_P(SSLClientSocketPoolTest, HttpProxyBasic) {
619  MockWrite writes[] = {
620      MockWrite(SYNCHRONOUS,
621                "CONNECT host:80 HTTP/1.1\r\n"
622                "Host: host\r\n"
623                "Proxy-Connection: keep-alive\r\n"
624                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
625  };
626  MockRead reads[] = {
627      MockRead(SYNCHRONOUS, "HTTP/1.1 200 Connection Established\r\n\r\n"),
628  };
629  StaticSocketDataProvider data(reads, arraysize(reads), writes,
630                                arraysize(writes));
631  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
632  socket_factory_.AddSocketDataProvider(&data);
633  AddAuthToCache();
634  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
635  socket_factory_.AddSSLSocketDataProvider(&ssl);
636
637  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
638  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
639                                                    false);
640
641  ClientSocketHandle handle;
642  TestCompletionCallback callback;
643  int rv = handle.Init(
644      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
645  EXPECT_EQ(OK, rv);
646  EXPECT_TRUE(handle.is_initialized());
647  EXPECT_TRUE(handle.socket());
648  TestLoadTimingInfoNoDns(handle);
649}
650
651TEST_P(SSLClientSocketPoolTest, HttpProxyBasicAsync) {
652  MockWrite writes[] = {
653      MockWrite("CONNECT host:80 HTTP/1.1\r\n"
654                "Host: host\r\n"
655                "Proxy-Connection: keep-alive\r\n"
656                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
657  };
658  MockRead reads[] = {
659      MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
660  };
661  StaticSocketDataProvider data(reads, arraysize(reads), writes,
662                                arraysize(writes));
663  socket_factory_.AddSocketDataProvider(&data);
664  AddAuthToCache();
665  SSLSocketDataProvider ssl(ASYNC, OK);
666  socket_factory_.AddSSLSocketDataProvider(&ssl);
667
668  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
669  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
670                                                    false);
671
672  ClientSocketHandle handle;
673  TestCompletionCallback callback;
674  int rv = handle.Init(
675      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
676  EXPECT_EQ(ERR_IO_PENDING, rv);
677  EXPECT_FALSE(handle.is_initialized());
678  EXPECT_FALSE(handle.socket());
679
680  EXPECT_EQ(OK, callback.WaitForResult());
681  EXPECT_TRUE(handle.is_initialized());
682  EXPECT_TRUE(handle.socket());
683  TestLoadTimingInfoNoDns(handle);
684}
685
686TEST_P(SSLClientSocketPoolTest, NeedProxyAuth) {
687  MockWrite writes[] = {
688      MockWrite("CONNECT host:80 HTTP/1.1\r\n"
689                "Host: host\r\n"
690                "Proxy-Connection: keep-alive\r\n\r\n"),
691  };
692  MockRead reads[] = {
693      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
694      MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
695      MockRead("Content-Length: 10\r\n\r\n"),
696      MockRead("0123456789"),
697  };
698  StaticSocketDataProvider data(reads, arraysize(reads), writes,
699                                arraysize(writes));
700  socket_factory_.AddSocketDataProvider(&data);
701  SSLSocketDataProvider ssl(ASYNC, OK);
702  socket_factory_.AddSSLSocketDataProvider(&ssl);
703
704  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
705  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
706                                                    false);
707
708  ClientSocketHandle handle;
709  TestCompletionCallback callback;
710  int rv = handle.Init(
711      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
712  EXPECT_EQ(ERR_IO_PENDING, rv);
713  EXPECT_FALSE(handle.is_initialized());
714  EXPECT_FALSE(handle.socket());
715
716  EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
717  EXPECT_FALSE(handle.is_initialized());
718  EXPECT_FALSE(handle.socket());
719  EXPECT_FALSE(handle.is_ssl_error());
720  const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
721  EXPECT_EQ(tunnel_info.headers->response_code(), 407);
722  scoped_ptr<ClientSocketHandle> tunnel_handle(
723      handle.release_pending_http_proxy_connection());
724  EXPECT_TRUE(tunnel_handle->socket());
725  EXPECT_FALSE(tunnel_handle->socket()->IsConnected());
726}
727
728TEST_P(SSLClientSocketPoolTest, IPPooling) {
729  const int kTestPort = 80;
730  struct TestHosts {
731    std::string name;
732    std::string iplist;
733    SpdySessionKey key;
734    AddressList addresses;
735  } test_hosts[] = {
736    { "www.webkit.org",    "192.0.2.33,192.168.0.1,192.168.0.5" },
737    { "code.google.com",   "192.168.0.2,192.168.0.3,192.168.0.5" },
738    { "js.webkit.org",     "192.168.0.4,192.168.0.1,192.0.2.33" },
739  };
740
741  host_resolver_.set_synchronous_mode(true);
742  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
743    host_resolver_.rules()->AddIPLiteralRule(
744        test_hosts[i].name, test_hosts[i].iplist, std::string());
745
746    // This test requires that the HostResolver cache be populated.  Normal
747    // code would have done this already, but we do it manually.
748    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
749    host_resolver_.Resolve(info, &test_hosts[i].addresses, CompletionCallback(),
750                           NULL, BoundNetLog());
751
752    // Setup a SpdySessionKey
753    test_hosts[i].key = SpdySessionKey(
754        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(),
755        kPrivacyModeDisabled);
756  }
757
758  MockRead reads[] = {
759      MockRead(ASYNC, ERR_IO_PENDING),
760  };
761  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
762  socket_factory_.AddSocketDataProvider(&data);
763  SSLSocketDataProvider ssl(ASYNC, OK);
764  ssl.cert = X509Certificate::CreateFromBytes(
765      reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der));
766  ssl.SetNextProto(GetParam());
767  socket_factory_.AddSSLSocketDataProvider(&ssl);
768
769  CreatePool(true /* tcp pool */, false, false);
770  base::WeakPtr<SpdySession> spdy_session =
771      CreateSecureSpdySession(session_, test_hosts[0].key, BoundNetLog());
772
773  EXPECT_TRUE(
774      HasSpdySession(session_->spdy_session_pool(), test_hosts[0].key));
775  EXPECT_FALSE(
776      HasSpdySession(session_->spdy_session_pool(), test_hosts[1].key));
777  EXPECT_TRUE(
778      HasSpdySession(session_->spdy_session_pool(), test_hosts[2].key));
779
780  session_->spdy_session_pool()->CloseAllSessions();
781}
782
783void SSLClientSocketPoolTest::TestIPPoolingDisabled(
784    SSLSocketDataProvider* ssl) {
785  const int kTestPort = 80;
786  struct TestHosts {
787    std::string name;
788    std::string iplist;
789    SpdySessionKey key;
790    AddressList addresses;
791  } test_hosts[] = {
792    { "www.webkit.org",    "192.0.2.33,192.168.0.1,192.168.0.5" },
793    { "js.webkit.com",     "192.168.0.4,192.168.0.1,192.0.2.33" },
794  };
795
796  TestCompletionCallback callback;
797  int rv;
798  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
799    host_resolver_.rules()->AddIPLiteralRule(
800        test_hosts[i].name, test_hosts[i].iplist, std::string());
801
802    // This test requires that the HostResolver cache be populated.  Normal
803    // code would have done this already, but we do it manually.
804    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
805    rv = host_resolver_.Resolve(info, &test_hosts[i].addresses,
806                                callback.callback(), NULL, BoundNetLog());
807    EXPECT_EQ(OK, callback.GetResult(rv));
808
809    // Setup a SpdySessionKey
810    test_hosts[i].key = SpdySessionKey(
811        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(),
812        kPrivacyModeDisabled);
813  }
814
815  MockRead reads[] = {
816      MockRead(ASYNC, ERR_IO_PENDING),
817  };
818  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
819  socket_factory_.AddSocketDataProvider(&data);
820  socket_factory_.AddSSLSocketDataProvider(ssl);
821
822  CreatePool(true /* tcp pool */, false, false);
823  base::WeakPtr<SpdySession> spdy_session =
824      CreateSecureSpdySession(session_, test_hosts[0].key, BoundNetLog());
825
826  EXPECT_TRUE(
827      HasSpdySession(session_->spdy_session_pool(), test_hosts[0].key));
828  EXPECT_FALSE(
829      HasSpdySession(session_->spdy_session_pool(), test_hosts[1].key));
830
831  session_->spdy_session_pool()->CloseAllSessions();
832}
833
834// Verifies that an SSL connection with client authentication disables SPDY IP
835// pooling.
836TEST_P(SSLClientSocketPoolTest, IPPoolingClientCert) {
837  SSLSocketDataProvider ssl(ASYNC, OK);
838  ssl.cert = X509Certificate::CreateFromBytes(
839      reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der));
840  ssl.client_cert_sent = true;
841  ssl.SetNextProto(GetParam());
842  TestIPPoolingDisabled(&ssl);
843}
844
845// Verifies that an SSL connection with channel ID disables SPDY IP pooling.
846TEST_P(SSLClientSocketPoolTest, IPPoolingChannelID) {
847  SSLSocketDataProvider ssl(ASYNC, OK);
848  ssl.channel_id_sent = true;
849  ssl.SetNextProto(GetParam());
850  TestIPPoolingDisabled(&ssl);
851}
852
853// It would be nice to also test the timeouts in SSLClientSocketPool.
854
855}  // namespace
856
857}  // namespace net
858