| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <math.h> // ceil | 5 #include <math.h> // ceil |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "net/base/completion_callback.h" | 8 #include "net/base/completion_callback.h" |
| 9 #include "net/base/mock_host_resolver.h" | 9 #include "net/base/mock_host_resolver.h" |
| 10 #include "net/base/ssl_config_service_defaults.h" | 10 #include "net/base/ssl_config_service_defaults.h" |
| (...skipping 1483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1494 EXPECT_EQ(ERR_IO_PENDING, rv); | 1494 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1495 | 1495 |
| 1496 rv = callback3.WaitForResult(); | 1496 rv = callback3.WaitForResult(); |
| 1497 EXPECT_EQ(OK, rv); | 1497 EXPECT_EQ(OK, rv); |
| 1498 | 1498 |
| 1499 response = trans->GetResponseInfo(); | 1499 response = trans->GetResponseInfo(); |
| 1500 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 1500 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1501 EXPECT_EQ(100, response->headers->GetContentLength()); | 1501 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 1502 } | 1502 } |
| 1503 | 1503 |
| 1504 // For the NTLM implementation using SSPI, we skip the NTLM tests since we |
| 1505 // can't hook into its internals to cause it to generate predictable NTLM |
| 1506 // authorization headers. |
| 1507 #if defined(NTLM_PORTABLE) |
| 1504 // The NTLM authentication unit tests were generated by capturing the HTTP | 1508 // The NTLM authentication unit tests were generated by capturing the HTTP |
| 1505 // requests and responses using Fiddler 2 and inspecting the generated random | 1509 // requests and responses using Fiddler 2 and inspecting the generated random |
| 1506 // bytes in the debugger. | 1510 // bytes in the debugger. |
| 1507 | 1511 |
| 1508 // Enter the correct password and authenticate successfully. | 1512 // Enter the correct password and authenticate successfully. |
| 1509 TEST_F(HttpNetworkTransactionTest, NTLMAuth1) { | 1513 TEST_F(HttpNetworkTransactionTest, NTLMAuth1) { |
| 1510 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, | 1514 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1, |
| 1511 MockGetHostName); | 1515 MockGetHostName); |
| 1512 SessionDependencies session_deps; | 1516 SessionDependencies session_deps; |
| 1513 scoped_ptr<HttpTransaction> trans( | 1517 scoped_ptr<HttpTransaction> trans( |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1822 rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback5); | 1826 rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback5); |
| 1823 EXPECT_EQ(ERR_IO_PENDING, rv); | 1827 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1824 | 1828 |
| 1825 rv = callback5.WaitForResult(); | 1829 rv = callback5.WaitForResult(); |
| 1826 EXPECT_EQ(OK, rv); | 1830 EXPECT_EQ(OK, rv); |
| 1827 | 1831 |
| 1828 response = trans->GetResponseInfo(); | 1832 response = trans->GetResponseInfo(); |
| 1829 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 1833 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 1830 EXPECT_EQ(13, response->headers->GetContentLength()); | 1834 EXPECT_EQ(13, response->headers->GetContentLength()); |
| 1831 } | 1835 } |
| 1836 #endif // NTLM_PORTABLE |
| 1832 | 1837 |
| 1833 // Test reading a server response which has only headers, and no body. | 1838 // Test reading a server response which has only headers, and no body. |
| 1834 // After some maximum number of bytes is consumed, the transaction should | 1839 // After some maximum number of bytes is consumed, the transaction should |
| 1835 // fail with ERR_RESPONSE_HEADERS_TOO_BIG. | 1840 // fail with ERR_RESPONSE_HEADERS_TOO_BIG. |
| 1836 TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) { | 1841 TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) { |
| 1837 SessionDependencies session_deps; | 1842 SessionDependencies session_deps; |
| 1838 scoped_ptr<HttpTransaction> trans( | 1843 scoped_ptr<HttpTransaction> trans( |
| 1839 new HttpNetworkTransaction( | 1844 new HttpNetworkTransaction( |
| 1840 CreateSession(&session_deps), | 1845 CreateSession(&session_deps), |
| 1841 &session_deps.socket_factory)); | 1846 &session_deps.socket_factory)); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2125 std::string response_data; | 2130 std::string response_data; |
| 2126 rv = ReadTransaction(trans.get(), &response_data); | 2131 rv = ReadTransaction(trans.get(), &response_data); |
| 2127 EXPECT_EQ(OK, rv); | 2132 EXPECT_EQ(OK, rv); |
| 2128 EXPECT_EQ(kExpectedResponseData[i], response_data); | 2133 EXPECT_EQ(kExpectedResponseData[i], response_data); |
| 2129 } | 2134 } |
| 2130 } | 2135 } |
| 2131 | 2136 |
| 2132 // Test the request-challenge-retry sequence for basic auth when there is | 2137 // Test the request-challenge-retry sequence for basic auth when there is |
| 2133 // an identity in the URL. The request should be sent as normal, but when | 2138 // an identity in the URL. The request should be sent as normal, but when |
| 2134 // it fails the identity from the URL is used to answer the challenge. | 2139 // it fails the identity from the URL is used to answer the challenge. |
| 2135 TEST_F(HttpNetworkTransactionTest, AuthIdentityInUrl) { | 2140 TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) { |
| 2136 SessionDependencies session_deps; | 2141 SessionDependencies session_deps; |
| 2137 scoped_ptr<HttpTransaction> trans( | 2142 scoped_ptr<HttpTransaction> trans( |
| 2138 new HttpNetworkTransaction( | 2143 new HttpNetworkTransaction( |
| 2139 CreateSession(&session_deps), | 2144 CreateSession(&session_deps), |
| 2140 &session_deps.socket_factory)); | 2145 &session_deps.socket_factory)); |
| 2141 | 2146 |
| 2142 HttpRequestInfo request; | 2147 HttpRequestInfo request; |
| 2143 request.method = "GET"; | 2148 request.method = "GET"; |
| 2144 // Note: the URL has a username:password in it. | 2149 // Note: the URL has a username:password in it. |
| 2145 request.url = GURL("http://foo:b@r@www.google.com/"); | 2150 request.url = GURL("http://foo:b@r@www.google.com/"); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2157 }; | 2162 }; |
| 2158 | 2163 |
| 2159 MockRead data_reads1[] = { | 2164 MockRead data_reads1[] = { |
| 2160 MockRead("HTTP/1.0 401 Unauthorized\r\n"), | 2165 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2161 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), | 2166 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 2162 MockRead("Content-Length: 10\r\n\r\n"), | 2167 MockRead("Content-Length: 10\r\n\r\n"), |
| 2163 MockRead(false, ERR_FAILED), | 2168 MockRead(false, ERR_FAILED), |
| 2164 }; | 2169 }; |
| 2165 | 2170 |
| 2166 // After the challenge above, the transaction will be restarted using the | 2171 // After the challenge above, the transaction will be restarted using the |
| 2167 // identity from the url (foo, bar) to answer the challenge. | 2172 // identity from the url (foo, b@r) to answer the challenge. |
| 2168 MockWrite data_writes2[] = { | 2173 MockWrite data_writes2[] = { |
| 2169 MockWrite("GET / HTTP/1.1\r\n" | 2174 MockWrite("GET / HTTP/1.1\r\n" |
| 2170 "Host: www.google.com\r\n" | 2175 "Host: www.google.com\r\n" |
| 2171 "Connection: keep-alive\r\n" | 2176 "Connection: keep-alive\r\n" |
| 2172 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"), | 2177 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"), |
| 2173 }; | 2178 }; |
| 2174 | 2179 |
| 2175 MockRead data_reads2[] = { | 2180 MockRead data_reads2[] = { |
| 2176 MockRead("HTTP/1.0 200 OK\r\n"), | 2181 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2177 MockRead("Content-Length: 100\r\n\r\n"), | 2182 MockRead("Content-Length: 100\r\n\r\n"), |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2204 | 2209 |
| 2205 // There is no challenge info, since the identity in URL worked. | 2210 // There is no challenge info, since the identity in URL worked. |
| 2206 EXPECT_TRUE(response->auth_challenge.get() == NULL); | 2211 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2207 | 2212 |
| 2208 EXPECT_EQ(100, response->headers->GetContentLength()); | 2213 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 2209 | 2214 |
| 2210 // Empty the current queue. | 2215 // Empty the current queue. |
| 2211 MessageLoop::current()->RunAllPending(); | 2216 MessageLoop::current()->RunAllPending(); |
| 2212 } | 2217 } |
| 2213 | 2218 |
| 2219 // Test the request-challenge-retry sequence for basic auth when there is |
| 2220 // an incorrect identity in the URL. The identity from the URL should be used |
| 2221 // only once. |
| 2222 TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) { |
| 2223 SessionDependencies session_deps; |
| 2224 scoped_ptr<HttpTransaction> trans( |
| 2225 new HttpNetworkTransaction( |
| 2226 CreateSession(&session_deps), |
| 2227 &session_deps.socket_factory)); |
| 2228 |
| 2229 HttpRequestInfo request; |
| 2230 request.method = "GET"; |
| 2231 // Note: the URL has a username:password in it. The password "baz" is |
| 2232 // wrong (should be "bar"). |
| 2233 request.url = GURL("http://foo:baz@www.google.com/"); |
| 2234 |
| 2235 request.load_flags = 0; |
| 2236 |
| 2237 MockWrite data_writes1[] = { |
| 2238 MockWrite("GET / HTTP/1.1\r\n" |
| 2239 "Host: www.google.com\r\n" |
| 2240 "Connection: keep-alive\r\n\r\n"), |
| 2241 }; |
| 2242 |
| 2243 MockRead data_reads1[] = { |
| 2244 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2245 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 2246 MockRead("Content-Length: 10\r\n\r\n"), |
| 2247 MockRead(false, ERR_FAILED), |
| 2248 }; |
| 2249 |
| 2250 // After the challenge above, the transaction will be restarted using the |
| 2251 // identity from the url (foo, baz) to answer the challenge. |
| 2252 MockWrite data_writes2[] = { |
| 2253 MockWrite("GET / HTTP/1.1\r\n" |
| 2254 "Host: www.google.com\r\n" |
| 2255 "Connection: keep-alive\r\n" |
| 2256 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"), |
| 2257 }; |
| 2258 |
| 2259 MockRead data_reads2[] = { |
| 2260 MockRead("HTTP/1.0 401 Unauthorized\r\n"), |
| 2261 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"), |
| 2262 MockRead("Content-Length: 10\r\n\r\n"), |
| 2263 MockRead(false, ERR_FAILED), |
| 2264 }; |
| 2265 |
| 2266 // After the challenge above, the transaction will be restarted using the |
| 2267 // identity supplied by the user (foo, bar) to answer the challenge. |
| 2268 MockWrite data_writes3[] = { |
| 2269 MockWrite("GET / HTTP/1.1\r\n" |
| 2270 "Host: www.google.com\r\n" |
| 2271 "Connection: keep-alive\r\n" |
| 2272 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), |
| 2273 }; |
| 2274 |
| 2275 MockRead data_reads3[] = { |
| 2276 MockRead("HTTP/1.0 200 OK\r\n"), |
| 2277 MockRead("Content-Length: 100\r\n\r\n"), |
| 2278 MockRead(false, OK), |
| 2279 }; |
| 2280 |
| 2281 StaticMockSocket data1(data_reads1, data_writes1); |
| 2282 StaticMockSocket data2(data_reads2, data_writes2); |
| 2283 StaticMockSocket data3(data_reads3, data_writes3); |
| 2284 session_deps.socket_factory.AddMockSocket(&data1); |
| 2285 session_deps.socket_factory.AddMockSocket(&data2); |
| 2286 session_deps.socket_factory.AddMockSocket(&data3); |
| 2287 |
| 2288 TestCompletionCallback callback1; |
| 2289 |
| 2290 int rv = trans->Start(&request, &callback1, NULL); |
| 2291 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2292 |
| 2293 rv = callback1.WaitForResult(); |
| 2294 EXPECT_EQ(OK, rv); |
| 2295 |
| 2296 EXPECT_TRUE(trans->IsReadyToRestartForAuth()); |
| 2297 TestCompletionCallback callback2; |
| 2298 rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2); |
| 2299 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2300 rv = callback2.WaitForResult(); |
| 2301 EXPECT_EQ(OK, rv); |
| 2302 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 2303 |
| 2304 const HttpResponseInfo* response = trans->GetResponseInfo(); |
| 2305 EXPECT_FALSE(response == NULL); |
| 2306 // The password prompt info should have been set in response->auth_challenge. |
| 2307 EXPECT_FALSE(response->auth_challenge.get() == NULL); |
| 2308 |
| 2309 EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port); |
| 2310 EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm); |
| 2311 EXPECT_EQ(L"basic", response->auth_challenge->scheme); |
| 2312 |
| 2313 TestCompletionCallback callback3; |
| 2314 rv = trans->RestartWithAuth(L"foo", L"bar", &callback3); |
| 2315 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 2316 rv = callback3.WaitForResult(); |
| 2317 EXPECT_EQ(OK, rv); |
| 2318 EXPECT_FALSE(trans->IsReadyToRestartForAuth()); |
| 2319 |
| 2320 response = trans->GetResponseInfo(); |
| 2321 EXPECT_FALSE(response == NULL); |
| 2322 |
| 2323 // There is no challenge info, since the identity worked. |
| 2324 EXPECT_TRUE(response->auth_challenge.get() == NULL); |
| 2325 |
| 2326 EXPECT_EQ(100, response->headers->GetContentLength()); |
| 2327 |
| 2328 // Empty the current queue. |
| 2329 MessageLoop::current()->RunAllPending(); |
| 2330 } |
| 2331 |
| 2214 // Test that previously tried username/passwords for a realm get re-used. | 2332 // Test that previously tried username/passwords for a realm get re-used. |
| 2215 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { | 2333 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) { |
| 2216 SessionDependencies session_deps; | 2334 SessionDependencies session_deps; |
| 2217 scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps); | 2335 scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps); |
| 2218 | 2336 |
| 2219 // Transaction 1: authenticate (foo, bar) on MyRealm1 | 2337 // Transaction 1: authenticate (foo, bar) on MyRealm1 |
| 2220 { | 2338 { |
| 2221 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( | 2339 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( |
| 2222 session, &session_deps.socket_factory)); | 2340 session, &session_deps.socket_factory)); |
| 2223 | 2341 |
| (...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3617 // Extract the unescaped identity. | 3735 // Extract the unescaped identity. |
| 3618 std::wstring username, password; | 3736 std::wstring username, password; |
| 3619 HttpNetworkTransaction::GetIdentifyFromUrl(url, &username, &password); | 3737 HttpNetworkTransaction::GetIdentifyFromUrl(url, &username, &password); |
| 3620 | 3738 |
| 3621 // Verify that it was decoded as UTF8. | 3739 // Verify that it was decoded as UTF8. |
| 3622 EXPECT_EQ(L"foo", username); | 3740 EXPECT_EQ(L"foo", username); |
| 3623 EXPECT_EQ(L"\x4f60\x597d", password); | 3741 EXPECT_EQ(L"\x4f60\x597d", password); |
| 3624 } | 3742 } |
| 3625 | 3743 |
| 3626 } // namespace net | 3744 } // namespace net |
| OLD | NEW |