diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/http/http_network_transaction.cc | 25 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 4 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 40 |
3 files changed, 65 insertions, 4 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index b0a6ac9..d0edafa 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -1727,9 +1727,25 @@ void HttpNetworkTransaction::AddAuthorizationHeader( } GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const { - return target == HttpAuth::AUTH_PROXY ? - GURL("http://" + proxy_info_.proxy_server().host_and_port()) : - request_->url.GetOrigin(); + GURL origin = PossiblyInvalidAuthOrigin(target); + DCHECK(origin.is_valid()); + return origin; +} + +GURL HttpNetworkTransaction::PossiblyInvalidAuthOrigin( + HttpAuth::Target target) const { + switch (target) { + case HttpAuth::AUTH_PROXY: + if (!proxy_info_.proxy_server().is_valid() || + proxy_info_.proxy_server().is_direct()) { + return GURL(); // There is no proxy server. + } + return GURL("http://" + proxy_info_.proxy_server().host_and_port()); + case HttpAuth::AUTH_SERVER: + return request_->url.GetOrigin(); + default: + return GURL(); + } } std::string HttpNetworkTransaction::AuthPath(HttpAuth::Target target) @@ -1903,7 +1919,7 @@ int HttpNetworkTransaction::HandleAuthChallenge() { return OK; HttpAuth::Target target = status == 407 ? HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; - GURL auth_origin = AuthOrigin(target); + GURL auth_origin = PossiblyInvalidAuthOrigin(target); LOG(INFO) << "The " << AuthTargetString(target) << " " << auth_origin << " requested auth" @@ -1911,6 +1927,7 @@ int HttpNetworkTransaction::HandleAuthChallenge() { if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) return ERR_UNEXPECTED_PROXY_AUTH; + DCHECK(auth_origin.is_valid()); // The auth we tried just failed, hence it can't be valid. Remove it from // the cache so it won't be used again. diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 3217fac..7b033e3 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -258,6 +258,10 @@ class HttpNetworkTransaction : public HttpTransaction { // Get the {scheme, host, port} for the authentication target GURL AuthOrigin(HttpAuth::Target target) const; + // Same as AuthOrigin(), but will return an invalid GURL if the target is + // invalid. + GURL PossiblyInvalidAuthOrigin(HttpAuth::Target target) const; + // Get the absolute path of the resource needing authentication. // For proxy authentication the path is always empty string. std::string AuthPath(HttpAuth::Target target) const; diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 8f0528a..5b6a9b8 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -1379,6 +1379,46 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv); } +// Test when a server (non-proxy) returns a 407 (proxy-authenticate). +// The request should fail with ERR_UNEXPECTED_PROXY_AUTH. +TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) { + // We are using a DIRECT connection (i.e. no proxy) for this session. + SessionDependencies session_deps; + scoped_ptr<HttpTransaction> trans( + new HttpNetworkTransaction(CreateSession(&session_deps))); + + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("http://www.google.com/"); + request.load_flags = 0; + + MockWrite data_writes1[] = { + 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.0 407 Proxy Auth required\r\n"), + MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"), + // Large content-length -- won't matter, as connection will be reset. + MockRead("Content-Length: 10000\r\n\r\n"), + MockRead(false, ERR_FAILED), + }; + + StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), + data_writes1, arraysize(data_writes1)); + session_deps.socket_factory.AddSocketDataProvider(&data1); + + TestCompletionCallback callback; + + int rv = trans->Start(&request, &callback, BoundNetLog()); + EXPECT_EQ(ERR_IO_PENDING, rv); + + rv = callback.WaitForResult(); + EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv); +} + void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( const MockRead& status, int expected_status) { // Configure against proxy server "myproxy:70". |