summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/base/net_error_list.h5
-rw-r--r--net/http/http_network_transaction.cc128
-rw-r--r--net/http/http_network_transaction.h7
-rw-r--r--net/http/http_network_transaction_unittest.cc188
-rw-r--r--net/http/http_proxy_client_socket.cc52
-rw-r--r--net/http/http_proxy_client_socket.h17
-rw-r--r--net/http/http_proxy_client_socket_pool.cc14
-rw-r--r--net/http/http_proxy_client_socket_pool.h9
-rw-r--r--net/http/http_proxy_client_socket_pool_unittest.cc70
-rw-r--r--net/socket/client_socket_handle.cc1
-rw-r--r--net/socket/client_socket_handle.h7
-rw-r--r--net/socket/socket_test_util.cc48
-rw-r--r--net/socket/socket_test_util.h40
-rw-r--r--net/socket/ssl_client_socket_pool.cc28
-rw-r--r--net/socket/ssl_client_socket_pool.h4
-rw-r--r--net/socket/ssl_client_socket_pool_unittest.cc236
16 files changed, 417 insertions, 437 deletions
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h
index e302a9f..53849631 100644
--- a/net/base/net_error_list.h
+++ b/net/base/net_error_list.h
@@ -167,11 +167,6 @@ NET_ERROR(PROXY_AUTH_REQUESTED, -127)
// A known TLS strict server didn't offer the renegotiation extension.
NET_ERROR(SSL_UNSAFE_NEGOTIATION, -128)
-// The socket is reporting that we tried to provide new credentials after a
-// a failed attempt on a connection without keep alive. We need to
-// reestablish the transport socket in order to retry the authentication.
-NET_ERROR(RETRY_CONNECTION, -129)
-
// Certificate error codes
//
// The values of certificate error codes must be consecutive.
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 09a4772..6d77eb1 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -348,7 +348,8 @@ int HttpNetworkTransaction::RestartWithAuth(
if (target == HttpAuth::AUTH_PROXY && using_ssl_ && proxy_info_.is_http()) {
DCHECK(establishing_tunnel_);
- next_state_ = STATE_INIT_CONNECTION;
+ next_state_ = STATE_RESTART_TUNNEL_AUTH;
+ auth_controllers_[target] = NULL;
ResetStateForRestart();
} else {
PrepareForAuthRestart(target);
@@ -549,6 +550,13 @@ int HttpNetworkTransaction::DoLoop(int result) {
case STATE_INIT_CONNECTION_COMPLETE:
rv = DoInitConnectionComplete(rv);
break;
+ case STATE_RESTART_TUNNEL_AUTH:
+ DCHECK_EQ(OK, rv);
+ rv = DoRestartTunnelAuth();
+ break;
+ case STATE_RESTART_TUNNEL_AUTH_COMPLETE:
+ rv = DoRestartTunnelAuthComplete(rv);
+ break;
case STATE_GENERATE_PROXY_AUTH_TOKEN:
DCHECK_EQ(OK, rv);
rv = DoGenerateProxyAuthToken();
@@ -726,15 +734,6 @@ int HttpNetworkTransaction::DoInitConnection() {
DCHECK(proxy_info_.proxy_server().is_valid());
next_state_ = STATE_INIT_CONNECTION_COMPLETE;
- // Now that the proxy server has been resolved, create the auth_controllers_.
- for (int i = 0; i < HttpAuth::AUTH_NUM_TARGETS; i++) {
- HttpAuth::Target target = static_cast<HttpAuth::Target>(i);
- if (!auth_controllers_[target].get())
- auth_controllers_[target] = new HttpAuthController(target,
- AuthURL(target),
- session_);
- }
-
bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol
&& alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2;
using_ssl_ = request_->url.SchemeIs("https") ||
@@ -784,29 +783,24 @@ int HttpNetworkTransaction::DoInitConnection() {
request_->referrer, disable_resolver_cache);
if (proxy_info_.is_http()) {
- scoped_refptr<HttpAuthController> http_proxy_auth;
GURL authentication_url = request_->url;
- if (using_ssl_) {
- if (!authentication_url.SchemeIs("https")) {
- // If a proxy tunnel connection needs to be established due to
- // an Alternate-Protocol, the URL needs to be changed to indicate
- // https or digest authentication attempts will fail.
- // For example, suppose the initial request was for
- // "http://www.example.com/index.html". If this is an SSL
- // upgrade due to alternate protocol, the digest authorization
- // should have a uri="www.example.com:443" field rather than a
- // "/index.html" entry, even though the original request URL has not
- // changed.
- authentication_url = UpgradeUrlToHttps(authentication_url);
- }
- http_proxy_auth = auth_controllers_[HttpAuth::AUTH_PROXY];
- establishing_tunnel_ = true;
+ if (using_ssl_ && !authentication_url.SchemeIs("https")) {
+ // If a proxy tunnel connection needs to be established due to
+ // an Alternate-Protocol, the URL needs to be changed to indicate
+ // https or digest authentication attempts will fail.
+ // For example, suppose the initial request was for
+ // "http://www.example.com/index.html". If this is an SSL
+ // upgrade due to alternate protocol, the digest authorization
+ // should have a uri="www.example.com:443" field rather than a
+ // "/index.html" entry, even though the original request URL has not
+ // changed.
+ authentication_url = UpgradeUrlToHttps(authentication_url);
}
+ establishing_tunnel_ = using_ssl_;
http_proxy_params = new HttpProxySocketParams(proxy_tcp_params,
authentication_url,
endpoint_,
- http_proxy_auth,
- using_ssl_);
+ session_, using_ssl_);
} else {
DCHECK(proxy_info_.is_socks());
char socks_version;
@@ -914,14 +908,13 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) {
if (result == ERR_PROXY_AUTH_REQUESTED) {
DCHECK(!ssl_started);
- const HttpResponseInfo& tunnel_auth_response =
- connection_->ssl_error_response_info();
-
- response_.headers = tunnel_auth_response.headers;
- response_.auth_challenge = tunnel_auth_response.auth_challenge;
- headers_valid_ = true;
- pending_auth_target_ = HttpAuth::AUTH_PROXY;
- return OK;
+ // Other state (i.e. |using_ssl_|) suggests that |connection_| will have an
+ // SSL socket, but there was an error before that could happened. This
+ // puts the in progress HttpProxy socket into |connection_| in order to
+ // complete the auth. The tunnel restart code is carefully to remove it
+ // before returning control to the rest of this class.
+ connection_.reset(connection_->release_pending_http_proxy_connection());
+ return HandleTunnelAuthFailure(result);
}
if ((!ssl_started && result < 0 &&
@@ -1001,12 +994,44 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) {
return OK;
}
+int HttpNetworkTransaction::DoRestartTunnelAuth() {
+ next_state_ = STATE_RESTART_TUNNEL_AUTH_COMPLETE;
+ HttpProxyClientSocket* http_proxy_socket =
+ static_cast<HttpProxyClientSocket*>(connection_->socket());
+ return http_proxy_socket->RestartWithAuth(&io_callback_);
+}
+
+int HttpNetworkTransaction::DoRestartTunnelAuthComplete(int result) {
+ if (result == ERR_PROXY_AUTH_REQUESTED)
+ return HandleTunnelAuthFailure(result);
+
+ if (result == OK) {
+ // Now that we've got the HttpProxyClientSocket connected. We have
+ // to release it as an idle socket into the pool and start the connection
+ // process from the beginning. Trying to pass it in with the
+ // SSLSocketParams might cause a deadlock since params are dispatched
+ // interchangeably. This request won't necessarily get this http proxy
+ // socket, but there will be forward progress.
+ connection_->Reset();
+ establishing_tunnel_ = false;
+ next_state_ = STATE_INIT_CONNECTION;
+ return OK;
+ }
+
+ return ReconsiderProxyAfterError(result);
+}
+
int HttpNetworkTransaction::DoGenerateProxyAuthToken() {
next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
if (!ShouldApplyProxyAuth())
return OK;
- return auth_controllers_[HttpAuth::AUTH_PROXY]->MaybeGenerateAuthToken(
- request_, &io_callback_, net_log_);
+ HttpAuth::Target target = HttpAuth::AUTH_PROXY;
+ if (!auth_controllers_[target].get())
+ auth_controllers_[target] = new HttpAuthController(target, AuthURL(target),
+ session_);
+ return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
+ &io_callback_,
+ net_log_);
}
int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {
@@ -1018,10 +1043,15 @@ int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) {
int HttpNetworkTransaction::DoGenerateServerAuthToken() {
next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE;
+ HttpAuth::Target target = HttpAuth::AUTH_SERVER;
+ if (!auth_controllers_[target].get())
+ auth_controllers_[target] = new HttpAuthController(target, AuthURL(target),
+ session_);
if (!ShouldApplyServerAuth())
return OK;
- return auth_controllers_[HttpAuth::AUTH_SERVER]->MaybeGenerateAuthToken(
- request_, &io_callback_, net_log_);
+ return auth_controllers_[target]->MaybeGenerateAuthToken(request_,
+ &io_callback_,
+ net_log_);
}
int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
@@ -1544,6 +1574,24 @@ void HttpNetworkTransaction::LogTransactionMetrics() const {
}
}
+int HttpNetworkTransaction::HandleTunnelAuthFailure(int error) {
+ DCHECK(establishing_tunnel_);
+ DCHECK_EQ(ERR_PROXY_AUTH_REQUESTED, error);
+ HttpProxyClientSocket* http_proxy_socket =
+ static_cast<HttpProxyClientSocket*>(connection_->socket());
+
+ const HttpResponseInfo* tunnel_auth_response =
+ http_proxy_socket->GetResponseInfo();
+ response_.headers = tunnel_auth_response->headers;
+ response_.auth_challenge = tunnel_auth_response->auth_challenge;
+ headers_valid_ = true;
+
+ auth_controllers_[HttpAuth::AUTH_PROXY] =
+ http_proxy_socket->auth_controller();
+ pending_auth_target_ = HttpAuth::AUTH_PROXY;
+ return OK;
+}
+
int HttpNetworkTransaction::HandleCertificateError(int error) {
DCHECK(using_ssl_);
DCHECK(IsCertificateError(error));
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h
index 8117325..b3a083c 100644
--- a/net/http/http_network_transaction.h
+++ b/net/http/http_network_transaction.h
@@ -91,6 +91,8 @@ class HttpNetworkTransaction : public HttpTransaction {
STATE_RESOLVE_PROXY_COMPLETE,
STATE_INIT_CONNECTION,
STATE_INIT_CONNECTION_COMPLETE,
+ STATE_RESTART_TUNNEL_AUTH,
+ STATE_RESTART_TUNNEL_AUTH_COMPLETE,
STATE_GENERATE_PROXY_AUTH_TOKEN,
STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
STATE_GENERATE_SERVER_AUTH_TOKEN,
@@ -134,6 +136,8 @@ class HttpNetworkTransaction : public HttpTransaction {
int DoResolveProxyComplete(int result);
int DoInitConnection();
int DoInitConnectionComplete(int result);
+ int DoRestartTunnelAuth();
+ int DoRestartTunnelAuthComplete(int result);
int DoGenerateProxyAuthToken();
int DoGenerateProxyAuthTokenComplete(int result);
int DoGenerateServerAuthToken();
@@ -170,6 +174,9 @@ class HttpNetworkTransaction : public HttpTransaction {
static void LogIOErrorMetrics(const ClientSocketHandle& handle);
+ // Called to handle an HTTP proxy tunnel request for auth.
+ int HandleTunnelAuthFailure(int error);
+
// Called to handle a certificate error. Returns OK if the error should be
// ignored. Otherwise, stores the certificate in response_.ssl_info and
// returns the same error code.
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 72fa8aa..4e0d354 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -1343,6 +1343,111 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
EXPECT_EQ(100, response->headers->GetContentLength());
}
+// Test the request-challenge-retry sequence for basic auth, over a connection
+// that requires a restart when setting up an SSL tunnel.
+TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
+ // Configure against proxy server "myproxy:70".
+ SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
+ CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
+ session_deps.net_log = log.bound().net_log();
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+
+ scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.google.com/");
+ // when the no authentication data flag is set.
+ request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
+
+ // Since we have proxy, should try to establish tunnel.
+ MockWrite data_writes1[] = {
+ MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ // The proxy responds to the connect with a 407, using a persistent
+ // connection.
+ MockRead data_reads1[] = {
+ // No credentials.
+ MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+ MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
+ MockRead("Proxy-Connection: close\r\n\r\n"),
+
+ MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
+
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 100\r\n\r\n"),
+ MockRead(false, OK),
+ };
+
+ StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
+ data_writes1, arraysize(data_writes1));
+ session_deps.socket_factory.AddSocketDataProvider(&data1);
+ SSLSocketDataProvider ssl(true, OK);
+ session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
+
+ TestCompletionCallback callback1;
+
+ int rv = trans->Start(&request, &callback1, log.bound());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback1.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ size_t pos = ExpectLogContainsSomewhere(
+ log.entries(), 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
+ NetLog::PHASE_NONE);
+ ExpectLogContainsSomewhere(
+ log.entries(), pos,
+ NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
+ NetLog::PHASE_NONE);
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_FALSE(response == NULL);
+
+ EXPECT_EQ(407, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ // The password prompt info should have been set in response->auth_challenge.
+ ASSERT_FALSE(response->auth_challenge.get() == NULL);
+
+ EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
+ EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
+ EXPECT_EQ(L"basic", response->auth_challenge->scheme);
+
+ TestCompletionCallback callback2;
+
+ rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ rv = callback2.WaitForResult();
+ EXPECT_EQ(OK, rv);
+
+ response = trans->GetResponseInfo();
+ ASSERT_FALSE(response == NULL);
+
+ EXPECT_TRUE(response->headers->IsKeepAlive());
+ EXPECT_EQ(200, response->headers->response_code());
+ EXPECT_EQ(100, response->headers->GetContentLength());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ // The password prompt info should not be set.
+ EXPECT_TRUE(response->auth_challenge.get() == NULL);
+}
+
// Test the request-challenge-retry sequence for basic auth, over a keep-alive
// proxy connection, when setting up an SSL tunnel.
TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
@@ -6296,6 +6401,7 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
"\r\n"),
};
MockRead data_reads_1[] = {
+ MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
MockRead("HTTP/1.1 200 OK\r\n"
"Alternate-Protocol: 443:npn-spdy/2\r\n"
"Proxy-Connection: close\r\n"
@@ -6307,55 +6413,64 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
// Second round tries to tunnel to www.google.com due to the
// Alternate-Protocol announcement in the first round. It fails due
// to a proxy authentication challenge.
+ // After the failure, a tunnel is established to www.google.com using
+ // Proxy-Authorization headers. There is then a SPDY request round.
+ //
+ // NOTE: Despite the "Proxy-Connection: Close", these are done on the
+ // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
+ // does a Disconnect and Connect on the same socket, rather than trying
+ // to obtain a new one.
+ //
+ // NOTE: Originally, the proxy response to the second CONNECT request
+ // simply returned another 407 so the unit test could skip the SSL connection
+ // establishment and SPDY framing issues. Alas, the
+ // retry-http-when-alternate-protocol fails logic kicks in, which was more
+ // complicated to set up expectations for than the SPDY session.
+
+ scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+ scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
+
MockWrite data_writes_2[] = {
+ // First connection attempt without Proxy-Authorization.
MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
"Host: www.google.com\r\n"
"Proxy-Connection: keep-alive\r\n"
"\r\n"),
- };
- MockRead data_reads_2[] = {
- MockRead("HTTP/1.0 407 Unauthorized\r\n"
- "Proxy-Authenticate: Mock\r\n"
- "Proxy-Connection: close\r\n"
- "\r\n"),
- };
- StaticSocketDataProvider data_2(data_reads_2, arraysize(data_reads_2),
- data_writes_2, arraysize(data_writes_2));
- // Third round establishes a tunnel to www.google.com due to the
- // Alternate-Protocol announcement in the first round, and does a SPDY
- // request round.
- // TODO(cbentzel): Originally, this just returned another 407 so the unit test
- // could skip the SSL connection establishment and SPDY framing issues. Alas,
- // the retry-http-when-alternate-protocol fails logic kicks in, which was more
- // complicated to set up expectations for than the SPDY session.
- scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
- scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
-
- MockWrite data_writes_3[] = {
- // TUNNEL connection established
+ // Second connection attempt with Proxy-Authorization.
MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
"Host: www.google.com\r\n"
"Proxy-Connection: keep-alive\r\n"
"Proxy-Authorization: auth_token\r\n"
"\r\n"),
+
// SPDY request
- CreateMockWrite(*req), // 3
+ CreateMockWrite(*req),
};
+ const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
+ "Proxy-Authenticate: Mock\r\n"
+ "Proxy-Connection: close\r\n"
+ "\r\n");
+ const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
+ MockRead data_reads_2[] = {
+ // First connection attempt fails
+ MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
+ MockRead(true, kRejectConnectResponse,
+ arraysize(kRejectConnectResponse) - 1, 1),
- const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
- MockRead data_reads_3[] = {
- // Proxy response
- MockRead(true, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),
- // SPDY response.
- CreateMockRead(*resp.get(), 4),
- CreateMockRead(*data.get(), 4),
- MockRead(true, 0, 0, 4),
- };
- scoped_refptr<OrderedSocketData> data_3(
- new OrderedSocketData(data_reads_3, arraysize(data_reads_3),
- data_writes_3, arraysize(data_writes_3)));
+ // Second connection attempt passes
+ MockRead(true, kAcceptConnectResponse,
+ arraysize(kAcceptConnectResponse) -1, 4),
+
+ // SPDY response
+ CreateMockRead(*resp.get(), 6),
+ CreateMockRead(*data.get(), 6),
+ MockRead(true, 0, 0, 6),
+ };
+ scoped_refptr<OrderedSocketData> data_2(
+ new OrderedSocketData(data_reads_2, arraysize(data_reads_2),
+ data_writes_2, arraysize(data_writes_2)));
SSLSocketDataProvider ssl(true, OK);
ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
@@ -6363,8 +6478,7 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
ssl.was_npn_negotiated = true;
session_deps.socket_factory.AddSocketDataProvider(&data_1);
- session_deps.socket_factory.AddSocketDataProvider(&data_2);
- session_deps.socket_factory.AddSocketDataProvider(data_3.get());
+ session_deps.socket_factory.AddSocketDataProvider(data_2.get());
session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc
index 02c2666..1c76c36 100644
--- a/net/http/http_proxy_client_socket.cc
+++ b/net/http/http_proxy_client_socket.cc
@@ -50,18 +50,20 @@ void BuildTunnelRequest(const HttpRequestInfo* request_info,
HttpProxyClientSocket::HttpProxyClientSocket(
ClientSocketHandle* transport_socket, const GURL& request_url,
- const HostPortPair& endpoint, const scoped_refptr<HttpAuthController>& auth,
- bool tunnel)
+ const HostPortPair& endpoint, const HostPortPair& proxy_server,
+ const scoped_refptr<HttpNetworkSession>& session, bool tunnel)
: ALLOW_THIS_IN_INITIALIZER_LIST(
io_callback_(this, &HttpProxyClientSocket::OnIOComplete)),
next_state_(STATE_NONE),
user_callback_(NULL),
transport_(transport_socket),
endpoint_(endpoint),
- auth_(auth),
+ auth_(tunnel ?
+ new HttpAuthController(HttpAuth::AUTH_PROXY,
+ GURL("http://" + proxy_server.ToString()),
+ session) : NULL),
tunnel_(tunnel),
net_log_(transport_socket->socket()->NetLog()) {
- DCHECK_EQ(tunnel, auth != NULL);
// Synthesize the bits of a request that we actually use.
request_.url = request_url;
request_.method = "GET";
@@ -126,13 +128,14 @@ int HttpProxyClientSocket::PrepareForAuthRestart() {
}
int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) {
- int rc = OK;
if (keep_alive && transport_->socket()->IsConnectedAndIdle()) {
next_state_ = STATE_GENERATE_AUTH_TOKEN;
transport_->set_is_reused(true);
} else {
+ // This assumes that the underlying transport socket is a TCP socket,
+ // since only TCP sockets are restartable.
+ next_state_ = STATE_TCP_RESTART;
transport_->socket()->Disconnect();
- rc = ERR_RETRY_CONNECTION;
}
// Reset the other member variables.
@@ -140,7 +143,7 @@ int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) {
http_stream_.reset();
request_headers_.clear();
response_ = HttpResponseInfo();
- return rc;
+ return OK;
}
void HttpProxyClientSocket::LogBlockedTunnelResponse(int response_code) const {
@@ -159,19 +162,16 @@ void HttpProxyClientSocket::Disconnect() {
}
bool HttpProxyClientSocket::IsConnected() const {
- return transport_->socket()->IsConnected();
+ return next_state_ == STATE_DONE && transport_->socket()->IsConnected();
}
bool HttpProxyClientSocket::IsConnectedAndIdle() const {
- return transport_->socket()->IsConnectedAndIdle();
-}
-
-bool HttpProxyClientSocket::NeedsRestartWithAuth() const {
- return next_state_ != STATE_DONE;
+ return next_state_ == STATE_DONE &&
+ transport_->socket()->IsConnectedAndIdle();
}
int HttpProxyClientSocket::Read(IOBuffer* buf, int buf_len,
- CompletionCallback* callback) {
+ CompletionCallback* callback) {
DCHECK(!user_callback_);
if (next_state_ != STATE_DONE) {
// We're trying to read the body of the response but we're still trying
@@ -273,6 +273,13 @@ int HttpProxyClientSocket::DoLoop(int last_io_result) {
case STATE_DRAIN_BODY_COMPLETE:
rv = DoDrainBodyComplete(rv);
break;
+ case STATE_TCP_RESTART:
+ DCHECK_EQ(OK, rv);
+ rv = DoTCPRestart();
+ break;
+ case STATE_TCP_RESTART_COMPLETE:
+ rv = DoTCPRestartComplete(rv);
+ break;
case STATE_DONE:
break;
default:
@@ -280,8 +287,8 @@ int HttpProxyClientSocket::DoLoop(int last_io_result) {
rv = ERR_UNEXPECTED;
break;
}
- } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE
- && next_state_ != STATE_DONE);
+ } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE &&
+ next_state_ != STATE_DONE);
return rv;
}
@@ -406,6 +413,19 @@ int HttpProxyClientSocket::DoDrainBodyComplete(int result) {
return OK;
}
+int HttpProxyClientSocket::DoTCPRestart() {
+ next_state_ = STATE_TCP_RESTART_COMPLETE;
+ return transport_->socket()->Connect(&io_callback_);
+}
+
+int HttpProxyClientSocket::DoTCPRestartComplete(int result) {
+ if (result != OK)
+ return result;
+
+ next_state_ = STATE_GENERATE_AUTH_TOKEN;
+ return result;
+}
+
int HttpProxyClientSocket::HandleAuthChallenge() {
DCHECK(response_.headers);
diff --git a/net/http/http_proxy_client_socket.h b/net/http/http_proxy_client_socket.h
index 317b220..ef4f76c 100644
--- a/net/http/http_proxy_client_socket.h
+++ b/net/http/http_proxy_client_socket.h
@@ -35,7 +35,8 @@ class HttpProxyClientSocket : public ClientSocket {
// this socket will establish an Http tunnel.
HttpProxyClientSocket(ClientSocketHandle* transport_socket,
const GURL& request_url, const HostPortPair& endpoint,
- const scoped_refptr<HttpAuthController>& auth,
+ const HostPortPair& proxy_server,
+ const scoped_refptr<HttpNetworkSession>& session,
bool tunnel);
// On destruction Disconnect() is called.
@@ -46,12 +47,12 @@ class HttpProxyClientSocket : public ClientSocket {
// RestartWithAuth.
int RestartWithAuth(CompletionCallback* callback);
- // Indicates if RestartWithAuth needs to be called. i.e. if Connect
- // returned PROXY_AUTH_REQUESTED. Only valid after Connect has been called.
- bool NeedsRestartWithAuth() const;
-
const HttpResponseInfo* GetResponseInfo() const {
- return response_.headers ? &response_ : NULL;
+ return response_.headers ? &response_ : NULL;
+ }
+
+ const scoped_refptr<HttpAuthController>& auth_controller() {
+ return auth_;
}
// ClientSocket methods:
@@ -85,6 +86,8 @@ class HttpProxyClientSocket : public ClientSocket {
STATE_RESOLVE_CANONICAL_NAME_COMPLETE,
STATE_DRAIN_BODY,
STATE_DRAIN_BODY_COMPLETE,
+ STATE_TCP_RESTART,
+ STATE_TCP_RESTART_COMPLETE,
STATE_DONE,
};
@@ -112,6 +115,8 @@ class HttpProxyClientSocket : public ClientSocket {
int DoReadHeadersComplete(int result);
int DoDrainBody();
int DoDrainBodyComplete(int result);
+ int DoTCPRestart();
+ int DoTCPRestartComplete(int result);
CompletionCallbackImpl<HttpProxyClientSocket> io_callback_;
State next_state_;
diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc
index a142576..783c10f 100644
--- a/net/http/http_proxy_client_socket_pool.cc
+++ b/net/http/http_proxy_client_socket_pool.cc
@@ -7,6 +7,7 @@
#include "base/time.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
+#include "net/http/http_network_session.h"
#include "net/http/http_proxy_client_socket.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
@@ -18,12 +19,12 @@ HttpProxySocketParams::HttpProxySocketParams(
const scoped_refptr<TCPSocketParams>& proxy_server,
const GURL& request_url,
HostPortPair endpoint,
- scoped_refptr<HttpAuthController> auth_controller,
+ scoped_refptr<HttpNetworkSession> session,
bool tunnel)
: tcp_params_(proxy_server),
request_url_(request_url),
endpoint_(endpoint),
- auth_controller_(auth_controller),
+ session_(session),
tunnel_(tunnel) {
}
@@ -133,19 +134,22 @@ int HttpProxyConnectJob::DoTCPConnectComplete(int result) {
int HttpProxyConnectJob::DoHttpProxyConnect() {
next_state_ = kStateHttpProxyConnectComplete;
+ const HostResolver::RequestInfo& tcp_destination =
+ params_->tcp_params()->destination();
+ HostPortPair proxy_server(tcp_destination.hostname(),
+ tcp_destination.port());
// Add a HttpProxy connection on top of the tcp socket.
socket_.reset(new HttpProxyClientSocket(tcp_socket_handle_.release(),
params_->request_url(),
params_->endpoint(),
- params_->auth_controller(),
+ proxy_server,
+ params_->session(),
params_->tunnel()));
return socket_->Connect(&callback_);
}
int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) {
- DCHECK_NE(result, ERR_RETRY_CONNECTION);
-
if (result == OK || result == ERR_PROXY_AUTH_REQUESTED)
set_socket(socket_.release());
diff --git a/net/http/http_proxy_client_socket_pool.h b/net/http/http_proxy_client_socket_pool.h
index 63d5c02..347a2427 100644
--- a/net/http/http_proxy_client_socket_pool.h
+++ b/net/http/http_proxy_client_socket_pool.h
@@ -26,12 +26,13 @@ namespace net {
class ClientSocketFactory;
class ConnectJobFactory;
class HttpAuthController;
+class HttpNetworkSession;
class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> {
public:
HttpProxySocketParams(const scoped_refptr<TCPSocketParams>& proxy_server,
const GURL& request_url, HostPortPair endpoint,
- scoped_refptr<HttpAuthController> auth_controller,
+ scoped_refptr<HttpNetworkSession> session,
bool tunnel);
const scoped_refptr<TCPSocketParams>& tcp_params() const {
@@ -39,8 +40,8 @@ class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> {
}
const GURL& request_url() const { return request_url_; }
const HostPortPair& endpoint() const { return endpoint_; }
- const scoped_refptr<HttpAuthController>& auth_controller() {
- return auth_controller_;
+ const scoped_refptr<HttpNetworkSession>& session() {
+ return session_;
}
bool tunnel() const { return tunnel_; }
@@ -51,7 +52,7 @@ class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> {
const scoped_refptr<TCPSocketParams> tcp_params_;
const GURL request_url_;
const HostPortPair endpoint_;
- const scoped_refptr<HttpAuthController> auth_controller_;
+ const scoped_refptr<HttpNetworkSession> session_;
const bool tunnel_;
DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams);
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc
index 9400dd8..3e06c3b 100644
--- a/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -6,12 +6,19 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/string_util.h"
+#include "net/base/mock_host_resolver.h"
#include "net/base/net_errors.h"
+#include "net/base/ssl_config_service_defaults.h"
#include "net/base/test_completion_callback.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_network_session.h"
#include "net/http/http_proxy_client_socket.h"
+#include "net/proxy/proxy_service.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 {
@@ -29,19 +36,34 @@ class HttpProxyClientSocketPoolTest : public ClientSocketPoolTest {
tcp_histograms_(new ClientSocketPoolHistograms("MockTCP")),
tcp_socket_pool_(new MockTCPClientSocketPool(kMaxSockets,
kMaxSocketsPerGroup, tcp_histograms_, &tcp_client_socket_factory_)),
+ http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
+ session_(new HttpNetworkSession(new MockHostResolver,
+ ProxyService::CreateNull(),
+ &socket_factory_,
+ new SSLConfigServiceDefaults,
+ new SpdySessionPool(),
+ http_auth_handler_factory_.get(),
+ NULL,
+ NULL)),
notunnel_socket_params_(new HttpProxySocketParams(
ignored_tcp_socket_params_, GURL("http://host"),
HostPortPair("host", 80), NULL, false)),
- auth_controller_(new MockHttpAuthController),
tunnel_socket_params_(new HttpProxySocketParams(
ignored_tcp_socket_params_, GURL("http://host"),
- HostPortPair("host", 80), auth_controller_, true)),
+ HostPortPair("host", 80), session_, true)),
http_proxy_histograms_(
new ClientSocketPoolHistograms("HttpProxyUnitTest")),
pool_(new HttpProxyClientSocketPool(kMaxSockets, kMaxSocketsPerGroup,
http_proxy_histograms_, NULL, tcp_socket_pool_, NULL)) {
}
+ void AddAuthToCache() {
+ const string16 kFoo(ASCIIToUTF16("foo"));
+ const string16 kBar(ASCIIToUTF16("bar"));
+ session_->auth_cache()->Add(GURL("http://proxy/"), "MyRealm1", "Basic",
+ "Basic realm=MyRealm1", kFoo, kBar, "/");
+ }
+
int StartRequest(const std::string& group_name, RequestPriority priority) {
return StartRequestUsingPool(
pool_, group_name, priority, tunnel_socket_params_);
@@ -52,8 +74,10 @@ class HttpProxyClientSocketPoolTest : public ClientSocketPoolTest {
MockClientSocketFactory tcp_client_socket_factory_;
scoped_refptr<MockTCPClientSocketPool> tcp_socket_pool_;
+ MockClientSocketFactory socket_factory_;
+ scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
+ scoped_refptr<HttpNetworkSession> session_;
scoped_refptr<HttpProxySocketParams> notunnel_socket_params_;
- scoped_refptr<MockHttpAuthController> auth_controller_;
scoped_refptr<HttpProxySocketParams> tunnel_socket_params_;
scoped_refptr<ClientSocketPoolHistograms> http_proxy_histograms_;
scoped_refptr<HttpProxyClientSocketPool> pool_;
@@ -72,7 +96,7 @@ TEST_F(HttpProxyClientSocketPoolTest, NoTunnel) {
EXPECT_TRUE(handle.socket());
HttpProxyClientSocket* tunnel_socket =
static_cast<HttpProxyClientSocket*>(handle.socket());
- EXPECT_FALSE(tunnel_socket->NeedsRestartWithAuth());
+ EXPECT_TRUE(tunnel_socket->IsConnected());
}
TEST_F(HttpProxyClientSocketPoolTest, NeedAuth) {
@@ -92,10 +116,6 @@ TEST_F(HttpProxyClientSocketPoolTest, NeedAuth) {
arraysize(writes));
tcp_client_socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData(""),
- };
- auth_controller_->SetMockAuthControllerData(auth_data, arraysize(auth_data));
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -110,7 +130,7 @@ TEST_F(HttpProxyClientSocketPoolTest, NeedAuth) {
EXPECT_TRUE(handle.socket());
HttpProxyClientSocket* tunnel_socket =
static_cast<HttpProxyClientSocket*>(handle.socket());
- EXPECT_TRUE(tunnel_socket->NeedsRestartWithAuth());
+ EXPECT_FALSE(tunnel_socket->IsConnected());
}
TEST_F(HttpProxyClientSocketPoolTest, HaveAuth) {
@@ -119,7 +139,7 @@ TEST_F(HttpProxyClientSocketPoolTest, HaveAuth) {
"CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead(false, "HTTP/1.1 200 Connection Established\r\n\r\n"),
@@ -129,10 +149,7 @@ TEST_F(HttpProxyClientSocketPoolTest, HaveAuth) {
data.set_connect_data(MockConnect(false, 0));
tcp_client_socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData("Proxy-Authorization: Basic Zm9vOmJheg=="),
- };
- auth_controller_->SetMockAuthControllerData(auth_data, arraysize(auth_data));
+ AddAuthToCache();
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -143,7 +160,7 @@ TEST_F(HttpProxyClientSocketPoolTest, HaveAuth) {
EXPECT_TRUE(handle.socket());
HttpProxyClientSocket* tunnel_socket =
static_cast<HttpProxyClientSocket*>(handle.socket());
- EXPECT_FALSE(tunnel_socket->NeedsRestartWithAuth());
+ EXPECT_TRUE(tunnel_socket->IsConnected());
}
TEST_F(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
@@ -151,7 +168,7 @@ TEST_F(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
MockWrite("CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
@@ -160,10 +177,7 @@ TEST_F(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
arraysize(writes));
tcp_client_socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData("Proxy-Authorization: Basic Zm9vOmJheg=="),
- };
- auth_controller_->SetMockAuthControllerData(auth_data, arraysize(auth_data));
+ AddAuthToCache();
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -178,7 +192,7 @@ TEST_F(HttpProxyClientSocketPoolTest, AsyncHaveAuth) {
EXPECT_TRUE(handle.socket());
HttpProxyClientSocket* tunnel_socket =
static_cast<HttpProxyClientSocket*>(handle.socket());
- EXPECT_FALSE(tunnel_socket->NeedsRestartWithAuth());
+ EXPECT_TRUE(tunnel_socket->IsConnected());
}
TEST_F(HttpProxyClientSocketPoolTest, TCPError) {
@@ -205,7 +219,7 @@ TEST_F(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) {
MockWrite("CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead("HTTP/1.1 200 Conn"),
@@ -215,10 +229,7 @@ TEST_F(HttpProxyClientSocketPoolTest, TunnelUnexpectedClose) {
arraysize(writes));
tcp_client_socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData("Proxy-Authorization: Basic Zm9vOmJheg=="),
- };
- auth_controller_->SetMockAuthControllerData(auth_data, arraysize(auth_data));
+ AddAuthToCache();
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -238,7 +249,7 @@ TEST_F(HttpProxyClientSocketPoolTest, TunnelSetupError) {
MockWrite("CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
@@ -247,10 +258,7 @@ TEST_F(HttpProxyClientSocketPoolTest, TunnelSetupError) {
arraysize(writes));
tcp_client_socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData("Proxy-Authorization: Basic Zm9vOmJheg=="),
- };
- auth_controller_->SetMockAuthControllerData(auth_data, arraysize(auth_data));
+ AddAuthToCache();
ClientSocketHandle handle;
TestCompletionCallback callback;
diff --git a/net/socket/client_socket_handle.cc b/net/socket/client_socket_handle.cc
index de2fd94..d9ccbd5 100644
--- a/net/socket/client_socket_handle.cc
+++ b/net/socket/client_socket_handle.cc
@@ -59,6 +59,7 @@ void ClientSocketHandle::ResetInternal(bool cancel) {
void ClientSocketHandle::ResetErrorState() {
is_ssl_error_ = false;
ssl_error_response_info_ = HttpResponseInfo();
+ pending_http_proxy_connection_.reset();
}
LoadState ClientSocketHandle::GetLoadState() const {
diff --git a/net/socket/client_socket_handle.h b/net/socket/client_socket_handle.h
index a25bfdb..adccc89 100644
--- a/net/socket/client_socket_handle.h
+++ b/net/socket/client_socket_handle.h
@@ -109,6 +109,9 @@ class ClientSocketHandle {
void set_ssl_error_response_info(const HttpResponseInfo& ssl_error_state) {
ssl_error_response_info_ = ssl_error_state;
}
+ void set_pending_http_proxy_connection(ClientSocketHandle* connection) {
+ pending_http_proxy_connection_.reset(connection);
+ }
// Only valid if there is no |socket_|.
bool is_ssl_error() const {
@@ -121,6 +124,9 @@ class ClientSocketHandle {
const HttpResponseInfo& ssl_error_response_info() const {
return ssl_error_response_info_;
}
+ ClientSocketHandle* release_pending_http_proxy_connection() {
+ return pending_http_proxy_connection_.release();
+ }
// These may only be used if is_initialized() is true.
const std::string& group_name() const { return group_name_; }
@@ -179,6 +185,7 @@ class ClientSocketHandle {
int pool_id_; // See ClientSocketPool::ReleaseSocket() for an explanation.
bool is_ssl_error_;
HttpResponseInfo ssl_error_response_info_;
+ scoped_ptr<ClientSocketHandle> pending_http_proxy_connection_;
base::TimeTicks init_time_;
base::TimeDelta setup_time_;
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index d4d74a7..142a39e 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -187,6 +187,7 @@ int MockTCPClientSocket::Connect(net::CompletionCallback* callback) {
if (connected_)
return net::OK;
connected_ = true;
+ peer_closed_connection_ = false;
if (data_->connect_data().async) {
RunCallbackAsync(callback, data_->connect_data().result);
return net::ERR_IO_PENDING;
@@ -886,53 +887,6 @@ void MockSOCKSClientSocketPool::ReleaseSocket(const std::string& group_name,
MockSOCKSClientSocketPool::~MockSOCKSClientSocketPool() {}
-MockHttpAuthController::MockHttpAuthController()
- : HttpAuthController(HttpAuth::AUTH_PROXY, GURL(),
- scoped_refptr<HttpNetworkSession>(NULL)),
- data_(NULL),
- data_index_(0),
- data_count_(0) {
-}
-
-void MockHttpAuthController::SetMockAuthControllerData(
- struct MockHttpAuthControllerData* data, size_t count) {
- data_ = data;
- data_count_ = count;
-}
-
-int MockHttpAuthController::MaybeGenerateAuthToken(
- const HttpRequestInfo* request,
- CompletionCallback* callback,
- const BoundNetLog& net_log) {
- return OK;
-}
-
-void MockHttpAuthController::AddAuthorizationHeader(
- HttpRequestHeaders* authorization_headers) {
- authorization_headers->AddHeadersFromString(CurrentData().auth_header);
-}
-
-int MockHttpAuthController::HandleAuthChallenge(
- scoped_refptr<HttpResponseHeaders> headers,
- bool do_not_send_server_auth,
- bool establishing_tunnel,
- const BoundNetLog& net_log) {
- return OK;
-}
-
-void MockHttpAuthController::ResetAuth(const string16& username,
- const string16& password) {
- data_index_++;
-}
-
-bool MockHttpAuthController::HaveAuth() const {
- return CurrentData().auth_header.size() != 0;
-}
-
-bool MockHttpAuthController::HaveAuthHandler() const {
- return HaveAuth();
-}
-
const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
const int kSOCKS5GreetRequestLength = arraysize(kSOCKS5GreetRequest);
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 1a0ab11..0ccf878 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -695,46 +695,6 @@ class MockSOCKSClientSocketPool : public SOCKSClientSocketPool {
DISALLOW_COPY_AND_ASSIGN(MockSOCKSClientSocketPool);
};
-struct MockHttpAuthControllerData {
- explicit MockHttpAuthControllerData(std::string header)
- : auth_header(header) {}
-
- std::string auth_header;
-};
-
-class MockHttpAuthController : public HttpAuthController {
- public:
- MockHttpAuthController();
- void SetMockAuthControllerData(struct MockHttpAuthControllerData* data,
- size_t data_length);
-
- // HttpAuthController methods.
- virtual int MaybeGenerateAuthToken(const HttpRequestInfo* request,
- CompletionCallback* callback,
- const BoundNetLog& net_log);
- virtual void AddAuthorizationHeader(
- HttpRequestHeaders* authorization_headers);
- virtual int HandleAuthChallenge(scoped_refptr<HttpResponseHeaders> headers,
- bool do_not_send_server_auth,
- bool establishing_tunnel,
- const BoundNetLog& net_log);
- virtual void ResetAuth(const string16& username,
- const string16& password);
- virtual bool HaveAuthHandler() const;
- virtual bool HaveAuth() const;
-
- private:
- virtual ~MockHttpAuthController() {}
- const struct MockHttpAuthControllerData& CurrentData() const {
- DCHECK(data_index_ < data_count_);
- return data_[data_index_];
- }
-
- MockHttpAuthControllerData* data_;
- size_t data_index_;
- size_t data_count_;
-};
-
// Constants for a successful SOCKS v5 handshake.
extern const char kSOCKS5GreetRequest[];
extern const int kSOCKS5GreetRequestLength;
diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc
index 03e2e80..5ed450e 100644
--- a/net/socket/ssl_client_socket_pool.cc
+++ b/net/socket/ssl_client_socket_pool.cc
@@ -103,11 +103,6 @@ LoadState SSLConnectJob::GetLoadState() const {
}
int SSLConnectJob::ConnectInternal() {
- DetermineFirstState();
- return DoLoop(OK);
-}
-
-void SSLConnectJob::DetermineFirstState() {
switch (params_->proxy()) {
case ProxyServer::SCHEME_DIRECT:
next_state_ = STATE_TCP_CONNECT;
@@ -123,6 +118,7 @@ void SSLConnectJob::DetermineFirstState() {
NOTREACHED() << "unknown proxy type";
break;
}
+ return DoLoop(OK);
}
void SSLConnectJob::OnIOComplete(int result) {
@@ -214,6 +210,7 @@ int SSLConnectJob::DoSOCKSConnectComplete(int result) {
int SSLConnectJob::DoTunnelConnect() {
DCHECK(http_proxy_pool_.get());
next_state_ = STATE_TUNNEL_CONNECT_COMPLETE;
+
transport_socket_handle_.reset(new ClientSocketHandle());
scoped_refptr<HttpProxySocketParams> http_proxy_params =
params_->http_proxy_params();
@@ -228,12 +225,6 @@ int SSLConnectJob::DoTunnelConnectComplete(int result) {
HttpProxyClientSocket* tunnel_socket =
static_cast<HttpProxyClientSocket*>(socket);
- if (result == ERR_RETRY_CONNECTION) {
- DetermineFirstState();
- transport_socket_handle_->socket()->Disconnect();
- return OK;
- }
-
// Extract the information needed to prompt for the proxy authentication.
// so that when ClientSocketPoolBaseHelper calls |GetAdditionalErrorState|,
// we can easily set the state.
@@ -243,20 +234,17 @@ int SSLConnectJob::DoTunnelConnectComplete(int result) {
if (result < 0)
return result;
- if (tunnel_socket->NeedsRestartWithAuth()) {
- // We must have gotten an 'idle' tunnel socket that is waiting for auth.
- // The HttpAuthController should have new credentials, we just need
- // to retry.
- next_state_ = STATE_TUNNEL_CONNECT_COMPLETE;
- return tunnel_socket->RestartWithAuth(&callback_);
- }
-
+ DCHECK(tunnel_socket->IsConnected());
next_state_ = STATE_SSL_CONNECT;
return result;
}
void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
- handle->set_ssl_error_response_info(error_response_info_);
+ if (error_response_info_.headers) {
+ handle->set_ssl_error_response_info(error_response_info_);
+ handle->set_pending_http_proxy_connection(
+ transport_socket_handle_.release());
+ }
if (!ssl_connect_start_time_.is_null())
handle->set_is_ssl_error(true);
}
diff --git a/net/socket/ssl_client_socket_pool.h b/net/socket/ssl_client_socket_pool.h
index b44985f..9857c61 100644
--- a/net/socket/ssl_client_socket_pool.h
+++ b/net/socket/ssl_client_socket_pool.h
@@ -44,7 +44,7 @@ class SSLSocketParams : public base::RefCounted<SSLSocketParams> {
bool want_spdy_over_npn);
const scoped_refptr<TCPSocketParams>& tcp_params() { return tcp_params_; }
- const scoped_refptr<HttpProxySocketParams>& http_proxy_params () {
+ const scoped_refptr<HttpProxySocketParams>& http_proxy_params() {
return http_proxy_params_;
}
const scoped_refptr<SOCKSSocketParams>& socks_params() {
@@ -114,8 +114,6 @@ class SSLConnectJob : public ConnectJob {
// Otherwise, it returns a net error code.
virtual int ConnectInternal();
- void DetermineFirstState();
-
void OnIOComplete(int result);
// Runs the state transition loop.
diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc
index efc4795..047a647 100644
--- a/net/socket/ssl_client_socket_pool_unittest.cc
+++ b/net/socket/ssl_client_socket_pool_unittest.cc
@@ -6,13 +6,14 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/string_util.h"
#include "base/time.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_controller.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"
@@ -20,6 +21,7 @@
#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 {
@@ -32,7 +34,16 @@ const int kMaxSocketsPerGroup = 6;
class SSLClientSocketPoolTest : public ClientSocketPoolTest {
protected:
SSLClientSocketPoolTest()
- : direct_tcp_socket_params_(new TCPSocketParams(
+ : http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
+ session_(new HttpNetworkSession(new MockHostResolver,
+ ProxyService::CreateNull(),
+ &socket_factory_,
+ new SSLConfigServiceDefaults,
+ new SpdySessionPool(),
+ http_auth_handler_factory_.get(),
+ NULL,
+ NULL)),
+ direct_tcp_socket_params_(new TCPSocketParams(
HostPortPair("host", 443), MEDIUM, GURL(), false)),
tcp_socket_pool_(new MockTCPClientSocketPool(
kMaxSockets,
@@ -41,6 +52,9 @@ class SSLClientSocketPoolTest : public ClientSocketPoolTest {
&socket_factory_)),
proxy_tcp_socket_params_(new TCPSocketParams(
HostPortPair("proxy", 443), MEDIUM, GURL(), false)),
+ http_proxy_socket_params_(new HttpProxySocketParams(
+ proxy_tcp_socket_params_, GURL("http://host"),
+ HostPortPair("host", 80), session_, true)),
http_proxy_socket_pool_(new HttpProxyClientSocketPool(
kMaxSockets,
kMaxSocketsPerGroup,
@@ -74,33 +88,30 @@ class SSLClientSocketPoolTest : public ClientSocketPoolTest {
NULL);
}
- scoped_refptr<SSLSocketParams> SSLParams(
- ProxyServer::Scheme proxy, struct MockHttpAuthControllerData* auth_data,
- size_t auth_data_len, bool want_spdy_over_ssl, bool want_spdy_over_npn) {
- scoped_refptr<HttpProxySocketParams> http_proxy_params;
- if (proxy == ProxyServer::SCHEME_HTTP) {
- scoped_refptr<MockHttpAuthController> auth_controller =
- new MockHttpAuthController();
- auth_controller->SetMockAuthControllerData(auth_data, auth_data_len);
- http_proxy_params = new HttpProxySocketParams(proxy_tcp_socket_params_,
- GURL("http://host"),
- HostPortPair("host", 80),
- auth_controller, true);
- }
-
+ 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,
- http_proxy_params,
+ proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : NULL,
proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : NULL,
proxy,
"host",
ssl_config_,
0,
- want_spdy_over_ssl,
+ 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<HttpAuthHandlerFactory> http_auth_handler_factory_;
+ scoped_refptr<HttpNetworkSession> session_;
scoped_refptr<TCPSocketParams> direct_tcp_socket_params_;
scoped_refptr<MockTCPClientSocketPool> tcp_socket_pool_;
@@ -123,7 +134,7 @@ TEST_F(SSLClientSocketPoolTest, TCPFail) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
int rv = handle.Init("a", params, MEDIUM, NULL, pool_, BoundNetLog());
@@ -140,7 +151,7 @@ TEST_F(SSLClientSocketPoolTest, TCPFailAsync) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -164,7 +175,7 @@ TEST_F(SSLClientSocketPoolTest, BasicDirect) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -182,7 +193,7 @@ TEST_F(SSLClientSocketPoolTest, BasicDirectAsync) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -204,7 +215,7 @@ TEST_F(SSLClientSocketPoolTest, DirectCertError) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -226,7 +237,7 @@ TEST_F(SSLClientSocketPoolTest, DirectSSLError) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -251,7 +262,7 @@ TEST_F(SSLClientSocketPoolTest, DirectWithNPN) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -277,7 +288,7 @@ TEST_F(SSLClientSocketPoolTest, DirectNoSPDY) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, true);
+ true);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -302,7 +313,7 @@ TEST_F(SSLClientSocketPoolTest, DirectGotSPDY) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, true);
+ true);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -333,7 +344,7 @@ TEST_F(SSLClientSocketPoolTest, DirectGotBonusSPDY) {
CreatePool(true /* tcp pool */, false, false);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
- NULL, 0, false, true);
+ true);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -361,7 +372,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSFail) {
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -379,7 +390,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSFailAsync) {
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -403,7 +414,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSBasic) {
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -421,7 +432,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSBasicAsync) {
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -442,7 +453,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyFail) {
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -460,7 +471,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyFailAsync) {
CreatePool(false, true /* http proxy pool */, true /* socks pool */);
scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
- NULL, 0, false, false);
+ false);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -481,7 +492,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) {
"CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead(false, "HTTP/1.1 200 Connection Established\r\n\r\n"),
@@ -490,17 +501,12 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) {
arraysize(writes));
data.set_connect_data(MockConnect(false, OK));
socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData("Proxy-Authorization: Basic Zm9vOmJheg=="),
- };
+ 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,
- auth_data,
- arraysize(auth_data),
- false,
false);
ClientSocketHandle handle;
@@ -516,7 +522,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) {
MockWrite("CONNECT host:80 HTTP/1.1\r\n"
"Host: host\r\n"
"Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
+ "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
};
MockRead reads[] = {
MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
@@ -524,17 +530,12 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) {
StaticSocketDataProvider data(reads, arraysize(reads), writes,
arraysize(writes));
socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData("Proxy-Authorization: Basic Zm9vOmJheg=="),
- };
+ 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,
- auth_data,
- arraysize(auth_data),
- false,
false);
ClientSocketHandle handle;
@@ -564,135 +565,11 @@ TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) {
StaticSocketDataProvider data(reads, arraysize(reads), writes,
arraysize(writes));
socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData(""),
- };
- 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,
- auth_data,
- arraysize(auth_data),
- false,
- false);
-
- ClientSocketHandle handle;
- TestCompletionCallback callback;
- int rv = handle.Init("a", params, MEDIUM, &callback, pool_, 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);
-}
-
-TEST_F(SSLClientSocketPoolTest, DoProxyAuth) {
- MockWrite writes[] = {
- MockWrite("CONNECT host:80 HTTP/1.1\r\n"
- "Host: host\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
- MockWrite("CONNECT host:80 HTTP/1.1\r\n"
- "Host: host\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\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"),
- MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
- };
- StaticSocketDataProvider data(reads, arraysize(reads), writes,
- arraysize(writes));
- socket_factory_.AddSocketDataProvider(&data);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData(""),
- MockHttpAuthControllerData("Proxy-Authorization: Basic Zm9vOmJheg=="),
- };
- 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,
- auth_data,
- arraysize(auth_data),
- false,
- false);
-
- ClientSocketHandle handle;
- TestCompletionCallback callback;
- int rv = handle.Init("a", params, MEDIUM, &callback, pool_, 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);
-
- params->http_proxy_params()->auth_controller()->ResetAuth(string16(),
- string16());
- rv = handle.Init("a", params, MEDIUM, &callback, pool_, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_FALSE(handle.is_initialized());
- EXPECT_FALSE(handle.socket());
-
- // Test that http://crbug.com/49325 doesn't regress.
- EXPECT_EQ(handle.GetLoadState(), LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
-
- EXPECT_EQ(OK, callback.WaitForResult());
- EXPECT_TRUE(handle.is_initialized());
- EXPECT_TRUE(handle.socket());
-}
-
-TEST_F(SSLClientSocketPoolTest, DoProxyAuthNoKeepAlive) {
- MockWrite writes1[] = {
- MockWrite("CONNECT host:80 HTTP/1.1\r\n"
- "Host: host\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
- };
- MockWrite writes2[] = {
- MockWrite("CONNECT host:80 HTTP/1.1\r\n"
- "Host: host\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
- };
- MockRead reads1[] = {
- MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
- MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
- MockRead("Content0123456789"),
- };
- MockRead reads2[] = {
- MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
- };
- StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
- arraysize(writes1));
- socket_factory_.AddSocketDataProvider(&data1);
- StaticSocketDataProvider data2(reads2, arraysize(reads2), writes2,
- arraysize(writes2));
- socket_factory_.AddSocketDataProvider(&data2);
- MockHttpAuthControllerData auth_data[] = {
- MockHttpAuthControllerData(""),
- MockHttpAuthControllerData("Proxy-Authorization: Basic Zm9vOmJheg=="),
- };
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,
- auth_data,
- arraysize(auth_data),
- false,
false);
ClientSocketHandle handle;
@@ -708,17 +585,10 @@ TEST_F(SSLClientSocketPoolTest, DoProxyAuthNoKeepAlive) {
EXPECT_FALSE(handle.is_ssl_error());
const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
EXPECT_EQ(tunnel_info.headers->response_code(), 407);
-
- params->http_proxy_params()->auth_controller()->ResetAuth(string16(),
- string16());
- rv = handle.Init("a", params, MEDIUM, &callback, pool_, 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());
+ 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.