summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-06 11:19:10 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-06 11:19:10 +0000
commit7ef4cbbb55e58e43e7edcf358a9fb689673d39a9 (patch)
tree38662d2db7022c893fac7dd2ab3dd1fbb77e64b4 /net
parent3d16481bffe60e1c49d59a64cdab48fd69bc50a4 (diff)
downloadchromium_src-7ef4cbbb55e58e43e7edcf358a9fb689673d39a9.zip
chromium_src-7ef4cbbb55e58e43e7edcf358a9fb689673d39a9.tar.gz
chromium_src-7ef4cbbb55e58e43e7edcf358a9fb689673d39a9.tar.bz2
Test that the same socket is used for each round of connection-based auth.
NTLM and Negotiate were broken in beta builds around M6/M7 since the socket was released back to the general socket pool. A competing request would then grab it, but the server would expect another round of authentication on the same socket and authentication would break. BUG=58770 TEST=net_unittests --gtest_filter="*MultiRoundAuth" Review URL: http://codereview.chromium.org/6349108 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73953 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_network_transaction_unittest.cc74
1 files changed, 69 insertions, 5 deletions
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 66ab6d4..8ac2a6e 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -7404,6 +7404,21 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
request.load_flags = 0;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+
+ // Use a TCP Socket Pool with only one connection per group. This is used
+ // to validate that the TCP socket is not released to the pool between
+ // each round of multi-round authentication.
+ HttpNetworkSessionPeer session_peer(session);
+ ClientSocketPoolHistograms tcp_pool_histograms("SmallTCP");
+ TCPClientSocketPool* tcp_pool = new TCPClientSocketPool(
+ 50, // Max sockets for pool
+ 1, // Max sockets per group
+ &tcp_pool_histograms,
+ session_deps.host_resolver.get(),
+ &session_deps.socket_factory,
+ session_deps.net_log);
+ session_peer.SetTCPSocketPool(tcp_pool);
+
scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
TestCompletionCallback callback;
@@ -7437,7 +7452,9 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
// Third round
kGetAuth,
// Fourth round
- kGetAuth
+ kGetAuth,
+ // Competing request
+ kGet,
};
MockRead reads[] = {
// First round
@@ -7448,12 +7465,16 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
kServerChallenge,
// Fourth round
kSuccess,
+ // Competing response
+ kSuccess,
};
StaticSocketDataProvider data_provider(reads, arraysize(reads),
writes, arraysize(writes));
session_deps.socket_factory.AddSocketDataProvider(&data_provider);
- // First round
+ const char* const kSocketGroup = "www.example.com:80";
+
+ // First round of authentication.
auth_handler->SetGenerateExpectation(false, OK);
rv = trans->Start(&request, &callback, BoundNetLog());
if (rv == ERR_IO_PENDING)
@@ -7462,8 +7483,21 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
response = trans->GetResponseInfo();
ASSERT_FALSE(response == NULL);
EXPECT_FALSE(response->auth_challenge.get() == NULL);
+ EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+
+ // In between rounds, another request comes in for the same domain.
+ // It should not be able to grab the TCP socket that trans has already
+ // claimed.
+ scoped_ptr<HttpTransaction> trans_compete(
+ new HttpNetworkTransaction(session));
+ TestCompletionCallback callback_compete;
+ rv = trans_compete->Start(&request, &callback_compete, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ // callback_compete.WaitForResult at this point would stall forever,
+ // since the HttpNetworkTransaction does not release the request back to
+ // the pool until after authentication completes.
- // Second round
+ // Second round of authentication.
auth_handler->SetGenerateExpectation(false, OK);
rv = trans->RestartWithAuth(kFoo, kBar, &callback);
if (rv == ERR_IO_PENDING)
@@ -7472,8 +7506,9 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
response = trans->GetResponseInfo();
ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
+ EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
- // Third round
+ // Third round of authentication.
auth_handler->SetGenerateExpectation(false, OK);
rv = trans->RestartWithAuth(string16(), string16(), &callback);
if (rv == ERR_IO_PENDING)
@@ -7482,8 +7517,9 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
response = trans->GetResponseInfo();
ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
+ EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
- // Fourth round
+ // Fourth round of authentication, which completes successfully.
auth_handler->SetGenerateExpectation(false, OK);
rv = trans->RestartWithAuth(string16(), string16(), &callback);
if (rv == ERR_IO_PENDING)
@@ -7492,6 +7528,34 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
response = trans->GetResponseInfo();
ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
+ EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+
+ // Read the body since the fourth round was successful. This will also
+ // release the socket back to the pool.
+ scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
+ rv = trans->Read(io_buf, io_buf->size(), &callback);
+ if (rv == ERR_IO_PENDING)
+ rv = callback.WaitForResult();
+ EXPECT_EQ(3, rv);
+ rv = trans->Read(io_buf, io_buf->size(), &callback);
+ EXPECT_EQ(0, rv);
+ // There are still 0 idle sockets, since the trans_compete transaction
+ // will be handed it immediately after trans releases it to the group.
+ EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+
+ // The competing request can now finish. Wait for the headers and then
+ // read the body.
+ rv = callback_compete.WaitForResult();
+ EXPECT_EQ(OK, rv);
+ rv = trans_compete->Read(io_buf, io_buf->size(), &callback);
+ if (rv == ERR_IO_PENDING)
+ rv = callback.WaitForResult();
+ EXPECT_EQ(3, rv);
+ rv = trans_compete->Read(io_buf, io_buf->size(), &callback);
+ EXPECT_EQ(0, rv);
+
+ // Finally, the socket is released to the group.
+ EXPECT_EQ(1, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
}
class TLSDecompressionFailureSocketDataProvider : public SocketDataProvider {