| Index: net/http/http_network_transaction_unittest.cc
|
| ===================================================================
|
| --- net/http/http_network_transaction_unittest.cc (revision 28069)
|
| +++ net/http/http_network_transaction_unittest.cc (working copy)
|
| @@ -1494,6 +1494,10 @@
|
| EXPECT_EQ(100, response->headers->GetContentLength());
|
| }
|
|
|
| +// For the NTLM implementation using SSPI, we skip the NTLM tests since we
|
| +// can't hook into its internals to cause it to generate predictable NTLM
|
| +// authorization headers.
|
| +#if defined(NTLM_PORTABLE)
|
| // The NTLM authentication unit tests were generated by capturing the HTTP
|
| // requests and responses using Fiddler 2 and inspecting the generated random
|
| // bytes in the debugger.
|
| @@ -1822,6 +1826,7 @@
|
| EXPECT_TRUE(response->auth_challenge.get() == NULL);
|
| EXPECT_EQ(13, response->headers->GetContentLength());
|
| }
|
| +#endif // NTLM_PORTABLE
|
|
|
| // Test reading a server response which has only headers, and no body.
|
| // After some maximum number of bytes is consumed, the transaction should
|
| @@ -2125,7 +2130,7 @@
|
| // Test the request-challenge-retry sequence for basic auth when there is
|
| // an identity in the URL. The request should be sent as normal, but when
|
| // it fails the identity from the URL is used to answer the challenge.
|
| -TEST_F(HttpNetworkTransactionTest, AuthIdentityInUrl) {
|
| +TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
|
| SessionDependencies session_deps;
|
| scoped_ptr<HttpTransaction> trans(
|
| new HttpNetworkTransaction(
|
| @@ -2199,6 +2204,119 @@
|
| MessageLoop::current()->RunAllPending();
|
| }
|
|
|
| +// Test the request-challenge-retry sequence for basic auth when there is
|
| +// an incorrect identity in the URL. The identity from the URL should be used
|
| +// only once.
|
| +TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
|
| + SessionDependencies session_deps;
|
| + scoped_ptr<HttpTransaction> trans(
|
| + new HttpNetworkTransaction(
|
| + CreateSession(&session_deps),
|
| + &session_deps.socket_factory));
|
| +
|
| + HttpRequestInfo request;
|
| + request.method = "GET";
|
| + // Note: the URL has a username:password in it. The password "baz" is
|
| + // wrong (should be "bar").
|
| + request.url = GURL("http://foo:baz@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 401 Unauthorized\r\n"),
|
| + MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
|
| + MockRead("Content-Length: 10\r\n\r\n"),
|
| + MockRead(false, ERR_FAILED),
|
| + };
|
| +
|
| + // After the challenge above, the transaction will be restarted using the
|
| + // identity from the url (foo, baz) to answer the challenge.
|
| + MockWrite data_writes2[] = {
|
| + MockWrite("GET / HTTP/1.1\r\n"
|
| + "Host: www.google.com\r\n"
|
| + "Connection: keep-alive\r\n"
|
| + "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
|
| + };
|
| +
|
| + MockRead data_reads2[] = {
|
| + MockRead("HTTP/1.0 401 Unauthorized\r\n"),
|
| + MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
|
| + MockRead("Content-Length: 10\r\n\r\n"),
|
| + MockRead(false, ERR_FAILED),
|
| + };
|
| +
|
| + // After the challenge above, the transaction will be restarted using the
|
| + // identity supplied by the user (foo, bar) to answer the challenge.
|
| + MockWrite data_writes3[] = {
|
| + MockWrite("GET / HTTP/1.1\r\n"
|
| + "Host: www.google.com\r\n"
|
| + "Connection: keep-alive\r\n"
|
| + "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
|
| + };
|
| +
|
| + MockRead data_reads3[] = {
|
| + MockRead("HTTP/1.0 200 OK\r\n"),
|
| + MockRead("Content-Length: 100\r\n\r\n"),
|
| + MockRead(false, OK),
|
| + };
|
| +
|
| + StaticMockSocket data1(data_reads1, data_writes1);
|
| + StaticMockSocket data2(data_reads2, data_writes2);
|
| + StaticMockSocket data3(data_reads3, data_writes3);
|
| + session_deps.socket_factory.AddMockSocket(&data1);
|
| + session_deps.socket_factory.AddMockSocket(&data2);
|
| + session_deps.socket_factory.AddMockSocket(&data3);
|
| +
|
| + TestCompletionCallback callback1;
|
| +
|
| + int rv = trans->Start(&request, &callback1);
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| +
|
| + rv = callback1.WaitForResult();
|
| + EXPECT_EQ(OK, rv);
|
| +
|
| + EXPECT_TRUE(trans->IsReadyToRestartForAuth());
|
| + TestCompletionCallback callback2;
|
| + rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + rv = callback2.WaitForResult();
|
| + EXPECT_EQ(OK, rv);
|
| + EXPECT_FALSE(trans->IsReadyToRestartForAuth());
|
| +
|
| + const HttpResponseInfo* response = trans->GetResponseInfo();
|
| + EXPECT_FALSE(response == NULL);
|
| + // The password prompt info should have been set in response->auth_challenge.
|
| + EXPECT_FALSE(response->auth_challenge.get() == NULL);
|
| +
|
| + EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
|
| + EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
|
| + EXPECT_EQ(L"basic", response->auth_challenge->scheme);
|
| +
|
| + TestCompletionCallback callback3;
|
| + rv = trans->RestartWithAuth(L"foo", L"bar", &callback3);
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + rv = callback3.WaitForResult();
|
| + EXPECT_EQ(OK, rv);
|
| + EXPECT_FALSE(trans->IsReadyToRestartForAuth());
|
| +
|
| + response = trans->GetResponseInfo();
|
| + EXPECT_FALSE(response == NULL);
|
| +
|
| + // There is no challenge info, since the identity worked.
|
| + EXPECT_TRUE(response->auth_challenge.get() == NULL);
|
| +
|
| + EXPECT_EQ(100, response->headers->GetContentLength());
|
| +
|
| + // Empty the current queue.
|
| + MessageLoop::current()->RunAllPending();
|
| +}
|
| +
|
| // Test that previously tried username/passwords for a realm get re-used.
|
| TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
|
| SessionDependencies session_deps;
|
|
|