diff options
Diffstat (limited to 'net')
20 files changed, 163 insertions, 940 deletions
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. |