summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/http/http_network_transaction.cc25
-rw-r--r--net/http/http_network_transaction.h4
-rw-r--r--net/http/http_network_transaction_unittest.cc40
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".