Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Unified Diff: net/http/http_network_transaction_unittest.cc

Issue 2382293004: [net/auth] Don't abort network transaction over non-permanent auth errors. (Closed)
Patch Set: Address comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/http/http_auth_controller_unittest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_network_transaction_unittest.cc
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index d71ac60ce810d9a05d046f4892d231c71b89958e..2391c4b77dd46957cd7ef8761a5af8b5db3709c2 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -4135,6 +4135,138 @@ TEST_F(HttpNetworkTransactionTest,
session->CloseAllConnections();
}
+// A more nuanced test than GenerateAuthToken test which asserts that
+// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
+// unnecessarily invalidated, and that if the server co-operates, the
+// authentication handshake can continue with the same scheme but with a
+// different identity.
+TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+
+ std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
+ new HttpAuthHandlerMock::Factory());
+ auth_handler_factory->set_do_init_from_challenge(true);
+
+ // First handler. Uses default credentials, but barfs at generate auth token.
+ std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
+ mock_handler->set_allows_default_credentials(true);
+ mock_handler->set_allows_explicit_credentials(true);
+ mock_handler->set_connection_based(true);
+ mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
+ auth_handler_factory->AddMockHandler(mock_handler.release(),
+ HttpAuth::AUTH_SERVER);
+
+ // Add another handler for the second challenge. It supports default
+ // credentials, but they shouldn't be used, since they were already tried.
+ mock_handler.reset(new HttpAuthHandlerMock());
+ mock_handler->set_allows_default_credentials(true);
+ mock_handler->set_allows_explicit_credentials(true);
+ mock_handler->set_connection_based(true);
+ auth_handler_factory->AddMockHandler(mock_handler.release(),
+ HttpAuth::AUTH_SERVER);
+ session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
+
+ std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
+
+ MockWrite data_writes1[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead data_reads1[] = {
+ MockRead("HTTP/1.1 401 Authentication Required\r\n"
+ "WWW-Authenticate: Mock\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ // Identical to data_writes1[]. The AuthHandler encounters a
+ // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
+ // transaction procceds without an authorization header.
+ MockWrite data_writes2[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead data_reads2[] = {
+ MockRead("HTTP/1.1 401 Authentication Required\r\n"
+ "WWW-Authenticate: Mock\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockWrite data_writes3[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n"
+ "Authorization: auth_token\r\n\r\n"),
+ };
+
+ MockRead data_reads3[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Content-Length: 5\r\n"
+ "Content-Type: text/plain\r\n"
+ "Connection: keep-alive\r\n\r\n"
+ "Hello"),
+ };
+
+ StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
+ data_writes1, arraysize(data_writes1));
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+
+ StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
+ data_writes3, arraysize(data_writes3));
+ session_deps_.socket_factory->AddSocketDataProvider(&data3);
+
+ std::unique_ptr<HttpNetworkTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+
+ // The following three tests assert that an authentication challenge was
+ // received and that the stack is ready to respond to the challenge using
+ // ambient credentials.
+ EXPECT_EQ(401, response->headers->response_code());
+ EXPECT_TRUE(trans->IsReadyToRestartForAuth());
+ EXPECT_FALSE(response->auth_challenge);
+
+ rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+
+ // The following three tests assert that an authentication challenge was
+ // received and that the stack needs explicit credentials before it is ready
+ // to respond to the challenge.
+ EXPECT_EQ(401, response->headers->response_code());
+ EXPECT_FALSE(trans->IsReadyToRestartForAuth());
+ EXPECT_TRUE(response->auth_challenge);
+
+ rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
+ EXPECT_EQ(200, response->headers->response_code());
+
+ trans.reset();
+ session->CloseAllConnections();
+}
+
// Test the load timing for HTTPS requests with an HTTP proxy.
TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
HttpRequestInfo request1;
@@ -11395,7 +11527,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
int server_auth_rv;
int num_auth_rounds;
int first_ssl_round;
- TestRound rounds[3];
+ TestRound rounds[4];
} test_configs[] = {
// Non-authenticating HTTP server with a direct connection.
{NULL,
@@ -11426,8 +11558,25 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
ERR_INVALID_AUTH_CREDENTIALS,
2,
kNoSSL,
- {TestRound(kGet, kServerChallenge, OK),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
mmenke 2016/10/10 21:06:09 Should we still have a test that hard fails here?
mmenke 2016/10/10 21:06:09 More typically, we'd see another TestRound(kGet, k
asanka 2016/10/11 19:47:26 The test fixture will need some minor tweaking, bu
+ {NULL,
+ AUTH_NONE,
+ OK,
+ kServer,
+ AUTH_SYNC,
+ ERR_UNSUPPORTED_AUTH_SCHEME,
+ 2,
+ kNoSSL,
+ {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
mmenke 2016/10/10 21:06:10 More typically, we'd see another TestRound(kGet, k
asanka 2016/10/11 19:47:26 Added another round. The new test round verifies t
+ {NULL,
+ AUTH_NONE,
+ OK,
+ kServer,
+ AUTH_SYNC,
+ ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
+ 2,
+ kNoSSL,
+ {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
{NULL,
AUTH_NONE,
OK,
@@ -11446,8 +11595,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
ERR_INVALID_AUTH_CREDENTIALS,
2,
kNoSSL,
- {TestRound(kGet, kServerChallenge, OK),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
// Non-authenticating HTTP server through a non-authenticating proxy.
{kProxy,
AUTH_NONE,
@@ -11478,8 +11626,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
2,
kNoSSL,
{TestRound(kGetProxy, kServerChallenge, OK),
- TestRound(kGetAuthThroughProxy, kFailure,
- ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGetProxy, kSuccess, OK)}},
{kProxy,
AUTH_NONE,
OK,
@@ -11499,8 +11646,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
2,
kNoSSL,
{TestRound(kGetProxy, kServerChallenge, OK),
- TestRound(kGetAuthThroughProxy, kFailure,
- ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGetProxy, kSuccess, OK)}},
// Non-authenticating HTTP server through an authenticating proxy.
{kProxy,
AUTH_SYNC,
@@ -11521,7 +11667,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
2,
kNoSSL,
{TestRound(kGetProxy, kProxyChallenge, OK),
- TestRound(kGetProxyAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGetProxy, kSuccess, OK)}},
{kProxy,
AUTH_ASYNC,
OK,
@@ -11541,7 +11687,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
2,
kNoSSL,
{TestRound(kGetProxy, kProxyChallenge, OK),
- TestRound(kGetProxyAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGetProxy, kSuccess, OK)}},
// Authenticating HTTP server through an authenticating proxy.
{kProxy,
AUTH_SYNC,
@@ -11564,8 +11710,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
kNoSSL,
{TestRound(kGetProxy, kProxyChallenge, OK),
TestRound(kGetProxyAuth, kServerChallenge, OK),
- TestRound(kGetAuthWithProxyAuth, kFailure,
- ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGetProxyAuth, kSuccess, OK)}},
{kProxy,
AUTH_ASYNC,
OK,
@@ -11587,8 +11732,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
kNoSSL,
{TestRound(kGetProxy, kProxyChallenge, OK),
TestRound(kGetProxyAuth, kServerChallenge, OK),
- TestRound(kGetAuthWithProxyAuth, kFailure,
- ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGetProxyAuth, kSuccess, OK)}},
{kProxy,
AUTH_SYNC,
OK,
@@ -11610,8 +11754,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
kNoSSL,
{TestRound(kGetProxy, kProxyChallenge, OK),
TestRound(kGetProxyAuth, kServerChallenge, OK),
- TestRound(kGetAuthWithProxyAuth, kFailure,
- ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGetProxyAuth, kSuccess, OK)}},
{kProxy,
AUTH_ASYNC,
OK,
@@ -11633,8 +11776,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
kNoSSL,
{TestRound(kGetProxy, kProxyChallenge, OK),
TestRound(kGetProxyAuth, kServerChallenge, OK),
- TestRound(kGetAuthWithProxyAuth, kFailure,
- ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGetProxyAuth, kSuccess, OK)}},
// Non-authenticating HTTPS server with a direct connection.
{NULL,
AUTH_NONE,
@@ -11664,8 +11806,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
ERR_INVALID_AUTH_CREDENTIALS,
2,
0,
- {TestRound(kGet, kServerChallenge, OK),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
{NULL,
AUTH_NONE,
OK,
@@ -11684,8 +11825,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
ERR_INVALID_AUTH_CREDENTIALS,
2,
0,
- {TestRound(kGet, kServerChallenge, OK),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
// Non-authenticating HTTPS server with a non-authenticating proxy.
{kProxy,
AUTH_NONE,
@@ -11716,7 +11856,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
2,
0,
{TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGet, kSuccess, OK)}},
{kProxy,
AUTH_NONE,
OK,
@@ -11736,7 +11876,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
2,
0,
{TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGet, kSuccess, OK)}},
// Non-Authenticating HTTPS server through an authenticating proxy.
{kProxy,
AUTH_SYNC,
@@ -11757,7 +11897,27 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
2,
kNoSSL,
{TestRound(kConnect, kProxyChallenge, OK),
- TestRound(kConnectProxyAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
+ {kProxy,
+ AUTH_SYNC,
+ ERR_UNSUPPORTED_AUTH_SCHEME,
+ kSecureServer,
+ AUTH_NONE,
+ OK,
+ 2,
+ kNoSSL,
+ {TestRound(kConnect, kProxyChallenge, OK),
+ TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
+ {kProxy,
+ AUTH_SYNC,
+ ERR_UNEXPECTED,
+ kSecureServer,
+ AUTH_NONE,
+ OK,
+ 2,
+ kNoSSL,
+ {TestRound(kConnect, kProxyChallenge, OK),
+ TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
{kProxy,
AUTH_ASYNC,
OK,
@@ -11777,7 +11937,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
2,
kNoSSL,
{TestRound(kConnect, kProxyChallenge, OK),
- TestRound(kConnectProxyAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
// Authenticating HTTPS server through an authenticating proxy.
{kProxy,
AUTH_SYNC,
@@ -11802,7 +11962,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
{TestRound(kConnect, kProxyChallenge, OK),
TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
&kServerChallenge),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGet, kSuccess, OK)}},
{kProxy,
AUTH_ASYNC,
OK,
@@ -11826,7 +11986,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
{TestRound(kConnect, kProxyChallenge, OK),
TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
&kServerChallenge),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGet, kSuccess, OK)}},
{kProxy,
AUTH_SYNC,
OK,
@@ -11850,7 +12010,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
{TestRound(kConnect, kProxyChallenge, OK),
TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
&kServerChallenge),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGet, kSuccess, OK)}},
{kProxy,
AUTH_ASYNC,
OK,
@@ -11874,10 +12034,11 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
{TestRound(kConnect, kProxyChallenge, OK),
TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
&kServerChallenge),
- TestRound(kGetAuth, kFailure, ERR_INVALID_AUTH_CREDENTIALS)}},
+ TestRound(kGet, kSuccess, OK)}},
};
for (size_t i = 0; i < arraysize(test_configs); ++i) {
+ SCOPED_TRACE(::testing::Message() << "Test config " << i);
HttpAuthHandlerMock::Factory* auth_factory(
new HttpAuthHandlerMock::Factory());
session_deps_.http_auth_handler_factory.reset(auth_factory);
« no previous file with comments | « net/http/http_auth_controller_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698