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

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: Created 4 years, 3 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
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 12b5f253267dd8f698cd7a6751f0a36a9e935754..b9dccb147438a4cdf34f1ccdfee34df77dbe1321 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -4134,6 +4134,127 @@ 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.
mmenke 2016/10/04 19:42:15 So default credentials for all different handlers
asanka 2016/10/06 14:16:35 These are auth handlers for the same scheme. The s
+ 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"),
+ };
+
+ MockWrite data_writes2[] = {
mmenke 2016/10/04 19:42:15 The first auth handler tries to generate credentia
asanka 2016/10/06 14:16:35 Done.
+ 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"),
mmenke 2016/10/04 19:42:15 What would happen differently if it tried default
asanka 2016/10/06 14:16:35 The type of credentials being used is checked by t
+ };
+
+ 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_EQ(401, response->headers->response_code());
+ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ 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);
+ 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;
@@ -11390,7 +11511,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,
@@ -11421,8 +11542,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)}},
+ {NULL,
+ AUTH_NONE,
+ OK,
+ kServer,
+ AUTH_SYNC,
+ ERR_UNSUPPORTED_AUTH_SCHEME,
+ 2,
+ kNoSSL,
+ {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka 2016/09/30 22:57:11 The implication here is a bit subtle. What we are
+ {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,
@@ -11441,8 +11579,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)}},
asanka 2016/09/30 22:57:11 Note that here and elsewhere, the old test round l
// Non-authenticating HTTP server through a non-authenticating proxy.
{kProxy,
AUTH_NONE,
@@ -11473,8 +11610,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,
@@ -11494,8 +11630,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,
@@ -11516,7 +11651,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,
@@ -11536,7 +11671,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,
@@ -11559,8 +11694,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,
@@ -11582,8 +11716,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,
@@ -11605,8 +11738,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,
@@ -11628,8 +11760,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,
@@ -11659,8 +11790,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,
@@ -11679,8 +11809,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,
@@ -11711,7 +11840,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,
@@ -11731,7 +11860,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,
@@ -11752,7 +11881,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,
@@ -11772,7 +11921,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,
@@ -11797,7 +11946,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,
@@ -11821,7 +11970,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,
@@ -11845,7 +11994,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,
@@ -11869,10 +12018,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);
« net/http/http_auth_controller_unittest.cc ('K') | « 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