diff options
author | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-05 18:31:10 +0000 |
---|---|---|
committer | cbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-05 18:31:10 +0000 |
commit | 7a67a81536b664eb4145731ec1e97bf2f7990e30 (patch) | |
tree | e7d5803190242329087b3860e28f4b3acdcad31c | |
parent | 264a93a2732e4b7f18c770b3016941368c2e9b3c (diff) | |
download | chromium_src-7a67a81536b664eb4145731ec1e97bf2f7990e30.zip chromium_src-7a67a81536b664eb4145731ec1e97bf2f7990e30.tar.gz chromium_src-7a67a81536b664eb4145731ec1e97bf2f7990e30.tar.bz2 |
Crash fix: HTTPS server responds with 407 through non-authenticating proxy.
Now, HttpNetworkTransaction::HandleAuthChallenge returns ERR_INVALID_PROXY_AUTHENTICATE when this is detected.
BUG=61701
TEST=net_unittests --gtest_filter="*HttpsServerRequestsProxyAuthThroughProxy*"
Review URL: http://codereview.chromium.org/4575001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65225 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/http/http_network_transaction.cc | 5 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 60 |
2 files changed, 65 insertions, 0 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index de9529e..bc2d322 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -1089,6 +1089,11 @@ int HttpNetworkTransaction::HandleAuthChallenge() { if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) return ERR_UNEXPECTED_PROXY_AUTH; + // This case can trigger when an HTTPS server responds with a 407 status + // code through a non-authenticating proxy. + if (!auth_controllers_[target].get()) + return ERR_UNEXPECTED_PROXY_AUTH; + int rv = auth_controllers_[target]->HandleAuthChallenge( headers, (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, false, net_log_); diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 0ba698c..b060d7c 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -1768,6 +1768,66 @@ TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) { EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); } +// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication) +// through a non-authenticating proxy. The request should fail with +// ERR_UNEXPECTED_PROXY_AUTH. +// Note that it is impossible to detect if an HTTP server returns a 407 through +// a non-authenticating proxy - there is nothing to indicate whether the +// response came from the proxy or the server, so it is treated as if the proxy +// issued the challenge. +TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) { + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); + CapturingBoundNetLog log(CapturingNetLog::kUnbounded); + session_deps.net_log = log.bound().net_log(); + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.google.com/"); + + // 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("GET / HTTP/1.1\r\n" + "Host: www.google.com\r\n" + "Connection: keep-alive\r\n\r\n"), + }; + + MockRead data_reads1[] = { + MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), + + MockRead("HTTP/1.1 407 Unauthorized\r\n"), + MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), + MockRead("\r\n"), + MockRead(false, OK), + }; + + StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), + data_writes1, arraysize(data_writes1)); + session_deps.socket_factory.AddSocketDataProvider(&data1); + SSLSocketDataProvider ssl(true, OK); + session_deps.socket_factory.AddSSLSocketDataProvider(&ssl); + + TestCompletionCallback callback1; + + scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); + + int rv = trans->Start(&request, &callback1, log.bound()); + EXPECT_EQ(ERR_IO_PENDING, rv); + + rv = callback1.WaitForResult(); + EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); + size_t pos = ExpectLogContainsSomewhere( + log.entries(), 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS, + NetLog::PHASE_NONE); + ExpectLogContainsSomewhere( + log.entries(), pos, + NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, + NetLog::PHASE_NONE); +} // Test a simple get through an HTTPS Proxy. TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) { |