diff options
author | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-04 00:29:48 +0000 |
---|---|---|
committer | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-04 00:29:48 +0000 |
commit | 0991485ae6cfb83c4a2ea82e4fce652e772d31a0 (patch) | |
tree | bcdfac413c63564d86fa5e2516f5b026f8371237 | |
parent | fcaad36622623077c948ec4557a8a028f16b21a2 (diff) | |
download | chromium_src-0991485ae6cfb83c4a2ea82e4fce652e772d31a0.zip chromium_src-0991485ae6cfb83c4a2ea82e4fce652e772d31a0.tar.gz chromium_src-0991485ae6cfb83c4a2ea82e4fce652e772d31a0.tar.bz2 |
Revert 118950 - Allow chrome to handle 407 auth challenges to CONNECT requests
through HTTPS Proxies. This also changes the mechanism used
to restart HttpProxyClientSocket requests with auth. Previously
the transport socket would be Disconnected, and then re-Connected
(which was not implemented for SSLClientSockets). However, the
approach was problematic in the face of, for example, ipv6. The
new approach is to close the HttpProxyClientSocket, and request
a new socket from the pool.
Initially was http://codereview.chromium.org/8502024
which turned out to have problems with NTLM auth.
Review URL: http://codereview.chromium.org/9148011
TBR=rch@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9310101
git-svn-id: svn://svn.chromium.org/chrome/branches/1025/src@120443 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 165 insertions, 956 deletions
diff --git a/jingle/notifier/base/proxy_resolving_client_socket.cc b/jingle/notifier/base/proxy_resolving_client_socket.cc index 83b0281..ab0b679 100644 --- a/jingle/notifier/base/proxy_resolving_client_socket.cc +++ b/jingle/notifier/base/proxy_resolving_client_socket.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -20,18 +20,6 @@ namespace notifier { -namespace { - -void HandleProxyTunnelAuth(const net::HttpResponseInfo& response_info, - net::HttpAuthController* auth_controller, - net::CompletionCallback callback) { - // Since we have no way to respond, simply invoke the callback and the - // request will fail. - callback.Run(net::OK); -} - -} // namespace - ProxyResolvingClientSocket::ProxyResolvingClientSocket( net::ClientSocketFactory* socket_factory, const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, @@ -184,9 +172,7 @@ void ProxyResolvingClientSocket::ProcessProxyResolveDone(int status) { // Now that we have resolved the proxy, we need to connect. status = net::InitSocketHandleForRawConnect( dest_host_port_pair_, network_session_.get(), proxy_info_, ssl_config_, - ssl_config_, bound_net_log_, transport_.get(), - base::Bind(&HandleProxyTunnelAuth), connect_callback_); - + ssl_config_, bound_net_log_, transport_.get(), connect_callback_); if (status != net::ERR_IO_PENDING) { // Since this method is always called asynchronously. it is OK to call // ProcessConnectDone synchronously. diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index bba09ea..37f5f31 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -285,9 +285,6 @@ NET_ERROR(CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, -151) // first was still being generated. NET_ERROR(ORIGIN_BOUND_CERT_GENERATION_TYPE_MISMATCH, -152) -// The proxy does not support restarting a request on the existing connection. -NET_ERROR(NO_KEEP_ALIVE_ON_AUTH_RESTART, -153) - // Certificate error codes // // The values of certificate error codes must be consecutive. diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index c522e8b..5a75e8d 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -421,16 +421,6 @@ bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) { return true; } -bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) { - if (!auth_challenge) - return false; - EXPECT_TRUE(auth_challenge->is_proxy); - EXPECT_EQ("proxy:70", auth_challenge->challenger.ToString()); - EXPECT_EQ(std::string(), auth_challenge->realm); - EXPECT_EQ("ntlm", auth_challenge->scheme); - return true; -} - TEST_F(HttpNetworkTransactionTest, Basic) { SessionDependencies session_deps; scoped_ptr<HttpTransaction> trans( @@ -1728,9 +1718,6 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { "Host: www.google.com\r\n" "Proxy-Connection: keep-alive\r\n\r\n"), - }; - - MockWrite data_writes2[] = { // 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" @@ -1750,9 +1737,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { 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 data_reads2[] = { MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), MockRead("HTTP/1.1 200 OK\r\n"), @@ -1763,10 +1748,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), data_writes1, arraysize(data_writes1)); - StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), - data_writes2, arraysize(data_writes2)); session_deps.socket_factory.AddSocketDataProvider(&data1); - session_deps.socket_factory.AddSocketDataProvider(&data2); SSLSocketDataProvider ssl(true, OK); session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); @@ -1981,372 +1963,6 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { session->CloseAllConnections(); } -// 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, BasicAuthHttpsProxyNoKeepAlive) { - 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; - - // Configure against https proxy server "myproxy:70". - SessionDependencies session_deps( - ProxyService::CreateFixed("https://myproxy:70")); - CapturingBoundNetLog log(CapturingNetLog::kUnbounded); - session_deps.net_log = log.bound().net_log(); - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - - // 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"), - }; - - MockWrite data_writes2[] = { - // 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 data_reads2[] = { - 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: 5\r\n\r\n"), - MockRead(false, "hello"), - }; - - StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), - data_writes1, arraysize(data_writes1)); - StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), - data_writes2, arraysize(data_writes2)); - session_deps.socket_factory.AddSocketDataProvider(&data1); - session_deps.socket_factory.AddSocketDataProvider(&data2); - SSLSocketDataProvider proxy(true, OK); - session_deps.socket_factory.AddSSLSocketDataProvider(&proxy); - SSLSocketDataProvider proxy2(true, OK); - session_deps.socket_factory.AddSSLSocketDataProvider(&proxy2); - SSLSocketDataProvider server(true, OK); - session_deps.socket_factory.AddSSLSocketDataProvider(&server); - - TestCompletionCallback callback1; - - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - - int rv = trans->Start(&request, callback1.callback(), log.bound()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback1.WaitForResult(); - EXPECT_EQ(OK, rv); - net::CapturingNetLog::EntryList entries; - log.GetEntries(&entries); - size_t pos = ExpectLogContainsSomewhere( - entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, - NetLog::PHASE_NONE); - ExpectLogContainsSomewhere( - entries, pos, - NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, - NetLog::PHASE_NONE); - - const HttpResponseInfo* response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - ASSERT_FALSE(response->headers == NULL); - EXPECT_EQ(407, response->headers->response_code()); - EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); - - TestCompletionCallback callback2; - - rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), - callback2.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback2.WaitForResult(); - EXPECT_EQ(OK, rv); - - response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - - EXPECT_TRUE(response->headers->IsKeepAlive()); - EXPECT_EQ(200, response->headers->response_code()); - EXPECT_EQ(5, 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); - - trans.reset(); - session->CloseAllConnections(); -} - -// Test the request-challenge-retry sequence for basic auth, over a keep-alive -// proxy connection, when setting up an SSL tunnel. -TEST_F(HttpNetworkTransactionTest, BasicAuthHttpsProxyKeepAlive) { - HttpRequestInfo request; - request.method = "GET"; - request.url = GURL("https://www.google.com/"); - // Ensure that proxy authentication is attempted even - // when the no authentication data flag is set. - request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA; - - // Configure against https proxy server "myproxy:70". - SessionDependencies session_deps( - ProxyService::CreateFixed("https://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)); - - // 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 Zm9vOmJheg==\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("Content-Length: 10\r\n\r\n"), - MockRead("0123456789"), - - // Wrong credentials (wrong password). - 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"), - // No response body because the test stops reading here. - MockRead(false, ERR_UNEXPECTED), // Should not be reached. - }; - - 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.callback(), log.bound()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback1.WaitForResult(); - EXPECT_EQ(OK, rv); - net::CapturingNetLog::EntryList entries; - log.GetEntries(&entries); - size_t pos = ExpectLogContainsSomewhere( - entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, - NetLog::PHASE_NONE); - ExpectLogContainsSomewhere( - entries, pos, - NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, - NetLog::PHASE_NONE); - - const HttpResponseInfo* response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - ASSERT_FALSE(response->headers == NULL); - EXPECT_TRUE(response->headers->IsKeepAlive()); - EXPECT_EQ(407, response->headers->response_code()); - EXPECT_EQ(10, response->headers->GetContentLength()); - EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); - - TestCompletionCallback callback2; - - // Wrong password (should be "bar"). - rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), - callback2.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback2.WaitForResult(); - EXPECT_EQ(OK, rv); - - response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - ASSERT_FALSE(response->headers == NULL); - EXPECT_TRUE(response->headers->IsKeepAlive()); - EXPECT_EQ(407, response->headers->response_code()); - EXPECT_EQ(10, response->headers->GetContentLength()); - EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); - - // Flush the idle socket before the NetLog and HttpNetworkTransaction go - // out of scope. - session->CloseAllConnections(); -} - -// Test the request-challenge-retry sequence for basic auth, through -// a SPDY proxy over a single SPDY session. -TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) { - 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; - - // Configure against https proxy server "myproxy:70". - SessionDependencies session_deps( - ProxyService::CreateFixed("https://myproxy:70")); - CapturingBoundNetLog log(CapturingNetLog::kUnbounded); - session_deps.net_log = log.bound().net_log(); - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - - // Since we have proxy, should try to establish tunnel. - scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyConnect(NULL, 0, 1)); - scoped_ptr<spdy::SpdyFrame> rst(ConstructSpdyRstStream(1, spdy::CANCEL)); - - // After calling trans->RestartWithAuth(), this is the request we should - // be issuing -- the final header line contains the credentials. - const char* const kAuthCredentials[] = { - "proxy-authorization", "Basic Zm9vOmJhcg==", - }; - scoped_ptr<spdy::SpdyFrame> connect2( - ConstructSpdyConnect(kAuthCredentials, arraysize(kAuthCredentials)/2, 3)); - // fetch https://www.google.com/ via HTTP - const char get[] = "GET / HTTP/1.1\r\n" - "Host: www.google.com\r\n" - "Connection: keep-alive\r\n\r\n"; - scoped_ptr<spdy::SpdyFrame> wrapped_get( - ConstructSpdyBodyFrame(3, get, strlen(get), false)); - - MockWrite spdy_writes[] = { - CreateMockWrite(*req, 0, true), - CreateMockWrite(*rst, 2, true), - CreateMockWrite(*connect2, 3), - CreateMockWrite(*wrapped_get, 5) - }; - - // The proxy responds to the connect with a 407, using a persistent - // connection. - const char* const kAuthChallenge[] = { - "status", "407 Proxy Authentication Required", - "version", "HTTP/1.1", - "proxy-authenticate", "Basic realm=\"MyRealm1\"", - }; - - scoped_ptr<spdy::SpdyFrame> conn_auth_resp( - ConstructSpdyControlFrame(NULL, - 0, - false, - 1, - LOWEST, - spdy::SYN_REPLY, - spdy::CONTROL_FLAG_NONE, - kAuthChallenge, - arraysize(kAuthChallenge))); - - scoped_ptr<spdy::SpdyFrame> conn_resp(ConstructSpdyGetSynReply(NULL, 0, 3)); - const char resp[] = "HTTP/1.1 200 OK\r\n" - "Content-Length: 5\r\n\r\n"; - - scoped_ptr<spdy::SpdyFrame> wrapped_get_resp( - ConstructSpdyBodyFrame(3, resp, strlen(resp), false)); - scoped_ptr<spdy::SpdyFrame> wrapped_body( - ConstructSpdyBodyFrame(3, "hello", 5, false)); - MockRead spdy_reads[] = { - CreateMockRead(*conn_auth_resp, 1, true), - CreateMockRead(*conn_resp, 4, true), - CreateMockRead(*wrapped_get_resp, 5, true), - CreateMockRead(*wrapped_body, 6, true), - MockRead(false, ERR_IO_PENDING), - }; - - scoped_ptr<OrderedSocketData> spdy_data( - new OrderedSocketData( - spdy_reads, arraysize(spdy_reads), - spdy_writes, arraysize(spdy_writes))); - session_deps.socket_factory.AddSocketDataProvider(spdy_data.get()); - // Negotiate SPDY to the proxy - SSLSocketDataProvider proxy(true, OK); - proxy.next_proto_status = SSLClientSocket::kNextProtoNegotiated; - proxy.next_proto = "spdy/2"; - proxy.was_npn_negotiated = true; - session_deps.socket_factory.AddSSLSocketDataProvider(&proxy); - // Vanilla SSL to the server - SSLSocketDataProvider server(true, OK); - session_deps.socket_factory.AddSSLSocketDataProvider(&server); - - TestCompletionCallback callback1; - - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - - int rv = trans->Start(&request, callback1.callback(), log.bound()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback1.WaitForResult(); - EXPECT_EQ(OK, rv); - net::CapturingNetLog::EntryList entries; - log.GetEntries(&entries); - size_t pos = ExpectLogContainsSomewhere( - entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, - NetLog::PHASE_NONE); - ExpectLogContainsSomewhere( - entries, pos, - NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, - NetLog::PHASE_NONE); - - const HttpResponseInfo* response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - ASSERT_FALSE(response->headers == NULL); - EXPECT_EQ(407, response->headers->response_code()); - EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); - EXPECT_TRUE(response->auth_challenge.get() != NULL); - EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); - - TestCompletionCallback callback2; - - rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), - callback2.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback2.WaitForResult(); - EXPECT_EQ(OK, rv); - - response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - - EXPECT_TRUE(response->headers->IsKeepAlive()); - EXPECT_EQ(200, response->headers->response_code()); - EXPECT_EQ(5, 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); - - trans.reset(); - session->CloseAllConnections(); -} - - // Test when a server (non-proxy) returns a 407 (proxy-authenticate). // The request should fail with ERR_UNEXPECTED_PROXY_AUTH. TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) { @@ -3449,152 +3065,6 @@ TEST_F(HttpNetworkTransactionTest, NTLMAuth1) { EXPECT_EQ(13, response->headers->GetContentLength()); } - -// Enter the correct password and authenticate successfully. -TEST_F(HttpNetworkTransactionTest, NTLMProxyAuthWithConnectTunnel) { - HttpRequestInfo request; - request.method = "GET"; - request.url = GURL("https://www.google.com/"); - request.load_flags = 0; - - HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, - MockGetHostName); - SessionDependencies session_deps(ProxyService::CreateFixed( - "https://proxy:70")); - - 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"), - }; - - MockRead data_reads1[] = { - MockRead("HTTP/1.1 407 Access Denied\r\n"), - // Negotiate and NTLM are often requested together. However, we only want - // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip - // the header that requests Negotiate for this test. - MockRead("Proxy-Authenticate: NTLM\r\n"), - MockRead("Connection: close\r\n"), - MockRead("Content-Length: 42\r\n"), - MockRead("Content-Type: text/html\r\n\r\n"), - // Missing content -- won't matter, as connection will be reset. - MockRead(false, ERR_UNEXPECTED), - }; - - MockWrite data_writes2[] = { - // After restarting with a null identity, this is the - // request we should be issuing -- the final header line contains a Type - // 1 message. - 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: NTLM " - "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), - - // After calling trans->RestartWithAuth(), we should send a Type 3 message - // (the credentials for the origin server). The second request continues - // on the same connection. - 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: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" - "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" - "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW" - "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX" - "ahlhx5I=\r\n\r\n"), - - MockWrite("GET / HTTP/1.1\r\n" - "Host: www.google.com\r\n" - "Connection: keep-alive\r\n\r\n"), - }; - - MockRead data_reads2[] = { - // The origin server responds with a Type 2 message. - MockRead("HTTP/1.1 407 Access Denied\r\n"), - MockRead("Proxy-Authenticate: NTLM " - "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo" - "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE" - "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA" - "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy" - "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB" - "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw" - "BtAAAAAAA=\r\n"), - MockRead("Content-Length: 42\r\n"), - MockRead("Content-Type: text/html\r\n\r\n"), - MockRead("You are not authorized to view this page\r\n"), - - // Connect succeeds - MockRead("HTTP/1.0 200 Connected\r\n\r\n"), - - // Lastly we get the desired content. - MockRead("HTTP/1.1 200 OK\r\n"), - MockRead("Content-Type: text/html; charset=utf-8\r\n"), - MockRead("Content-Length: 13\r\n\r\n"), - MockRead("Please Login\r\n"), - MockRead(false, OK), - }; - - StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), - data_writes1, arraysize(data_writes1)); - StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), - data_writes2, arraysize(data_writes2)); - SSLSocketDataProvider ssl(true, OK); - SSLSocketDataProvider ssl2(true, OK); - SSLSocketDataProvider ssl3(true, OK); - SSLSocketDataProvider ssl_server(true, OK); - session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); - session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2); - session_deps.socket_factory.AddSSLSocketDataProvider(&ssl3); - session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_server); - session_deps.socket_factory.AddSocketDataProvider(&data1); - session_deps.socket_factory.AddSocketDataProvider(&data2); - scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - - TestCompletionCallback callback1; - - scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); - - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback1.WaitForResult(); - EXPECT_EQ(OK, rv); - - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); - - const HttpResponseInfo* response = trans->GetResponseInfo(); - ASSERT_FALSE(response == NULL); - EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get())); - - TestCompletionCallback callback2; - - rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), - callback2.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback2.WaitForResult(); - EXPECT_EQ(OK, rv); - - EXPECT_TRUE(trans->IsReadyToRestartForAuth()); - - response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - EXPECT_TRUE(response->auth_challenge.get() == NULL); - - TestCompletionCallback callback3; - - rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); - EXPECT_EQ(ERR_IO_PENDING, rv); - - rv = callback3.WaitForResult(); - EXPECT_EQ(OK, rv); - - response = trans->GetResponseInfo(); - ASSERT_TRUE(response != NULL); - EXPECT_TRUE(response->auth_challenge.get() == NULL); - EXPECT_EQ(13, response->headers->GetContentLength()); -} - // Enter a wrong password, and then the correct one. TEST_F(HttpNetworkTransactionTest, NTLMAuth2) { HttpRequestInfo request; @@ -7982,7 +7452,7 @@ TEST_F(HttpNetworkTransactionTest, // - HTTP or HTTPS backend (to include proxy tunneling). // - Non-authenticating and authenticating backend. // -// In all, there are 44 reasonable permutations (for example, if there are +// In all, there are 44 reasonable permuations (for example, if there are // problems generating an auth token for an authenticating proxy, we don't // need to test all permutations of the backend server). // @@ -8840,6 +8310,11 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { // 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 @@ -8856,17 +8331,7 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { "Host: www.google.com\r\n" "Proxy-Connection: keep-alive\r\n" "\r\n"), - }; - - MockWrite data_writes_3[] = { - // Non-alternate protocol job that will run in parallel - MockWrite("GET https://www.google.com/ HTTP/1.1\r\n" - "Host: www.google.com\r\n" - "Proxy-Connection: keep-alive\r\n" - "\r\n"), - }; - MockWrite data_writes_4[] = { // Second connection attempt with Proxy-Authorization. MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" "Host: www.google.com\r\n" @@ -8880,7 +8345,6 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n" "Proxy-Authenticate: Mock\r\n" "Proxy-Connection: close\r\n" - "Content-Length: 0\r\n" "\r\n"); const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n"; MockRead data_reads_2[] = { @@ -8888,35 +8352,19 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1), MockRead(true, kRejectConnectResponse, arraysize(kRejectConnectResponse) - 1, 1), - }; - // Hang forever so we can ensure the alt job wins - MockRead data_reads_3[] = { - MockRead(false, ERR_IO_PENDING), - }; - - MockRead data_reads_4[] = { // Second connection attempt passes MockRead(true, kAcceptConnectResponse, - arraysize(kAcceptConnectResponse) -1, 1), + arraysize(kAcceptConnectResponse) -1, 4), // SPDY response - CreateMockRead(*resp.get(), 3), - CreateMockRead(*data.get(), 3), - MockRead(true, 0, 0, 4), + CreateMockRead(*resp.get(), 6), + CreateMockRead(*data.get(), 6), + MockRead(true, 0, 0, 6), }; scoped_ptr<OrderedSocketData> data_2( new OrderedSocketData(data_reads_2, arraysize(data_reads_2), data_writes_2, arraysize(data_writes_2))); - scoped_ptr<OrderedSocketData> data_3( - new OrderedSocketData(data_reads_3, arraysize(data_reads_3), - data_writes_3, arraysize(data_writes_3))); - // Hang forever so we can ensure the alt job wins - MockConnect conn_3(false, ERR_IO_PENDING); - data_3->set_connect_data(conn_3); - scoped_ptr<OrderedSocketData> data_4( - new OrderedSocketData(data_reads_4, arraysize(data_reads_4), - data_writes_4, arraysize(data_writes_4))); SSLSocketDataProvider ssl(true, OK); ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated; @@ -8932,9 +8380,6 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { session_deps.socket_factory.AddSocketDataProvider(&data_1); session_deps.socket_factory.AddSocketDataProvider(data_2.get()); - session_deps.socket_factory.AddSocketDataProvider(data_3.get()); - session_deps.socket_factory.AddSocketDataProvider(data_4.get()); - session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); session_deps.socket_factory.AddSocketDataProvider( &hanging_non_alternate_protocol_socket); diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc index 97f1402..8e6631a 100644 --- a/net/http/http_proxy_client_socket.cc +++ b/net/http/http_proxy_client_socket.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -31,7 +31,8 @@ HttpProxyClientSocket::HttpProxyClientSocket( const std::string& user_agent, const HostPortPair& endpoint, const HostPortPair& proxy_server, - HttpAuthController* http_auth_controller, + HttpAuthCache* http_auth_cache, + HttpAuthHandlerFactory* http_auth_handler_factory, bool tunnel, bool using_spdy, SSLClientSocket::NextProto protocol_negotiated, @@ -42,7 +43,13 @@ HttpProxyClientSocket::HttpProxyClientSocket( next_state_(STATE_NONE), transport_(transport_socket), endpoint_(endpoint), - auth_(http_auth_controller), + auth_(tunnel ? + new HttpAuthController(HttpAuth::AUTH_PROXY, + GURL((is_https_proxy ? "https://" : "http://") + + proxy_server.ToString()), + http_auth_cache, + http_auth_handler_factory) + : NULL), tunnel_(tunnel), using_spdy_(using_spdy), protocol_negotiated_(protocol_negotiated), @@ -60,11 +67,6 @@ HttpProxyClientSocket::~HttpProxyClientSocket() { Disconnect(); } -const -scoped_refptr<HttpAuthController>& HttpProxyClientSocket::GetAuthController() { - return auth_; -} - int HttpProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) { DCHECK_EQ(STATE_NONE, next_state_); DCHECK(user_callback_.is_null()); @@ -252,14 +254,14 @@ int HttpProxyClientSocket::PrepareForAuthRestart() { } int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) { - int rv = OK; if (keep_alive && transport_->socket()->IsConnectedAndIdle()) { next_state_ = STATE_GENERATE_AUTH_TOKEN; transport_->set_is_reused(true); } else { - next_state_ = STATE_NONE; + // 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(); - rv = ERR_NO_KEEP_ALIVE_ON_AUTH_RESTART; } // Reset the other member variables. @@ -269,6 +271,17 @@ int HttpProxyClientSocket::DidDrainBodyForAuthRestart(bool keep_alive) { request_line_.clear(); request_headers_.Clear(); response_ = HttpResponseInfo(); + return OK; +} + +int HttpProxyClientSocket::HandleAuthChallenge() { + DCHECK(response_.headers); + + int rv = auth_->HandleAuthChallenge(response_.headers, false, true, net_log_); + response_.auth_challenge = auth_->auth_info(); + if (rv == OK) + return ERR_PROXY_AUTH_REQUESTED; + return rv; } @@ -341,6 +354,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: @@ -439,7 +459,7 @@ int HttpProxyClientSocket::DoReadHeadersComplete(int result) { // authentication code is smart enough to avoid being tricked by an // active network attacker. // The next state is intentionally not set as it should be STATE_NONE; - return HandleAuthChallenge(auth_, &response_, net_log_); + return HandleAuthChallenge(); default: if (is_https_proxy_) @@ -475,4 +495,18 @@ int HttpProxyClientSocket::DoDrainBodyComplete(int result) { return OK; } +int HttpProxyClientSocket::DoTCPRestart() { + next_state_ = STATE_TCP_RESTART_COMPLETE; + return transport_->socket()->Connect( + base::Bind(&HttpProxyClientSocket::OnIOComplete, base::Unretained(this))); +} + +int HttpProxyClientSocket::DoTCPRestartComplete(int result) { + if (result != OK) + return result; + + next_state_ = STATE_GENERATE_AUTH_TOKEN; + return result; +} + } // namespace net diff --git a/net/http/http_proxy_client_socket.h b/net/http/http_proxy_client_socket.h index 7a05127..e4b1844 100644 --- a/net/http/http_proxy_client_socket.h +++ b/net/http/http_proxy_client_socket.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -27,6 +27,7 @@ namespace net { class AddressList; class ClientSocketHandle; class GrowableIOBuffer; +class HttpAuthCache; class HttpStream; class HttpStreamParser; class IOBuffer; @@ -41,7 +42,8 @@ class HttpProxyClientSocket : public ProxyClientSocket { const std::string& user_agent, const HostPortPair& endpoint, const HostPortPair& proxy_server, - HttpAuthController* http_auth_controller, + HttpAuthCache* http_auth_cache, + HttpAuthHandlerFactory* http_auth_handler_factory, bool tunnel, bool using_spdy, SSLClientSocket::NextProto protocol_negotiated, @@ -50,6 +52,15 @@ class HttpProxyClientSocket : public ProxyClientSocket { // On destruction Disconnect() is called. virtual ~HttpProxyClientSocket(); + // If Connect (or its callback) returns PROXY_AUTH_REQUESTED, then + // credentials should be added to the HttpAuthController before calling + // RestartWithAuth. + int RestartWithAuth(const CompletionCallback& callback); + + const scoped_refptr<HttpAuthController>& auth_controller() { + return auth_; + } + bool using_spdy() { return using_spdy_; } @@ -61,8 +72,6 @@ class HttpProxyClientSocket : public ProxyClientSocket { // ProxyClientSocket implementation. virtual const HttpResponseInfo* GetConnectResponseInfo() const OVERRIDE; virtual HttpStream* CreateConnectResponseStream() OVERRIDE; - virtual int RestartWithAuth(const CompletionCallback& callback) OVERRIDE; - virtual const scoped_refptr<HttpAuthController>& GetAuthController() OVERRIDE; // StreamSocket implementation. virtual int Connect(const CompletionCallback& callback) OVERRIDE; @@ -100,6 +109,8 @@ class HttpProxyClientSocket : public ProxyClientSocket { STATE_READ_HEADERS_COMPLETE, STATE_DRAIN_BODY, STATE_DRAIN_BODY_COMPLETE, + STATE_TCP_RESTART, + STATE_TCP_RESTART_COMPLETE, STATE_DONE, }; @@ -111,6 +122,8 @@ class HttpProxyClientSocket : public ProxyClientSocket { int PrepareForAuthRestart(); int DidDrainBodyForAuthRestart(bool keep_alive); + int HandleAuthChallenge(); + void LogBlockedTunnelResponse(int response_code) const; void DoCallback(int result); diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc index 7e2d168..7a51717 100644 --- a/net/http/http_proxy_client_socket_pool.cc +++ b/net/http/http_proxy_client_socket_pool.cc @@ -28,15 +28,6 @@ namespace net { -namespace { - -std::string GetProxyUrl(const scoped_refptr<HttpProxySocketParams>& params) { - return (params->ssl_params() != NULL ? "https://" : "http://") - + params->destination().host_port_pair().ToString(); -} - -} // namespace - HttpProxySocketParams::HttpProxySocketParams( const scoped_refptr<TransportSocketParams>& transport_params, const scoped_refptr<SSLSocketParams>& ssl_params, @@ -46,8 +37,7 @@ HttpProxySocketParams::HttpProxySocketParams( HttpAuthCache* http_auth_cache, HttpAuthHandlerFactory* http_auth_handler_factory, SpdySessionPool* spdy_session_pool, - bool tunnel, - TunnelAuthCallback auth_needed_callback) + bool tunnel) : transport_params_(transport_params), ssl_params_(ssl_params), spdy_session_pool_(spdy_session_pool), @@ -56,8 +46,7 @@ HttpProxySocketParams::HttpProxySocketParams( endpoint_(endpoint), http_auth_cache_(tunnel ? http_auth_cache : NULL), http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL), - tunnel_(tunnel), - auth_needed_callback_(auth_needed_callback) { + tunnel_(tunnel) { DCHECK((transport_params == NULL && ssl_params != NULL) || (transport_params != NULL && ssl_params == NULL)); if (transport_params_) @@ -98,14 +87,7 @@ HttpProxyConnectJob::HttpProxyConnectJob( callback_(base::Bind(&HttpProxyConnectJob::OnIOComplete, base::Unretained(this)))), using_spdy_(false), - protocol_negotiated_(SSLClientSocket::kProtoUnknown), - auth_(params->tunnel() ? - new HttpAuthController(HttpAuth::AUTH_PROXY, - GURL(GetProxyUrl(params_)), - params->http_auth_cache(), - params->http_auth_handler_factory()) - : NULL), - ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { + protocol_negotiated_(SSLClientSocket::kProtoUnknown) { } HttpProxyConnectJob::~HttpProxyConnectJob() {} @@ -121,8 +103,6 @@ LoadState HttpProxyConnectJob::GetLoadState() const { case STATE_HTTP_PROXY_CONNECT_COMPLETE: case STATE_SPDY_PROXY_CREATE_STREAM: case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: - case STATE_RESTART_WITH_AUTH: - case STATE_RESTART_WITH_AUTH_COMPLETE: return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; default: NOTREACHED(); @@ -179,13 +159,6 @@ int HttpProxyConnectJob::DoLoop(int result) { case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: rv = DoSpdyProxyCreateStreamComplete(rv); break; - case STATE_RESTART_WITH_AUTH: - DCHECK_EQ(OK, rv); - rv = DoRestartWithAuth(); - break; - case STATE_RESTART_WITH_AUTH_COMPLETE: - rv = DoRestartWithAuthComplete(rv); - break; default: NOTREACHED() << "bad state"; rv = ERR_FAILED; @@ -293,7 +266,8 @@ int HttpProxyConnectJob::DoHttpProxyConnect() { params_->user_agent(), params_->endpoint(), proxy_server, - auth_, + params_->http_auth_cache(), + params_->http_auth_handler_factory(), params_->tunnel(), using_spdy_, protocol_negotiated_, @@ -301,54 +275,8 @@ int HttpProxyConnectJob::DoHttpProxyConnect() { return transport_socket_->Connect(callback_); } -void HttpProxyConnectJob::HandleProxyAuthChallenge() { - next_state_ = STATE_RESTART_WITH_AUTH; - params_->auth_needed_callback().Run( - *transport_socket_->GetConnectResponseInfo(), - transport_socket_->GetAuthController(), - callback_); -} - -int HttpProxyConnectJob::DoRestartWithAuth() { - // If no auth was added to the controller, then we should abort. - next_state_ = STATE_RESTART_WITH_AUTH_COMPLETE; - if (!transport_socket_->GetAuthController()->HaveAuth()) { - return ERR_PROXY_AUTH_REQUESTED; - } - - return transport_socket_->RestartWithAuth(callback_); -} - -int HttpProxyConnectJob::DoRestartWithAuthComplete(int result) { - if (result != OK) { - if (result == ERR_NO_KEEP_ALIVE_ON_AUTH_RESTART) { - next_state_ = params_->transport_params() ? - STATE_TCP_CONNECT : STATE_SSL_CONNECT; - return OK; - } - if (result == ERR_PROXY_AUTH_REQUESTED || - result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { - set_socket(transport_socket_.release()); - } - return result; - } - - next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; - return OK; -} - int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) { - // Handle a proxy auth challenge by asynchronously invoking the callback. - // We do this asynchronously so that the caller is notified of job - // completion only via NotifyDelegateOfCompletion. - if (result == ERR_PROXY_AUTH_REQUESTED) { - MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&HttpProxyConnectJob::HandleProxyAuthChallenge, - ptr_factory_.GetWeakPtr())); - return ERR_IO_PENDING; - } - if (result == OK || + if (result == OK || result == ERR_PROXY_AUTH_REQUESTED || result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { set_socket(transport_socket_.release()); } @@ -398,7 +326,8 @@ int HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) { params_->endpoint(), params_->request_url(), params_->destination().host_port_pair(), - auth_)); + params_->http_auth_cache(), + params_->http_auth_handler_factory())); return transport_socket_->Connect(callback_); } diff --git a/net/http/http_proxy_client_socket_pool.h b/net/http/http_proxy_client_socket_pool.h index 70c8b5c..483520b 100644 --- a/net/http/http_proxy_client_socket_pool.h +++ b/net/http/http_proxy_client_socket_pool.h @@ -26,7 +26,6 @@ namespace net { class HostResolver; class HttpAuthCache; -class HttpAuthController; class HttpAuthHandlerFactory; class SSLClientSocketPool; class SSLSocketParams; @@ -35,17 +34,6 @@ class SpdyStream; class TransportClientSocketPool; class TransportSocketParams; -// Called when a 407 Proxy Authentication Required response is received -// from an HTTP or HTTPS proxy when attempting to establish a CONNECT tunnel -// to an HTTPS server. Information about the challenge can be found in -// the HttpResponse info. Credentials should be added to the -// HttpAuthController, and the CompletionCallback should be invoked -// with the status. -typedef base::Callback<void (const HttpResponseInfo&, - HttpAuthController*, - CompletionCallback)> - TunnelAuthCallback; - // HttpProxySocketParams only needs the socket params for one of the proxy // types. The other param must be NULL. When using an HTTP Proxy, // |transport_params| must be set. When using an HTTPS Proxy, |ssl_params| @@ -62,8 +50,7 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams HttpAuthCache* http_auth_cache, HttpAuthHandlerFactory* http_auth_handler_factory, SpdySessionPool* spdy_session_pool, - bool tunnel, - TunnelAuthCallback auth_needed_callback); + bool tunnel); const scoped_refptr<TransportSocketParams>& transport_params() const { return transport_params_; @@ -84,7 +71,6 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams const HostResolver::RequestInfo& destination() const; bool tunnel() const { return tunnel_; } bool ignore_limits() const { return ignore_limits_; } - TunnelAuthCallback auth_needed_callback() { return auth_needed_callback_; } private: friend class base::RefCounted<HttpProxySocketParams>; @@ -100,7 +86,6 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams HttpAuthHandlerFactory* const http_auth_handler_factory_; const bool tunnel_; bool ignore_limits_; - TunnelAuthCallback auth_needed_callback_; DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams); }; @@ -135,8 +120,6 @@ class HttpProxyConnectJob : public ConnectJob { STATE_SPDY_PROXY_CREATE_STREAM, STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE, STATE_SPDY_PROXY_CONNECT_COMPLETE, - STATE_RESTART_WITH_AUTH, - STATE_RESTART_WITH_AUTH_COMPLETE, STATE_NONE, }; @@ -158,11 +141,6 @@ class HttpProxyConnectJob : public ConnectJob { int DoSpdyProxyCreateStream(); int DoSpdyProxyCreateStreamComplete(int result); - int DoRestartWithAuth(); - int DoRestartWithAuthComplete(int result); - - void HandleProxyAuthChallenge(); - // Begins the tcp connection and the optional Http proxy tunnel. If the // request is not immediately servicable (likely), the request will return // ERR_IO_PENDING. An OK return from this function or the callback means @@ -189,11 +167,6 @@ class HttpProxyConnectJob : public ConnectJob { scoped_refptr<SpdyStream> spdy_stream_; - // AuthController to be used for *all* requests when setting up this tunnel. - scoped_refptr<HttpAuthController> auth_; - - base::WeakPtrFactory<HttpProxyConnectJob> ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob); }; diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc index bf5b418..433612f 100644 --- a/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/net/http/http_proxy_client_socket_pool_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -131,9 +131,7 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam { session_->http_auth_cache(), session_->http_auth_handler_factory(), session_->spdy_session_pool(), - tunnel, - base::Bind(&HttpProxyClientSocketPoolTest::OnNeedsProxyAuthCallback, - base::Unretained(this)))); + tunnel)); } scoped_refptr<HttpProxySocketParams> GetTunnelParams() { @@ -193,14 +191,6 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam { return new HttpNetworkSession(params); } - void OnNeedsProxyAuthCallback(const HttpResponseInfo& response_info, - HttpAuthController* auth_controller, - CompletionCallback cb) { - // Don't add any auth, just run the callback - cb.Run(OK); - } - - private: SSLConfig ssl_config_; @@ -268,21 +258,9 @@ TEST_P(HttpProxyClientSocketPoolTest, NeedAuth) { CreateMockWrite(*req, 0, true), CreateMockWrite(*rst, 2, true), }; - static const char* const kAuthChallenge[] = { - "status", "407 Proxy Authentication Required", - "version", "HTTP/1.1", - "proxy-authenticate", "Basic realm=\"MyRealm1\"", - }; scoped_ptr<spdy::SpdyFrame> resp( - ConstructSpdyControlFrame(NULL, - 0, - false, - 1, - LOWEST, - spdy::SYN_REPLY, - spdy::CONTROL_FLAG_NONE, - kAuthChallenge, - arraysize(kAuthChallenge))); + ConstructSpdySynReplyError( + "407 Proxy Authentication Required", NULL, 0, 1)); MockRead spdy_reads[] = { CreateMockWrite(*resp, 1, true), MockRead(true, 0, 3) @@ -299,16 +277,21 @@ TEST_P(HttpProxyClientSocketPoolTest, NeedAuth) { EXPECT_FALSE(handle_.is_initialized()); EXPECT_FALSE(handle_.socket()); - data_->RunFor(GetParam() == SPDY ? 2 : 4); + data_->RunFor(4); rv = callback_.WaitForResult(); - EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, rv); - EXPECT_TRUE(handle_.is_initialized()); - ASSERT_TRUE(handle_.socket()); if (GetParam() != SPDY) { + EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, rv); + EXPECT_TRUE(handle_.is_initialized()); + ASSERT_TRUE(handle_.socket()); HttpProxyClientSocket* tunnel_socket = static_cast<HttpProxyClientSocket*>(handle_.socket()); EXPECT_FALSE(tunnel_socket->IsConnected()); EXPECT_FALSE(tunnel_socket->using_spdy()); + } else { + // Proxy auth is not really implemented for SPDY yet + EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); + EXPECT_FALSE(handle_.is_initialized()); + EXPECT_FALSE(handle_.socket()); } } diff --git a/net/http/http_proxy_utils.cc b/net/http/http_proxy_utils.cc index c523eb1..7086bda 100644 --- a/net/http/http_proxy_utils.cc +++ b/net/http/http_proxy_utils.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,12 +7,8 @@ #include "base/stringprintf.h" #include "googleurl/src/gurl.h" #include "net/base/host_port_pair.h" -#include "net/base/net_errors.h" #include "net/base/net_util.h" -#include "net/http/http_auth_controller.h" #include "net/http/http_request_info.h" -#include "net/http/http_response_headers.h" -#include "net/http/http_response_info.h" namespace net { @@ -40,16 +36,4 @@ void BuildTunnelRequest( request_headers->MergeFrom(auth_headers); } -int HandleAuthChallenge(HttpAuthController* auth, - HttpResponseInfo* response, - const BoundNetLog& net_log) { - DCHECK(response->headers); - - int rv = auth->HandleAuthChallenge(response->headers, false, true, net_log); - response->auth_challenge = auth->auth_info(); - if (rv == OK) - return ERR_PROXY_AUTH_REQUESTED; - return rv; -} - } // namespace net diff --git a/net/http/http_proxy_utils.h b/net/http/http_proxy_utils.h index c8aabb8..b93d034 100644 --- a/net/http/http_proxy_utils.h +++ b/net/http/http_proxy_utils.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -10,9 +10,6 @@ namespace net { -class BoundNetLog; -class HttpAuthController; -class HttpResponseInfo; struct HttpRequestInfo; class HttpRequestHeaders; class HostPortPair; @@ -26,12 +23,6 @@ void BuildTunnelRequest(const HttpRequestInfo& request_info, std::string* request_line, HttpRequestHeaders* request_headers); -// When an auth challenge (407 response) is received during tunnel construction -// this method should be called. -int HandleAuthChallenge(HttpAuthController* auth, - HttpResponseInfo* response, - const BoundNetLog& net_log); - } // namespace net #endif // NET_HTTP_HTTP_PROXY_UTILS_H_ diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index 6c9a1fe..2bdc55e0 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc @@ -180,20 +180,12 @@ int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) { return StartInternal(); } -int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth() { - // We run this asynchronously to ensure that we don't invoke - // the callback (which might cause the caller to be deleted) - // while the caller is waiting for this method to return. - MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&HttpStreamFactoryImpl::Job::DoRestartTunnelWithProxyAuth, - ptr_factory_.GetWeakPtr())); - return ERR_IO_PENDING; -} - -void HttpStreamFactoryImpl::Job::DoRestartTunnelWithProxyAuth() { - tunnel_auth_handled_callback_.Run(OK); - tunnel_auth_handled_callback_.Reset(); +int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth( + const AuthCredentials& credentials) { + DCHECK(establishing_tunnel_); + next_state_ = STATE_RESTART_TUNNEL_AUTH; + stream_.reset(); + return RunLoop(OK); } LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { @@ -349,18 +341,6 @@ void HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback( // |this| may be deleted after this call. } -void HttpStreamFactoryImpl::Job::OnNeedsProxyTunnelAuthCallback( - const HttpResponseInfo& response_info, - HttpAuthController* auth_controller, - CompletionCallback callback) { - DCHECK(!callback.is_null()); - DCHECK(tunnel_auth_handled_callback_.is_null()); - tunnel_auth_handled_callback_ = callback; - request_->OnNeedsProxyAuth( - this, response_info, server_ssl_config_, proxy_info_, auth_controller); - // |this| may be deleted after this call. -} - void HttpStreamFactoryImpl::Job::OnNeedsClientAuthCallback( SSLCertRequestInfo* cert_info) { DCHECK(!IsPreconnecting()); @@ -439,10 +419,10 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { DCHECK(connection_->socket()); DCHECK(establishing_tunnel_); - ProxyClientSocket* proxy_socket = - static_cast<ProxyClientSocket*>(connection_->socket()); + HttpProxyClientSocket* http_proxy_socket = + static_cast<HttpProxyClientSocket*>(connection_->socket()); const HttpResponseInfo* tunnel_auth_response = - proxy_socket->GetConnectResponseInfo(); + http_proxy_socket->GetConnectResponseInfo(); next_state_ = STATE_WAITING_USER_ACTION; MessageLoop::current()->PostTask( @@ -451,7 +431,7 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { &HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback, ptr_factory_.GetWeakPtr(), *tunnel_auth_response, - proxy_socket->GetAuthController())); + http_proxy_socket->auth_controller())); } return ERR_IO_PENDING; @@ -752,18 +732,13 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { server_ssl_config_, proxy_ssl_config_, net_log_, - num_streams_, - base::Bind(&HttpStreamFactoryImpl::Job::OnNeedsProxyTunnelAuthCallback, - ptr_factory_.GetWeakPtr())); + num_streams_); } else { return InitSocketHandleForHttpRequest( origin_url_, request_info_.extra_headers, request_info_.load_flags, request_info_.priority, session_, proxy_info_, ShouldForceSpdySSL(), want_spdy_over_npn, server_ssl_config_, proxy_ssl_config_, net_log_, - connection_.get(), - base::Bind(&HttpStreamFactoryImpl::Job::OnNeedsProxyTunnelAuthCallback, - ptr_factory_.GetWeakPtr()), - io_callback_); + connection_.get(), io_callback_); } } diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h index 979e7e8..ab15c8e 100644 --- a/net/http/http_stream_factory_impl_job.h +++ b/net/http/http_stream_factory_impl_job.h @@ -13,7 +13,6 @@ #include "net/base/ssl_config_service.h" #include "net/http/http_auth.h" #include "net/http/http_auth_controller.h" -#include "net/http/http_proxy_client_socket_pool.h" #include "net/http/http_request_info.h" #include "net/http/http_stream_factory_impl.h" #include "net/proxy/proxy_service.h" @@ -47,8 +46,7 @@ class HttpStreamFactoryImpl::Job { // appropriate ClientSocketPool. int Preconnect(int num_streams); - int RestartTunnelWithProxyAuth(); - + int RestartTunnelWithProxyAuth(const AuthCredentials& credentials); LoadState GetLoadState() const; // Marks this Job as the "alternate" job, from Alternate-Protocol. Tracks the @@ -125,9 +123,6 @@ class HttpStreamFactoryImpl::Job { void OnCertificateErrorCallback(int result, const SSLInfo& ssl_info); void OnNeedsProxyAuthCallback(const HttpResponseInfo& response_info, HttpAuthController* auth_controller); - void OnNeedsProxyTunnelAuthCallback(const HttpResponseInfo& response_info, - HttpAuthController* auth_controller, - CompletionCallback callback); void OnNeedsClientAuthCallback(SSLCertRequestInfo* cert_info); void OnHttpsProxyTunnelResponseCallback(const HttpResponseInfo& response_info, HttpStream* stream); @@ -158,8 +153,6 @@ class HttpStreamFactoryImpl::Job { // Returns to STATE_INIT_CONNECTION and resets some state. void ReturnToStateInitConnection(bool close_connection); - void DoRestartTunnelWithProxyAuth(); - // Set the motivation for this request onto the underlying socket. void SetSocketMotivation(); @@ -262,9 +255,6 @@ class HttpStreamFactoryImpl::Job { scoped_refptr<HttpAuthController> auth_controllers_[HttpAuth::AUTH_NUM_TARGETS]; - // Invoked after a request for tunnel auth has been handled. - CompletionCallback tunnel_auth_handled_callback_; - // True when the tunnel is in the process of being established - we can't // read from the socket until the tunnel is done. bool establishing_tunnel_; diff --git a/net/http/http_stream_factory_impl_request.cc b/net/http/http_stream_factory_impl_request.cc index 1a14a86..cb8fcbf 100644 --- a/net/http/http_stream_factory_impl_request.cc +++ b/net/http/http_stream_factory_impl_request.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -205,7 +205,7 @@ void HttpStreamFactoryImpl::Request::OnHttpsProxyTunnelResponse( int HttpStreamFactoryImpl::Request::RestartTunnelWithProxyAuth( const AuthCredentials& credentials) { DCHECK(bound_job_.get()); - return bound_job_->RestartTunnelWithProxyAuth(); + return bound_job_->RestartTunnelWithProxyAuth(credentials); } LoadState HttpStreamFactoryImpl::Request::GetLoadState() const { diff --git a/net/http/proxy_client_socket.h b/net/http/proxy_client_socket.h index 21c7086..451e098 100644 --- a/net/http/proxy_client_socket.h +++ b/net/http/proxy_client_socket.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -12,7 +12,6 @@ namespace net { class HttpStream; class HttpResponseInfo; -class HttpAuthController; class NET_EXPORT_PRIVATE ProxyClientSocket : public StreamSocket { public: @@ -27,15 +26,6 @@ class NET_EXPORT_PRIVATE ProxyClientSocket : public StreamSocket { // which can be used to read the response body. virtual HttpStream* CreateConnectResponseStream() = 0; - // Returns the HttpAuthController which can be used - // to interact with an HTTP Proxy Authorization Required (407) request. - virtual const scoped_refptr<HttpAuthController>& GetAuthController() = 0; - - // If Connect (or its callback) returns PROXY_AUTH_REQUESTED, then - // credentials should be added to the HttpAuthController before calling - // RestartWithAuth. - virtual int RestartWithAuth(const CompletionCallback& callback) = 0; - private: DISALLOW_COPY_AND_ASSIGN(ProxyClientSocket); }; diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc index b65cb83..7098864 100644 --- a/net/socket/client_socket_pool_manager.cc +++ b/net/socket/client_socket_pool_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -52,7 +52,6 @@ int InitSocketPoolHelper(const GURL& request_url, const BoundNetLog& net_log, int num_preconnect_streams, ClientSocketHandle* socket_handle, - TunnelAuthCallback auth_needed_callback, const CompletionCallback& callback) { scoped_refptr<TransportSocketParams> tcp_params; scoped_refptr<HttpProxySocketParams> http_proxy_params; @@ -137,8 +136,7 @@ int InitSocketPoolHelper(const GURL& request_url, session->http_auth_cache(), session->http_auth_handler_factory(), session->spdy_session_pool(), - force_tunnel || using_ssl, - auth_needed_callback); + force_tunnel || using_ssl); } else { DCHECK(proxy_info.is_socks()); char socks_version; @@ -291,15 +289,13 @@ int InitSocketHandleForHttpRequest( const SSLConfig& ssl_config_for_proxy, const BoundNetLog& net_log, ClientSocketHandle* socket_handle, - TunnelAuthCallback auth_needed_callback, const CompletionCallback& callback) { - DCHECK(socket_handle); return InitSocketPoolHelper( request_url, request_extra_headers, request_load_flags, request_priority, session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn, ssl_config_for_origin, ssl_config_for_proxy, false, net_log, 0, - socket_handle, auth_needed_callback, callback); + socket_handle, callback); } int InitSocketHandleForRawConnect( @@ -310,7 +306,6 @@ int InitSocketHandleForRawConnect( const SSLConfig& ssl_config_for_proxy, const BoundNetLog& net_log, ClientSocketHandle* socket_handle, - TunnelAuthCallback auth_needed_callback, const CompletionCallback& callback) { DCHECK(socket_handle); // Synthesize an HttpRequestInfo. @@ -318,11 +313,11 @@ int InitSocketHandleForRawConnect( HttpRequestHeaders request_extra_headers; int request_load_flags = 0; RequestPriority request_priority = MEDIUM; + return InitSocketPoolHelper( request_url, request_extra_headers, request_load_flags, request_priority, session, proxy_info, false, false, ssl_config_for_origin, - ssl_config_for_proxy, true, net_log, 0, socket_handle, - auth_needed_callback, callback); + ssl_config_for_proxy, true, net_log, 0, socket_handle, callback); } int PreconnectSocketsForHttpRequest( @@ -337,13 +332,12 @@ int PreconnectSocketsForHttpRequest( const SSLConfig& ssl_config_for_origin, const SSLConfig& ssl_config_for_proxy, const BoundNetLog& net_log, - int num_preconnect_streams, - TunnelAuthCallback auth_needed_callback) { + int num_preconnect_streams) { return InitSocketPoolHelper( request_url, request_extra_headers, request_load_flags, request_priority, session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn, ssl_config_for_origin, ssl_config_for_proxy, false, net_log, - num_preconnect_streams, NULL, auth_needed_callback, CompletionCallback()); + num_preconnect_streams, NULL, CompletionCallback()); } } // namespace net diff --git a/net/socket/client_socket_pool_manager.h b/net/socket/client_socket_pool_manager.h index f025e56..7c1f865 100644 --- a/net/socket/client_socket_pool_manager.h +++ b/net/socket/client_socket_pool_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. // @@ -13,7 +13,6 @@ #include "net/base/completion_callback.h" #include "net/base/net_export.h" #include "net/base/request_priority.h" -#include "net/http/http_proxy_client_socket_pool.h" class GURL; @@ -27,6 +26,7 @@ class BoundNetLog; class ClientSocketHandle; class HostPortPair; class HttpNetworkSession; +class HttpProxyClientSocketPool; class HttpRequestHeaders; class ProxyInfo; class TransportClientSocketPool; @@ -88,7 +88,6 @@ int InitSocketHandleForHttpRequest( const SSLConfig& ssl_config_for_proxy, const BoundNetLog& net_log, ClientSocketHandle* socket_handle, - TunnelAuthCallback auth_needed_callback, const CompletionCallback& callback); // A helper method that uses the passed in proxy information to initialize a @@ -103,7 +102,6 @@ NET_EXPORT int InitSocketHandleForRawConnect( const SSLConfig& ssl_config_for_proxy, const BoundNetLog& net_log, ClientSocketHandle* socket_handle, - TunnelAuthCallback auth_needed_callback, const CompletionCallback& callback); // Similar to InitSocketHandleForHttpRequest except that it initiates the @@ -120,8 +118,7 @@ int PreconnectSocketsForHttpRequest( const SSLConfig& ssl_config_for_origin, const SSLConfig& ssl_config_for_proxy, const BoundNetLog& net_log, - int num_preconnect_streams, - TunnelAuthCallback auth_needed_callback); + int num_preconnect_streams); } // namespace net diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc index 33a0d70..53f7f97 100644 --- a/net/socket/ssl_client_socket_pool.cc +++ b/net/socket/ssl_client_socket_pool.cc @@ -258,8 +258,8 @@ int SSLConnectJob::DoTunnelConnectComplete(int result) { } else if (result == ERR_PROXY_AUTH_REQUESTED || result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { StreamSocket* socket = transport_socket_handle_->socket(); - ProxyClientSocket* tunnel_socket = - static_cast<ProxyClientSocket*>(socket); + HttpProxyClientSocket* tunnel_socket = + static_cast<HttpProxyClientSocket*>(socket); error_response_info_ = *tunnel_socket->GetConnectResponseInfo(); } if (result < 0) diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc index 53e6382..c751a4a 100644 --- a/net/socket/ssl_client_socket_pool_unittest.cc +++ b/net/socket/ssl_client_socket_pool_unittest.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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/socket/ssl_client_socket_pool.h" +#include "net/http/http_proxy_client_socket_pool.h" #include "base/callback.h" #include "base/compiler_specific.h" @@ -19,7 +19,6 @@ #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_pool.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "net/http/http_server_properties_impl.h" @@ -72,9 +71,7 @@ class SSLClientSocketPoolTest : public testing::Test { session_->http_auth_cache(), session_->http_auth_handler_factory(), session_->spdy_session_pool(), - true, - base::Bind(&SSLClientSocketPoolTest::OnNeedsProxyAuthCallback, - base::Unretained(this)))), + true)), http_proxy_histograms_("MockHttpProxy"), http_proxy_socket_pool_( kMaxSockets, @@ -147,13 +144,6 @@ class SSLClientSocketPoolTest : public testing::Test { return new HttpNetworkSession(params); } - void OnNeedsProxyAuthCallback(const HttpResponseInfo& response_info, - HttpAuthController* auth_controller, - CompletionCallback cb) { - // Don't add any auth, just execute the callback. - cb.Run(OK); - } - MockClientSocketFactory socket_factory_; MockCachingHostResolver host_resolver_; CertVerifier cert_verifier_; diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc index adbba8e..7267fef 100644 --- a/net/spdy/spdy_proxy_client_socket.cc +++ b/net/spdy/spdy_proxy_client_socket.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -14,6 +14,8 @@ #include "net/base/auth.h" #include "net/base/io_buffer.h" #include "net/base/net_util.h" +#include "net/http/http_auth_cache.h" +#include "net/http/http_auth_handler_factory.h" #include "net/http/http_net_log_params.h" #include "net/http/http_proxy_utils.h" #include "net/http/http_response_headers.h" @@ -27,11 +29,16 @@ SpdyProxyClientSocket::SpdyProxyClientSocket( const HostPortPair& endpoint, const GURL& url, const HostPortPair& proxy_server, - HttpAuthController* http_auth_controller) + HttpAuthCache* auth_cache, + HttpAuthHandlerFactory* auth_handler_factory) : next_state_(STATE_DISCONNECTED), spdy_stream_(spdy_stream), endpoint_(endpoint), - auth_(http_auth_controller), + auth_( + new HttpAuthController(HttpAuth::AUTH_PROXY, + GURL("https://" + proxy_server.ToString()), + auth_cache, + auth_handler_factory)), user_buffer_(NULL), write_buffer_len_(0), write_bytes_outstanding_(0), @@ -54,19 +61,6 @@ const HttpResponseInfo* SpdyProxyClientSocket::GetConnectResponseInfo() const { return response_.headers ? &response_ : NULL; } -const -scoped_refptr<HttpAuthController>& SpdyProxyClientSocket::GetAuthController() { - return auth_; -} - -int SpdyProxyClientSocket::RestartWithAuth(const CompletionCallback& callback) { - // A SPDY Stream can only handle a single request, so the underlying - // stream may not be reused and a new SpdyProxyClientSocket must be - // created (possibly on top of the same SPDY Session). - next_state_ = STATE_DISCONNECTED; - return ERR_NO_KEEP_ALIVE_ON_AUTH_RESTART; -} - HttpStream* SpdyProxyClientSocket::CreateConnectResponseStream() { DCHECK(response_stream_.get()); return response_stream_.release(); @@ -78,6 +72,8 @@ HttpStream* SpdyProxyClientSocket::CreateConnectResponseStream() { // ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status. // In any of these cases, Read() may be called to retrieve the HTTP // response body. Any other return values should be considered fatal. +// TODO(rch): handle 407 proxy auth requested correctly, perhaps +// by creating a new stream for the subsequent request. // TODO(rch): create a more appropriate error code to disambiguate // the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure. int SpdyProxyClientSocket::Connect(const CompletionCallback& callback) { @@ -383,17 +379,7 @@ int SpdyProxyClientSocket::DoReadReplyComplete(int result) { if (response_.headers->response_code() == 200) { return OK; } else if (response_.headers->response_code() == 407) { - int rv = HandleAuthChallenge(auth_, &response_, net_log_); - if (rv != ERR_PROXY_AUTH_REQUESTED) { - return rv; - } - // SPDY only supports basic and digest auth - if (!auth_->auth_info() || - (auth_->auth_info()->scheme != "basic" && - auth_->auth_info()->scheme != "digest")) { - return ERR_PROXY_AUTH_UNSUPPORTED; - } - return ERR_PROXY_AUTH_REQUESTED; + return ERR_TUNNEL_CONNECTION_FAILED; } else { // Immediately hand off our SpdyStream to a newly created SpdyHttpStream // so that any subsequent SpdyFrames are processed in the context of diff --git a/net/spdy/spdy_proxy_client_socket.h b/net/spdy/spdy_proxy_client_socket.h index 36d05dd..b969499 100644 --- a/net/spdy/spdy_proxy_client_socket.h +++ b/net/spdy/spdy_proxy_client_socket.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -47,15 +47,19 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, const HostPortPair& endpoint, const GURL& url, const HostPortPair& proxy_server, - HttpAuthController* auth_controller); + HttpAuthCache* auth_cache, + HttpAuthHandlerFactory* auth_handler_factory); + // On destruction Disconnect() is called. virtual ~SpdyProxyClientSocket(); + const scoped_refptr<HttpAuthController>& auth_controller() { + return auth_; + } + // ProxyClientSocket methods: virtual const HttpResponseInfo* GetConnectResponseInfo() const OVERRIDE; - virtual int RestartWithAuth(const CompletionCallback& callback) OVERRIDE; - virtual const scoped_refptr<HttpAuthController>& GetAuthController() OVERRIDE; // In the event of a non-200 response to the CONNECT request, this // method may be called to return an HttpStream in order to read diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc index 2bc939f..1357b7d 100644 --- a/net/spdy/spdy_proxy_client_socket_unittest.cc +++ b/net/spdy/spdy_proxy_client_socket_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -68,7 +68,6 @@ class SpdyProxyClientSocketTest : public PlatformTest { spdy::SpdyFrame* ConstructConnectAuthRequestFrame(); spdy::SpdyFrame* ConstructConnectReplyFrame(); spdy::SpdyFrame* ConstructConnectAuthReplyFrame(); - spdy::SpdyFrame* ConstructConnectNtlmAuthReplyFrame(); spdy::SpdyFrame* ConstructConnectErrorReplyFrame(); spdy::SpdyFrame* ConstructBodyFrame(const char* data, int length); scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size); @@ -200,12 +199,8 @@ void SpdyProxyClientSocketTest::Initialize(MockRead* reads, sock_.reset( new SpdyProxyClientSocket(spdy_stream_, user_agent_, endpoint_host_port_pair_, url_, - proxy_host_port_, - new HttpAuthController( - HttpAuth::AUTH_PROXY, - GURL(kProxyUrl), - session_->http_auth_cache(), - session_->http_auth_handler_factory()))); + proxy_host_port_, session_->http_auth_cache(), + session_->http_auth_handler_factory())); } scoped_refptr<IOBufferWithSize> SpdyProxyClientSocketTest::CreateBuffer( @@ -395,26 +390,6 @@ spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() { arraysize(kStandardReplyHeaders)); } -// Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT. -spdy::SpdyFrame* -SpdyProxyClientSocketTest::ConstructConnectNtlmAuthReplyFrame() { - const char* const kStandardReplyHeaders[] = { - "status", "407 Proxy Authentication Required", - "version", "HTTP/1.1", - "proxy-authenticate", "NTLM" - }; - - return ConstructSpdyControlFrame(NULL, - 0, - false, - kStreamId, - LOWEST, - spdy::SYN_REPLY, - spdy::CONTROL_FLAG_NONE, - kStandardReplyHeaders, - arraysize(kStandardReplyHeaders)); -} - // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error. spdy::SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() { const char* const kStandardReplyHeaders[] = { @@ -461,13 +436,13 @@ TEST_F(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) { AssertConnectionEstablished(); } -TEST_F(SpdyProxyClientSocketTest, ConnectWithUnsupportedAuthScheme) { +TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRequested) { scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, false), }; - scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectNtlmAuthReplyFrame()); + scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, true), MockRead(true, 0, 3), // EOF @@ -475,7 +450,13 @@ TEST_F(SpdyProxyClientSocketTest, ConnectWithUnsupportedAuthScheme) { Initialize(reads, arraysize(reads), writes, arraysize(writes)); - AssertConnectFails(ERR_PROXY_AUTH_UNSUPPORTED); + AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED); + + const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); + ASSERT_TRUE(response != NULL); + ASSERT_EQ(407, response->headers->response_code()); + ASSERT_EQ("Proxy Authentication Required", + response->headers->GetStatusText()); } TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) { @@ -498,39 +479,6 @@ TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) { AssertConnectionEstablished(); } -TEST_F(SpdyProxyClientSocketTest, ConnectWithAuthRestart) { - scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<spdy::SpdyFrame> auth(ConstructConnectAuthRequestFrame()); - MockWrite writes[] = { - CreateMockWrite(*conn, 0, false), - }; - - scoped_ptr<spdy::SpdyFrame> resp(ConstructConnectAuthReplyFrame()); - scoped_ptr<spdy::SpdyFrame> auth_resp(ConstructConnectReplyFrame()); - MockRead reads[] = { - CreateMockRead(*resp, 1, true), - MockRead(true, 0, 3), // EOF - }; - - Initialize(reads, arraysize(reads), writes, arraysize(writes)); - - AssertConnectFails(ERR_PROXY_AUTH_REQUESTED); - - const HttpResponseInfo* response = sock_->GetConnectResponseInfo(); - ASSERT_TRUE(response != NULL); - ASSERT_EQ(407, response->headers->response_code()); - ASSERT_EQ("Proxy Authentication Required", - response->headers->GetStatusText()); - - AddAuthToCache(); - - ASSERT_EQ(ERR_NO_KEEP_ALIVE_ON_AUTH_RESTART, - sock_->RestartWithAuth(read_callback_.callback())); - // A SpdyProxyClientSocket sits on a single SPDY stream which can - // only be used for a single request/response. - ASSERT_FALSE(sock_->IsConnectedAndIdle()); -} - TEST_F(SpdyProxyClientSocketTest, ConnectFails) { scoped_ptr<spdy::SpdyFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { @@ -883,7 +831,7 @@ TEST_F(SpdyProxyClientSocketTest, ReadAuthResponseBody) { Initialize(reads, arraysize(reads), writes, arraysize(writes)); - AssertConnectFails(ERR_PROXY_AUTH_REQUESTED); + AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED); Run(2); // SpdySession consumes the next two reads and sends then to // sock_ to be buffered. |