1// Copyright (c) 2011 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/string_util.h"
10#include "base/time.h"
11#include "base/utf_string_conversions.h"
12#include "net/base/auth.h"
13#include "net/base/cert_verifier.h"
14#include "net/base/mock_host_resolver.h"
15#include "net/base/net_errors.h"
16#include "net/base/ssl_config_service_defaults.h"
17#include "net/base/test_certificate_data.h"
18#include "net/base/test_completion_callback.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/proxy/proxy_service.h"
24#include "net/socket/client_socket_handle.h"
25#include "net/socket/client_socket_pool_histograms.h"
26#include "net/socket/socket_test_util.h"
27#include "net/spdy/spdy_session.h"
28#include "net/spdy/spdy_session_pool.h"
29#include "testing/gtest/include/gtest/gtest.h"
30
31namespace net {
32
33namespace {
34
35const int kMaxSockets = 32;
36const int kMaxSocketsPerGroup = 6;
37
38class SSLClientSocketPoolTest : public testing::Test {
39 protected:
40  SSLClientSocketPoolTest()
41      : proxy_service_(ProxyService::CreateDirect()),
42        ssl_config_service_(new SSLConfigServiceDefaults),
43        http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault(
44            &host_resolver_)),
45        session_(CreateNetworkSession()),
46        direct_transport_socket_params_(new TransportSocketParams(
47            HostPortPair("host", 443), MEDIUM, GURL(), false, false)),
48        transport_histograms_("MockTCP"),
49        transport_socket_pool_(
50            kMaxSockets,
51            kMaxSocketsPerGroup,
52            &transport_histograms_,
53            &socket_factory_),
54        proxy_transport_socket_params_(new TransportSocketParams(
55            HostPortPair("proxy", 443), MEDIUM, GURL(), false, false)),
56        socks_socket_params_(new SOCKSSocketParams(
57            proxy_transport_socket_params_, true,
58            HostPortPair("sockshost", 443), MEDIUM, GURL())),
59        socks_histograms_("MockSOCKS"),
60        socks_socket_pool_(
61            kMaxSockets,
62            kMaxSocketsPerGroup,
63            &socks_histograms_,
64            &transport_socket_pool_),
65        http_proxy_socket_params_(new HttpProxySocketParams(
66            proxy_transport_socket_params_, NULL, GURL("http://host"), "",
67            HostPortPair("host", 80),
68            session_->http_auth_cache(),
69            session_->http_auth_handler_factory(),
70            session_->spdy_session_pool(),
71            true)),
72        http_proxy_histograms_("MockHttpProxy"),
73        http_proxy_socket_pool_(
74            kMaxSockets,
75            kMaxSocketsPerGroup,
76            &http_proxy_histograms_,
77            &host_resolver_,
78            &transport_socket_pool_,
79            NULL,
80            NULL) {
81    scoped_refptr<SSLConfigService> ssl_config_service(
82        new SSLConfigServiceDefaults);
83    ssl_config_service->GetSSLConfig(&ssl_config_);
84  }
85
86  void CreatePool(bool transport_pool, bool http_proxy_pool, bool socks_pool) {
87    ssl_histograms_.reset(new ClientSocketPoolHistograms("SSLUnitTest"));
88    pool_.reset(new SSLClientSocketPool(
89        kMaxSockets,
90        kMaxSocketsPerGroup,
91        ssl_histograms_.get(),
92        NULL /* host_resolver */,
93        NULL /* cert_verifier */,
94        NULL /* dnsrr_resolver */,
95        NULL /* dns_cert_checker */,
96        NULL /* ssl_host_info_factory */,
97        &socket_factory_,
98        transport_pool ? &transport_socket_pool_ : NULL,
99        socks_pool ? &socks_socket_pool_ : NULL,
100        http_proxy_pool ? &http_proxy_socket_pool_ : NULL,
101        NULL,
102        NULL));
103  }
104
105  scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy,
106                                           bool want_spdy_over_npn) {
107    return make_scoped_refptr(new SSLSocketParams(
108        proxy == ProxyServer::SCHEME_DIRECT ?
109            direct_transport_socket_params_ : NULL,
110        proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : NULL,
111        proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : NULL,
112        proxy,
113        HostPortPair("host", 443),
114        ssl_config_,
115        0,
116        false,
117        want_spdy_over_npn));
118  }
119
120  void AddAuthToCache() {
121    const string16 kFoo(ASCIIToUTF16("foo"));
122    const string16 kBar(ASCIIToUTF16("bar"));
123    session_->http_auth_cache()->Add(GURL("http://proxy:443/"),
124                                     "MyRealm1",
125                                     HttpAuth::AUTH_SCHEME_BASIC,
126                                     "Basic realm=MyRealm1",
127                                     kFoo,
128                                     kBar,
129                                     "/");
130  }
131
132  HttpNetworkSession* CreateNetworkSession() {
133    HttpNetworkSession::Params params;
134    params.host_resolver = &host_resolver_;
135    params.cert_verifier = &cert_verifier_;
136    params.proxy_service = proxy_service_;
137    params.client_socket_factory = &socket_factory_;
138    params.ssl_config_service = ssl_config_service_;
139    params.http_auth_handler_factory = http_auth_handler_factory_.get();
140    return new HttpNetworkSession(params);
141  }
142
143  MockClientSocketFactory socket_factory_;
144  MockCachingHostResolver host_resolver_;
145  CertVerifier cert_verifier_;
146  const scoped_refptr<ProxyService> proxy_service_;
147  const scoped_refptr<SSLConfigService> ssl_config_service_;
148  const scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
149  const scoped_refptr<HttpNetworkSession> session_;
150
151  scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
152  ClientSocketPoolHistograms transport_histograms_;
153  MockTransportClientSocketPool transport_socket_pool_;
154
155  scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
156
157  scoped_refptr<SOCKSSocketParams> socks_socket_params_;
158  ClientSocketPoolHistograms socks_histograms_;
159  MockSOCKSClientSocketPool socks_socket_pool_;
160
161  scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
162  ClientSocketPoolHistograms http_proxy_histograms_;
163  HttpProxyClientSocketPool http_proxy_socket_pool_;
164
165  SSLConfig ssl_config_;
166  scoped_ptr<ClientSocketPoolHistograms> ssl_histograms_;
167  scoped_ptr<SSLClientSocketPool> pool_;
168};
169
170TEST_F(SSLClientSocketPoolTest, TCPFail) {
171  StaticSocketDataProvider data;
172  data.set_connect_data(MockConnect(false, ERR_CONNECTION_FAILED));
173  socket_factory_.AddSocketDataProvider(&data);
174
175  CreatePool(true /* tcp pool */, false, false);
176  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
177                                                    false);
178
179  ClientSocketHandle handle;
180  int rv = handle.Init("a", params, MEDIUM, NULL, pool_.get(), BoundNetLog());
181  EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
182  EXPECT_FALSE(handle.is_initialized());
183  EXPECT_FALSE(handle.socket());
184  EXPECT_FALSE(handle.is_ssl_error());
185}
186
187TEST_F(SSLClientSocketPoolTest, TCPFailAsync) {
188  StaticSocketDataProvider data;
189  data.set_connect_data(MockConnect(true, ERR_CONNECTION_FAILED));
190  socket_factory_.AddSocketDataProvider(&data);
191
192  CreatePool(true /* tcp pool */, false, false);
193  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
194                                                    false);
195
196  ClientSocketHandle handle;
197  TestCompletionCallback callback;
198  int rv = handle.Init(
199      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
200  EXPECT_EQ(ERR_IO_PENDING, rv);
201  EXPECT_FALSE(handle.is_initialized());
202  EXPECT_FALSE(handle.socket());
203
204  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
205  EXPECT_FALSE(handle.is_initialized());
206  EXPECT_FALSE(handle.socket());
207  EXPECT_FALSE(handle.is_ssl_error());
208}
209
210TEST_F(SSLClientSocketPoolTest, BasicDirect) {
211  StaticSocketDataProvider data;
212  data.set_connect_data(MockConnect(false, OK));
213  socket_factory_.AddSocketDataProvider(&data);
214  SSLSocketDataProvider ssl(false, OK);
215  socket_factory_.AddSSLSocketDataProvider(&ssl);
216
217  CreatePool(true /* tcp pool */, false, false);
218  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
219                                                    false);
220
221  ClientSocketHandle handle;
222  TestCompletionCallback callback;
223  int rv = handle.Init(
224      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
225  EXPECT_EQ(OK, rv);
226  EXPECT_TRUE(handle.is_initialized());
227  EXPECT_TRUE(handle.socket());
228}
229
230TEST_F(SSLClientSocketPoolTest, BasicDirectAsync) {
231  StaticSocketDataProvider data;
232  socket_factory_.AddSocketDataProvider(&data);
233  SSLSocketDataProvider ssl(true, OK);
234  socket_factory_.AddSSLSocketDataProvider(&ssl);
235
236  CreatePool(true /* tcp pool */, false, false);
237  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
238                                                    false);
239
240  ClientSocketHandle handle;
241  TestCompletionCallback callback;
242  int rv = handle.Init(
243      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
244  EXPECT_EQ(ERR_IO_PENDING, rv);
245  EXPECT_FALSE(handle.is_initialized());
246  EXPECT_FALSE(handle.socket());
247
248  EXPECT_EQ(OK, callback.WaitForResult());
249  EXPECT_TRUE(handle.is_initialized());
250  EXPECT_TRUE(handle.socket());
251}
252
253TEST_F(SSLClientSocketPoolTest, DirectCertError) {
254  StaticSocketDataProvider data;
255  socket_factory_.AddSocketDataProvider(&data);
256  SSLSocketDataProvider ssl(true, ERR_CERT_COMMON_NAME_INVALID);
257  socket_factory_.AddSSLSocketDataProvider(&ssl);
258
259  CreatePool(true /* tcp pool */, false, false);
260  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
261                                                    false);
262
263  ClientSocketHandle handle;
264  TestCompletionCallback callback;
265  int rv = handle.Init(
266      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
267  EXPECT_EQ(ERR_IO_PENDING, rv);
268  EXPECT_FALSE(handle.is_initialized());
269  EXPECT_FALSE(handle.socket());
270
271  EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, callback.WaitForResult());
272  EXPECT_TRUE(handle.is_initialized());
273  EXPECT_TRUE(handle.socket());
274}
275
276TEST_F(SSLClientSocketPoolTest, DirectSSLError) {
277  StaticSocketDataProvider data;
278  socket_factory_.AddSocketDataProvider(&data);
279  SSLSocketDataProvider ssl(true, ERR_SSL_PROTOCOL_ERROR);
280  socket_factory_.AddSSLSocketDataProvider(&ssl);
281
282  CreatePool(true /* tcp pool */, false, false);
283  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
284                                                    false);
285
286  ClientSocketHandle handle;
287  TestCompletionCallback callback;
288  int rv = handle.Init(
289      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
290  EXPECT_EQ(ERR_IO_PENDING, rv);
291  EXPECT_FALSE(handle.is_initialized());
292  EXPECT_FALSE(handle.socket());
293
294  EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, callback.WaitForResult());
295  EXPECT_FALSE(handle.is_initialized());
296  EXPECT_FALSE(handle.socket());
297  EXPECT_TRUE(handle.is_ssl_error());
298}
299
300TEST_F(SSLClientSocketPoolTest, DirectWithNPN) {
301  StaticSocketDataProvider data;
302  socket_factory_.AddSocketDataProvider(&data);
303  SSLSocketDataProvider ssl(true, OK);
304  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
305  ssl.next_proto = "http/1.1";
306  socket_factory_.AddSSLSocketDataProvider(&ssl);
307
308  CreatePool(true /* tcp pool */, false, false);
309  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
310                                                    false);
311
312  ClientSocketHandle handle;
313  TestCompletionCallback callback;
314  int rv = handle.Init(
315      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
316  EXPECT_EQ(ERR_IO_PENDING, rv);
317  EXPECT_FALSE(handle.is_initialized());
318  EXPECT_FALSE(handle.socket());
319
320  EXPECT_EQ(OK, callback.WaitForResult());
321  EXPECT_TRUE(handle.is_initialized());
322  EXPECT_TRUE(handle.socket());
323  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
324  EXPECT_TRUE(ssl_socket->was_npn_negotiated());
325}
326
327TEST_F(SSLClientSocketPoolTest, DirectNoSPDY) {
328  StaticSocketDataProvider data;
329  socket_factory_.AddSocketDataProvider(&data);
330  SSLSocketDataProvider ssl(true, OK);
331  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
332  ssl.next_proto = "http/1.1";
333  socket_factory_.AddSSLSocketDataProvider(&ssl);
334
335  CreatePool(true /* tcp pool */, false, false);
336  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
337                                                    true);
338
339  ClientSocketHandle handle;
340  TestCompletionCallback callback;
341  int rv = handle.Init(
342      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
343  EXPECT_EQ(ERR_IO_PENDING, rv);
344  EXPECT_FALSE(handle.is_initialized());
345  EXPECT_FALSE(handle.socket());
346
347  EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.WaitForResult());
348  EXPECT_FALSE(handle.is_initialized());
349  EXPECT_FALSE(handle.socket());
350  EXPECT_TRUE(handle.is_ssl_error());
351}
352
353TEST_F(SSLClientSocketPoolTest, DirectGotSPDY) {
354  StaticSocketDataProvider data;
355  socket_factory_.AddSocketDataProvider(&data);
356  SSLSocketDataProvider ssl(true, OK);
357  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
358  ssl.next_proto = "spdy/2";
359  socket_factory_.AddSSLSocketDataProvider(&ssl);
360
361  CreatePool(true /* tcp pool */, false, false);
362  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
363                                                    true);
364
365  ClientSocketHandle handle;
366  TestCompletionCallback callback;
367  int rv = handle.Init(
368      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
369  EXPECT_EQ(ERR_IO_PENDING, rv);
370  EXPECT_FALSE(handle.is_initialized());
371  EXPECT_FALSE(handle.socket());
372
373  EXPECT_EQ(OK, callback.WaitForResult());
374  EXPECT_TRUE(handle.is_initialized());
375  EXPECT_TRUE(handle.socket());
376
377  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
378  EXPECT_TRUE(ssl_socket->was_npn_negotiated());
379  std::string proto;
380  ssl_socket->GetNextProto(&proto);
381  EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto),
382            SSLClientSocket::kProtoSPDY2);
383}
384
385TEST_F(SSLClientSocketPoolTest, DirectGotBonusSPDY) {
386  StaticSocketDataProvider data;
387  socket_factory_.AddSocketDataProvider(&data);
388  SSLSocketDataProvider ssl(true, OK);
389  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
390  ssl.next_proto = "spdy/2";
391  socket_factory_.AddSSLSocketDataProvider(&ssl);
392
393  CreatePool(true /* tcp pool */, false, false);
394  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
395                                                    true);
396
397  ClientSocketHandle handle;
398  TestCompletionCallback callback;
399  int rv = handle.Init(
400      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
401  EXPECT_EQ(ERR_IO_PENDING, rv);
402  EXPECT_FALSE(handle.is_initialized());
403  EXPECT_FALSE(handle.socket());
404
405  EXPECT_EQ(OK, callback.WaitForResult());
406  EXPECT_TRUE(handle.is_initialized());
407  EXPECT_TRUE(handle.socket());
408
409  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
410  EXPECT_TRUE(ssl_socket->was_npn_negotiated());
411  std::string proto;
412  ssl_socket->GetNextProto(&proto);
413  EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto),
414            SSLClientSocket::kProtoSPDY2);
415}
416
417TEST_F(SSLClientSocketPoolTest, SOCKSFail) {
418  StaticSocketDataProvider data;
419  data.set_connect_data(MockConnect(false, ERR_CONNECTION_FAILED));
420  socket_factory_.AddSocketDataProvider(&data);
421
422  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
423  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
424                                                    false);
425
426  ClientSocketHandle handle;
427  TestCompletionCallback callback;
428  int rv = handle.Init(
429      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
430  EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
431  EXPECT_FALSE(handle.is_initialized());
432  EXPECT_FALSE(handle.socket());
433  EXPECT_FALSE(handle.is_ssl_error());
434}
435
436TEST_F(SSLClientSocketPoolTest, SOCKSFailAsync) {
437  StaticSocketDataProvider data;
438  data.set_connect_data(MockConnect(true, ERR_CONNECTION_FAILED));
439  socket_factory_.AddSocketDataProvider(&data);
440
441  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
442  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
443                                                    false);
444
445  ClientSocketHandle handle;
446  TestCompletionCallback callback;
447  int rv = handle.Init(
448      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
449  EXPECT_EQ(ERR_IO_PENDING, rv);
450  EXPECT_FALSE(handle.is_initialized());
451  EXPECT_FALSE(handle.socket());
452
453  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
454  EXPECT_FALSE(handle.is_initialized());
455  EXPECT_FALSE(handle.socket());
456  EXPECT_FALSE(handle.is_ssl_error());
457}
458
459TEST_F(SSLClientSocketPoolTest, SOCKSBasic) {
460  StaticSocketDataProvider data;
461  data.set_connect_data(MockConnect(false, OK));
462  socket_factory_.AddSocketDataProvider(&data);
463  SSLSocketDataProvider ssl(false, OK);
464  socket_factory_.AddSSLSocketDataProvider(&ssl);
465
466  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
467  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
468                                                    false);
469
470  ClientSocketHandle handle;
471  TestCompletionCallback callback;
472  int rv = handle.Init(
473      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
474  EXPECT_EQ(OK, rv);
475  EXPECT_TRUE(handle.is_initialized());
476  EXPECT_TRUE(handle.socket());
477}
478
479TEST_F(SSLClientSocketPoolTest, SOCKSBasicAsync) {
480  StaticSocketDataProvider data;
481  socket_factory_.AddSocketDataProvider(&data);
482  SSLSocketDataProvider ssl(true, OK);
483  socket_factory_.AddSSLSocketDataProvider(&ssl);
484
485  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
486  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
487                                                    false);
488
489  ClientSocketHandle handle;
490  TestCompletionCallback callback;
491  int rv = handle.Init(
492      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
493  EXPECT_EQ(ERR_IO_PENDING, rv);
494  EXPECT_FALSE(handle.is_initialized());
495  EXPECT_FALSE(handle.socket());
496
497  EXPECT_EQ(OK, callback.WaitForResult());
498  EXPECT_TRUE(handle.is_initialized());
499  EXPECT_TRUE(handle.socket());
500}
501
502TEST_F(SSLClientSocketPoolTest, HttpProxyFail) {
503  StaticSocketDataProvider data;
504  data.set_connect_data(MockConnect(false, ERR_CONNECTION_FAILED));
505  socket_factory_.AddSocketDataProvider(&data);
506
507  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
508  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
509                                                    false);
510
511  ClientSocketHandle handle;
512  TestCompletionCallback callback;
513  int rv = handle.Init(
514      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
515  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
516  EXPECT_FALSE(handle.is_initialized());
517  EXPECT_FALSE(handle.socket());
518  EXPECT_FALSE(handle.is_ssl_error());
519}
520
521TEST_F(SSLClientSocketPoolTest, HttpProxyFailAsync) {
522  StaticSocketDataProvider data;
523  data.set_connect_data(MockConnect(true, ERR_CONNECTION_FAILED));
524  socket_factory_.AddSocketDataProvider(&data);
525
526  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
527  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
528                                                    false);
529
530  ClientSocketHandle handle;
531  TestCompletionCallback callback;
532  int rv = handle.Init(
533      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
534  EXPECT_EQ(ERR_IO_PENDING, rv);
535  EXPECT_FALSE(handle.is_initialized());
536  EXPECT_FALSE(handle.socket());
537
538  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback.WaitForResult());
539  EXPECT_FALSE(handle.is_initialized());
540  EXPECT_FALSE(handle.socket());
541  EXPECT_FALSE(handle.is_ssl_error());
542}
543
544TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) {
545  MockWrite writes[] = {
546      MockWrite(false,
547                "CONNECT host:80 HTTP/1.1\r\n"
548                "Host: host\r\n"
549                "Proxy-Connection: keep-alive\r\n"
550                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
551  };
552  MockRead reads[] = {
553      MockRead(false, "HTTP/1.1 200 Connection Established\r\n\r\n"),
554  };
555  StaticSocketDataProvider data(reads, arraysize(reads), writes,
556                                arraysize(writes));
557  data.set_connect_data(MockConnect(false, OK));
558  socket_factory_.AddSocketDataProvider(&data);
559  AddAuthToCache();
560  SSLSocketDataProvider ssl(false, OK);
561  socket_factory_.AddSSLSocketDataProvider(&ssl);
562
563  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
564  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
565                                                    false);
566
567  ClientSocketHandle handle;
568  TestCompletionCallback callback;
569  int rv = handle.Init(
570      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
571  EXPECT_EQ(OK, rv);
572  EXPECT_TRUE(handle.is_initialized());
573  EXPECT_TRUE(handle.socket());
574}
575
576TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) {
577  MockWrite writes[] = {
578      MockWrite("CONNECT host:80 HTTP/1.1\r\n"
579                "Host: host\r\n"
580                "Proxy-Connection: keep-alive\r\n"
581                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
582  };
583  MockRead reads[] = {
584      MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
585  };
586  StaticSocketDataProvider data(reads, arraysize(reads), writes,
587                                arraysize(writes));
588  socket_factory_.AddSocketDataProvider(&data);
589  AddAuthToCache();
590  SSLSocketDataProvider ssl(true, OK);
591  socket_factory_.AddSSLSocketDataProvider(&ssl);
592
593  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
594  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
595                                                    false);
596
597  ClientSocketHandle handle;
598  TestCompletionCallback callback;
599  int rv = handle.Init(
600      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
601  EXPECT_EQ(ERR_IO_PENDING, rv);
602  EXPECT_FALSE(handle.is_initialized());
603  EXPECT_FALSE(handle.socket());
604
605  EXPECT_EQ(OK, callback.WaitForResult());
606  EXPECT_TRUE(handle.is_initialized());
607  EXPECT_TRUE(handle.socket());
608}
609
610TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) {
611  MockWrite writes[] = {
612      MockWrite("CONNECT host:80 HTTP/1.1\r\n"
613                "Host: host\r\n"
614                "Proxy-Connection: keep-alive\r\n\r\n"),
615  };
616  MockRead reads[] = {
617      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
618      MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
619      MockRead("Content-Length: 10\r\n\r\n"),
620      MockRead("0123456789"),
621  };
622  StaticSocketDataProvider data(reads, arraysize(reads), writes,
623                                arraysize(writes));
624  socket_factory_.AddSocketDataProvider(&data);
625  SSLSocketDataProvider ssl(true, OK);
626  socket_factory_.AddSSLSocketDataProvider(&ssl);
627
628  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
629  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
630                                                    false);
631
632  ClientSocketHandle handle;
633  TestCompletionCallback callback;
634  int rv = handle.Init(
635      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
636  EXPECT_EQ(ERR_IO_PENDING, rv);
637  EXPECT_FALSE(handle.is_initialized());
638  EXPECT_FALSE(handle.socket());
639
640  EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
641  EXPECT_FALSE(handle.is_initialized());
642  EXPECT_FALSE(handle.socket());
643  EXPECT_FALSE(handle.is_ssl_error());
644  const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
645  EXPECT_EQ(tunnel_info.headers->response_code(), 407);
646  scoped_ptr<ClientSocketHandle> tunnel_handle(
647      handle.release_pending_http_proxy_connection());
648  EXPECT_TRUE(tunnel_handle->socket());
649  EXPECT_FALSE(tunnel_handle->socket()->IsConnected());
650}
651
652TEST_F(SSLClientSocketPoolTest, IPPooling) {
653  const int kTestPort = 80;
654  struct TestHosts {
655    std::string name;
656    std::string iplist;
657    HostPortProxyPair pair;
658  } test_hosts[] = {
659    { "www.webkit.org",    "192.168.0.1,192.168.0.5" },
660    { "code.google.com",   "192.168.0.2,192.168.0.3,192.168.0.5" },
661    { "js.webkit.org",     "192.168.0.4,192.168.0.5" },
662  };
663
664  host_resolver_.set_synchronous_mode(true);
665  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
666    host_resolver_.rules()->AddIPLiteralRule(test_hosts[i].name,
667        test_hosts[i].iplist, "");
668
669    // This test requires that the HostResolver cache be populated.  Normal
670    // code would have done this already, but we do it manually.
671    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
672    AddressList result;
673    host_resolver_.Resolve(info, &result, NULL, NULL, BoundNetLog());
674
675    // Setup a HostPortProxyPair
676    test_hosts[i].pair = HostPortProxyPair(
677        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
678  }
679
680  MockRead reads[] = {
681      MockRead(true, ERR_IO_PENDING),
682  };
683  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
684  socket_factory_.AddSocketDataProvider(&data);
685  SSLSocketDataProvider ssl(true, OK);
686  ssl.cert_ = X509Certificate::CreateFromBytes(
687      reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der));
688  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
689  ssl.next_proto = "spdy/2";
690  socket_factory_.AddSSLSocketDataProvider(&ssl);
691
692  CreatePool(true /* tcp pool */, false, false);
693  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
694                                                    true);
695
696  scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle());
697  TestCompletionCallback callback;
698  int rv = handle->Init(
699      "a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
700  EXPECT_EQ(ERR_IO_PENDING, rv);
701  EXPECT_FALSE(handle->is_initialized());
702  EXPECT_FALSE(handle->socket());
703
704  EXPECT_EQ(OK, callback.WaitForResult());
705  EXPECT_TRUE(handle->is_initialized());
706  EXPECT_TRUE(handle->socket());
707
708  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle->socket());
709  EXPECT_TRUE(ssl_socket->was_npn_negotiated());
710  std::string proto;
711  ssl_socket->GetNextProto(&proto);
712  EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto),
713            SSLClientSocket::kProtoSPDY2);
714
715  scoped_refptr<SpdySession> spdy_session;
716  rv = session_->spdy_session_pool()->GetSpdySessionFromSocket(
717    test_hosts[0].pair, handle.release(), BoundNetLog(), 0,
718      &spdy_session, true);
719  EXPECT_EQ(0, rv);
720
721  EXPECT_TRUE(session_->spdy_session_pool()->HasSession(test_hosts[0].pair));
722  EXPECT_FALSE(session_->spdy_session_pool()->HasSession(test_hosts[1].pair));
723  EXPECT_TRUE(session_->spdy_session_pool()->HasSession(test_hosts[2].pair));
724
725  session_->spdy_session_pool()->CloseAllSessions();
726}
727
728// It would be nice to also test the timeouts in SSLClientSocketPool.
729
730}  // namespace
731
732}  // namespace net
733