blob: 2cc564bf645fdcfa9a7e356eb55a87df9c7eeeea [file] [log] [blame]
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/http/http_proxy_client_socket_pool.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/string_util.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "net/base/auth.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/base/ssl_config_service_defaults.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool_histograms.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/spdy_session_pool.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
const int kMaxSockets = 32;
const int kMaxSocketsPerGroup = 6;
class SSLClientSocketPoolTest : public testing::Test {
protected:
SSLClientSocketPoolTest()
: host_resolver_(new MockHostResolver),
http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault(
host_resolver_.get())),
session_(new HttpNetworkSession(host_resolver_.get(),
NULL /* dnsrr_resolver */,
ProxyService::CreateDirect(),
&socket_factory_,
new SSLConfigServiceDefaults,
new SpdySessionPool(NULL),
http_auth_handler_factory_.get(),
NULL,
NULL)),
direct_tcp_socket_params_(new TCPSocketParams(
HostPortPair("host", 443), MEDIUM, GURL(), false)),
tcp_histograms_("MockTCP"),
tcp_socket_pool_(
kMaxSockets,
kMaxSocketsPerGroup,
&tcp_histograms_,
&socket_factory_),
proxy_tcp_socket_params_(new TCPSocketParams(
HostPortPair("proxy", 443), MEDIUM, GURL(), false)),
socks_socket_params_(new SOCKSSocketParams(
proxy_tcp_socket_params_, true, HostPortPair("sockshost", 443),
MEDIUM, GURL())),
socks_histograms_("MockSOCKS"),
socks_socket_pool_(
kMaxSockets,
kMaxSocketsPerGroup,
&socks_histograms_,
&tcp_socket_pool_),
http_proxy_socket_params_(new HttpProxySocketParams(
proxy_tcp_socket_params_, NULL, GURL("http://host"), "",
HostPortPair("host", 80),
session_->auth_cache(),
session_->http_auth_handler_factory(),
true)),
http_proxy_histograms_("MockHttpProxy"),
http_proxy_socket_pool_(
kMaxSockets,
kMaxSocketsPerGroup,
&http_proxy_histograms_,
host_resolver_.get(),
&tcp_socket_pool_,
NULL,
NULL) {
scoped_refptr<SSLConfigService> ssl_config_service(
new SSLConfigServiceDefaults);
ssl_config_service->GetSSLConfig(&ssl_config_);
}
void CreatePool(bool tcp_pool, bool http_proxy_pool, bool socks_pool) {
ssl_histograms_.reset(new ClientSocketPoolHistograms("SSLUnitTest"));
pool_.reset(new SSLClientSocketPool(
kMaxSockets,
kMaxSocketsPerGroup,
ssl_histograms_.get(),
NULL,
NULL /* dnsrr_resolver */,
&socket_factory_,
tcp_pool ? &tcp_socket_pool_ : NULL,
socks_pool ? &socks_socket_pool_ : NULL,
http_proxy_pool ? &http_proxy_socket_pool_ : NULL,
NULL,
NULL));
}
scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy,
bool want_spdy_over_npn) {
return make_scoped_refptr(new SSLSocketParams(
proxy == ProxyServer::SCHEME_DIRECT ? direct_tcp_socket_params_ : NULL,
proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : NULL,
proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : NULL,
proxy,
"host",
ssl_config_,
0,
false,
want_spdy_over_npn));
}
void AddAuthToCache() {
const string16 kFoo(ASCIIToUTF16("foo"));
const string16 kBar(ASCIIToUTF16("bar"));
session_->auth_cache()->Add(GURL("http://proxy:443/"), "MyRealm1", "Basic",
"Basic realm=MyRealm1", kFoo, kBar, "/");
}
MockClientSocketFactory socket_factory_;
scoped_ptr<HostResolver> host_resolver_;
scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
scoped_refptr<HttpNetworkSession> session_;
scoped_refptr<TCPSocketParams> direct_tcp_socket_params_;
ClientSocketPoolHistograms tcp_histograms_;
MockTCPClientSocketPool tcp_socket_pool_;
scoped_refptr<TCPSocketParams> proxy_tcp_socket_params_;
scoped_refptr<SOCKSSocketParams> socks_socket_params_;
ClientSocketPoolHistograms socks_histograms_;
MockSOCKSClientSocketPool socks_socket_pool_;
scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
ClientSocketPoolHistograms http_proxy_histograms_;
HttpProxyClientSocketPool http_proxy_socket_pool_;
SSLConfig ssl_config_;
scoped_ptr<ClientSocketPoolHistograms> ssl_histograms_;
scoped_ptr<SSLClientSocketPool> pool_;
};
TEST_F(SSLClientSocketPoolTest, TCPFail) {
StaticSocketDataProvider data;
data.set_connect_data(MockConnect(false, ERR_CONNECTION_FAILED));
socket_factory_.AddSocketDataProvider(&data);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
false);
ClientSocketHandle handle;
int rv = handle.Init("a", params, MEDIUM, NULL, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
}
TEST_F(SSLClientSocketPoolTest, TCPFailAsync) {
StaticSocketDataProvider data;
data.set_connect_data(MockConnect(true, ERR_CONNECTION_FAILED));
socket_factory_.AddSocketDataProvider(&data);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
}
TEST_F(SSLClientSocketPoolTest, BasicDirect) {
StaticSocketDataProvider data;
data.set_connect_data(MockConnect(false, OK));
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(false, OK);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
}
TEST_F(SSLClientSocketPoolTest, BasicDirectAsync) {
StaticSocketDataProvider data;
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, OK);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
}
TEST_F(SSLClientSocketPoolTest, DirectCertError) {
StaticSocketDataProvider data;
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, ERR_CERT_COMMON_NAME_INVALID);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, callback.WaitForResult());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
}
TEST_F(SSLClientSocketPoolTest, DirectSSLError) {
StaticSocketDataProvider data;
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, ERR_SSL_PROTOCOL_ERROR);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, callback.WaitForResult());
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_TRUE(handle.is_ssl_error());
}
TEST_F(SSLClientSocketPoolTest, DirectWithNPN) {
StaticSocketDataProvider data;
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, OK);
ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
ssl.next_proto = "http/1.1";
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
EXPECT_TRUE(ssl_socket->was_npn_negotiated());
}
TEST_F(SSLClientSocketPoolTest, DirectNoSPDY) {
StaticSocketDataProvider data;
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, OK);
ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
ssl.next_proto = "http/1.1";
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
true);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.WaitForResult());
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_TRUE(handle.is_ssl_error());
}
TEST_F(SSLClientSocketPoolTest, DirectGotSPDY) {
StaticSocketDataProvider data;
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, OK);
ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
ssl.next_proto = "spdy/2";
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
true);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
EXPECT_TRUE(ssl_socket->was_npn_negotiated());
std::string proto;
ssl_socket->GetNextProto(&proto);
EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto),
SSLClientSocket::kProtoSPDY2);
}
TEST_F(SSLClientSocketPoolTest, DirectGotBonusSPDY) {
StaticSocketDataProvider data;
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, OK);
ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
ssl.next_proto = "spdy/2";
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
true);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
EXPECT_TRUE(ssl_socket->was_npn_negotiated());
std::string proto;
ssl_socket->GetNextProto(&proto);
EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto),
SSLClientSocket::kProtoSPDY2);
}
TEST_F(SSLClientSocketPoolTest, SOCKSFail) {
StaticSocketDataProvider data;
data.set_connect_data(MockConnect(false, ERR_CONNECTION_FAILED));
socket_factory_.AddSocketDataProvider(&data);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
}
TEST_F(SSLClientSocketPoolTest, SOCKSFailAsync) {
StaticSocketDataProvider data;
data.set_connect_data(MockConnect(true, ERR_CONNECTION_FAILED));
socket_factory_.AddSocketDataProvider(&data);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
}
TEST_F(SSLClientSocketPoolTest, SOCKSBasic) {
StaticSocketDataProvider data;
data.set_connect_data(MockConnect(false, OK));
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(false, OK);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
}
TEST_F(SSLClientSocketPoolTest, SOCKSBasicAsync) {
StaticSocketDataProvider data;
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, OK);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
}
TEST_F(SSLClientSocketPoolTest, HttpProxyFail) {
StaticSocketDataProvider data;
data.set_connect_data(MockConnect(false, ERR_CONNECTION_FAILED));
socket_factory_.AddSocketDataProvider(&data);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
}
TEST_F(SSLClientSocketPoolTest, HttpProxyFailAsync) {
StaticSocketDataProvider data;
data.set_connect_data(MockConnect(true, ERR_CONNECTION_FAILED));
socket_factory_.AddSocketDataProvider(&data);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback.WaitForResult());
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
}
TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) {
MockWrite writes[] = {
MockWrite(false,
"CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n"
"Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead(false, "HTTP/1.1 200 Connection Established\r\n\r\n"),
};
StaticSocketDataProvider data(reads, arraysize(reads), writes,
arraysize(writes));
data.set_connect_data(MockConnect(false, OK));
socket_factory_.AddSocketDataProvider(&data);
AddAuthToCache();
SSLSocketDataProvider ssl(false, OK);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
}
TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) {
MockWrite writes[] = {
MockWrite("CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n"
"Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
};
StaticSocketDataProvider data(reads, arraysize(reads), writes,
arraysize(writes));
socket_factory_.AddSocketDataProvider(&data);
AddAuthToCache();
SSLSocketDataProvider ssl(true, OK);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(OK, callback.WaitForResult());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
}
TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) {
MockWrite writes[] = {
MockWrite("CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n\r\n"),
};
MockRead reads[] = {
MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
MockRead("Content-Length: 10\r\n\r\n"),
MockRead("0123456789"),
};
StaticSocketDataProvider data(reads, arraysize(reads), writes,
arraysize(writes));
socket_factory_.AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(true, OK);
socket_factory_.AddSSLSocketDataProvider(&ssl);
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
false);
ClientSocketHandle handle;
TestCompletionCallback callback;
int rv = handle.Init(
"a", params, MEDIUM, &callback, pool_.get(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
EXPECT_FALSE(handle.is_initialized());
EXPECT_FALSE(handle.socket());
EXPECT_FALSE(handle.is_ssl_error());
const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
EXPECT_EQ(tunnel_info.headers->response_code(), 407);
scoped_ptr<ClientSocketHandle> tunnel_handle(
handle.release_pending_http_proxy_connection());
EXPECT_TRUE(tunnel_handle->socket());
EXPECT_FALSE(tunnel_handle->socket()->IsConnected());
}
// It would be nice to also test the timeouts in SSLClientSocketPool.
} // namespace
} // namespace net