| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <set> | 5 #include <set> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/ref_counted.h" | 8 #include "base/ref_counted.h" |
| 9 #include "base/scoped_ptr.h" | 9 #include "base/scoped_ptr.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "net/base/mock_host_resolver.h" | 11 #include "net/base/mock_host_resolver.h" |
| 12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
| 13 #include "net/http/http_auth.h" | 13 #include "net/http/http_auth.h" |
| 14 #include "net/http/http_auth_filter.h" | 14 #include "net/http/http_auth_filter.h" |
| 15 #include "net/http/http_auth_handler.h" | 15 #include "net/http/http_auth_handler.h" |
| 16 #include "net/http/http_auth_handler_factory.h" | 16 #include "net/http/http_auth_handler_factory.h" |
| 17 #include "net/http/http_auth_handler_mock.h" | 17 #include "net/http/http_auth_handler_mock.h" |
| 18 #include "net/http/http_response_headers.h" | 18 #include "net/http/http_response_headers.h" |
| 19 #include "net/http/http_util.h" | 19 #include "net/http/http_util.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 21 |
| 22 namespace net { | 22 namespace net { |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 HttpAuthHandlerMock* CreateMockHandler(bool connection_based) { | 26 HttpAuthHandlerMock* CreateMockHandler(bool connection_based) { |
| 27 HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock(); | 27 HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock(); |
| 28 auth_handler->set_connection_based(connection_based); | 28 auth_handler->set_connection_based(connection_based); |
| 29 std::string challenge_text = "Mock"; | 29 std::string challenge_text = "Basic"; |
| 30 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(), | 30 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(), |
| 31 challenge_text.end()); | 31 challenge_text.end()); |
| 32 GURL origin("www.example.com"); | 32 GURL origin("www.example.com"); |
| 33 EXPECT_TRUE(auth_handler->InitFromChallenge(&challenge, | 33 EXPECT_TRUE(auth_handler->InitFromChallenge(&challenge, |
| 34 HttpAuth::AUTH_SERVER, | 34 HttpAuth::AUTH_SERVER, |
| 35 origin, | 35 origin, |
| 36 BoundNetLog())); | 36 BoundNetLog())); |
| 37 return auth_handler; | 37 return auth_handler; |
| 38 } | 38 } |
| 39 | 39 |
| 40 HttpResponseHeaders* HeadersFromResponseText(const std::string& response) { | 40 HttpResponseHeaders* HeadersFromResponseText(const std::string& response) { |
| 41 return new HttpResponseHeaders( | 41 return new HttpResponseHeaders( |
| 42 HttpUtil::AssembleRawHeaders(response.c_str(), response.length())); | 42 HttpUtil::AssembleRawHeaders(response.c_str(), response.length())); |
| 43 } | 43 } |
| 44 | 44 |
| 45 HttpAuth::AuthorizationResult HandleChallengeResponse( | 45 HttpAuth::AuthorizationResult HandleChallengeResponse( |
| 46 bool connection_based, | 46 bool connection_based, |
| 47 const std::string& headers_text, | 47 const std::string& headers_text, |
| 48 std::string* challenge_used) { | 48 std::string* challenge_used) { |
| 49 scoped_ptr<HttpAuthHandlerMock> mock_handler( | 49 scoped_ptr<HttpAuthHandlerMock> mock_handler( |
| 50 CreateMockHandler(connection_based)); | 50 CreateMockHandler(connection_based)); |
| 51 std::set<std::string> disabled_schemes; | 51 std::set<HttpAuth::Scheme> disabled_schemes; |
| 52 scoped_refptr<HttpResponseHeaders> headers( | 52 scoped_refptr<HttpResponseHeaders> headers( |
| 53 HeadersFromResponseText(headers_text)); | 53 HeadersFromResponseText(headers_text)); |
| 54 return HttpAuth::HandleChallengeResponse( | 54 return HttpAuth::HandleChallengeResponse( |
| 55 mock_handler.get(), | 55 mock_handler.get(), |
| 56 headers.get(), | 56 headers.get(), |
| 57 HttpAuth::AUTH_SERVER, | 57 HttpAuth::AUTH_SERVER, |
| 58 disabled_schemes, | 58 disabled_schemes, |
| 59 challenge_used); | 59 challenge_used); |
| 60 } | 60 } |
| 61 | 61 |
| 62 } // namespace | 62 } // namespace |
| 63 | 63 |
| 64 TEST(HttpAuthTest, ChooseBestChallenge) { | 64 TEST(HttpAuthTest, ChooseBestChallenge) { |
| 65 static const struct { | 65 static const struct { |
| 66 const char* headers; | 66 const char* headers; |
| 67 const char* challenge_scheme; | 67 HttpAuth::Scheme challenge_scheme; |
| 68 const char* challenge_realm; | 68 const char* challenge_realm; |
| 69 } tests[] = { | 69 } tests[] = { |
| 70 { | 70 { |
| 71 // Basic is the only challenge type, pick it. |
| 71 "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n" | 72 "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n" |
| 72 "www-authenticate: Basic realm=\"BasicRealm\"\n", | 73 "www-authenticate: Basic realm=\"BasicRealm\"\n", |
| 73 | 74 |
| 74 // Basic is the only challenge type, pick it. | 75 HttpAuth::AUTH_SCHEME_BASIC, |
| 75 "basic", | |
| 76 "BasicRealm", | 76 "BasicRealm", |
| 77 }, | 77 }, |
| 78 { | 78 { |
| 79 // Fake is the only challenge type, but it is unsupported. |
| 79 "Y: Digest realm=\"FooBar\", nonce=\"aaaaaaaaaa\"\n" | 80 "Y: Digest realm=\"FooBar\", nonce=\"aaaaaaaaaa\"\n" |
| 80 "www-authenticate: Fake realm=\"FooBar\"\n", | 81 "www-authenticate: Fake realm=\"FooBar\"\n", |
| 81 | 82 |
| 82 // Fake is the only challenge type, but it is unsupported. | 83 HttpAuth::AUTH_SCHEME_MAX, |
| 83 "", | |
| 84 "", | 84 "", |
| 85 }, | 85 }, |
| 86 { | 86 { |
| 87 // Pick Digest over Basic. |
| 87 "www-authenticate: Basic realm=\"FooBar\"\n" | 88 "www-authenticate: Basic realm=\"FooBar\"\n" |
| 88 "www-authenticate: Fake realm=\"FooBar\"\n" | 89 "www-authenticate: Fake realm=\"FooBar\"\n" |
| 89 "www-authenticate: nonce=\"aaaaaaaaaa\"\n" | 90 "www-authenticate: nonce=\"aaaaaaaaaa\"\n" |
| 90 "www-authenticate: Digest realm=\"DigestRealm\", nonce=\"aaaaaaaaaa\"\n", | 91 "www-authenticate: Digest realm=\"DigestRealm\", nonce=\"aaaaaaaaaa\"\n", |
| 91 | 92 |
| 92 // Pick Digset over Basic | 93 HttpAuth::AUTH_SCHEME_DIGEST, |
| 93 "digest", | |
| 94 "DigestRealm", | 94 "DigestRealm", |
| 95 }, | 95 }, |
| 96 { | 96 { |
| 97 // Handle an empty header correctly. |
| 97 "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n" | 98 "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n" |
| 98 "www-authenticate:\n", | 99 "www-authenticate:\n", |
| 99 | 100 |
| 100 // Handle null header value. | 101 HttpAuth::AUTH_SCHEME_MAX, |
| 101 "", | |
| 102 "", | 102 "", |
| 103 }, | 103 }, |
| 104 { | 104 { |
| 105 // Choose Negotiate over NTLM on all platforms. |
| 106 // TODO(ahendrickson): This may be flaky on Linux and OSX as it |
| 107 // relies on being able to load one of the known .so files |
| 108 // for gssapi. |
| 105 "WWW-Authenticate: Negotiate\n" | 109 "WWW-Authenticate: Negotiate\n" |
| 106 "WWW-Authenticate: NTLM\n", | 110 "WWW-Authenticate: NTLM\n", |
| 107 | 111 |
| 108 // TODO(ahendrickson): This may be flaky on Linux and OSX as it | 112 HttpAuth::AUTH_SCHEME_NEGOTIATE, |
| 109 // relies on being able to load one of the known .so files | |
| 110 // for gssapi. | |
| 111 "negotiate", | |
| 112 "", | 113 "", |
| 113 } | 114 } |
| 114 }; | 115 }; |
| 115 GURL origin("http://www.example.com"); | 116 GURL origin("http://www.example.com"); |
| 116 std::set<std::string> disabled_schemes; | 117 std::set<HttpAuth::Scheme> disabled_schemes; |
| 117 URLSecurityManagerAllow url_security_manager; | 118 URLSecurityManagerAllow url_security_manager; |
| 118 scoped_ptr<HostResolver> host_resolver(new MockHostResolver()); | 119 scoped_ptr<HostResolver> host_resolver(new MockHostResolver()); |
| 119 scoped_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory( | 120 scoped_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory( |
| 120 HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); | 121 HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); |
| 121 http_auth_handler_factory->SetURLSecurityManager( | 122 http_auth_handler_factory->SetURLSecurityManager( |
| 122 "negotiate", &url_security_manager); | 123 "negotiate", &url_security_manager); |
| 123 | 124 |
| 124 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 125 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 125 // Make a HttpResponseHeaders object. | 126 // Make a HttpResponseHeaders object. |
| 126 std::string headers_with_status_line("HTTP/1.1 401 Unauthorized\n"); | 127 std::string headers_with_status_line("HTTP/1.1 401 Unauthorized\n"); |
| 127 headers_with_status_line += tests[i].headers; | 128 headers_with_status_line += tests[i].headers; |
| 128 scoped_refptr<HttpResponseHeaders> headers( | 129 scoped_refptr<HttpResponseHeaders> headers( |
| 129 HeadersFromResponseText(headers_with_status_line)); | 130 HeadersFromResponseText(headers_with_status_line)); |
| 130 | 131 |
| 131 scoped_ptr<HttpAuthHandler> handler; | 132 scoped_ptr<HttpAuthHandler> handler; |
| 132 HttpAuth::ChooseBestChallenge(http_auth_handler_factory.get(), | 133 HttpAuth::ChooseBestChallenge(http_auth_handler_factory.get(), |
| 133 headers.get(), | 134 headers.get(), |
| 134 HttpAuth::AUTH_SERVER, | 135 HttpAuth::AUTH_SERVER, |
| 135 origin, | 136 origin, |
| 136 disabled_schemes, | 137 disabled_schemes, |
| 137 BoundNetLog(), | 138 BoundNetLog(), |
| 138 &handler); | 139 &handler); |
| 139 | 140 |
| 140 if (handler.get()) { | 141 if (handler.get()) { |
| 141 EXPECT_STREQ(tests[i].challenge_scheme, handler->scheme().c_str()); | 142 EXPECT_EQ(tests[i].challenge_scheme, handler->auth_scheme()); |
| 142 EXPECT_STREQ(tests[i].challenge_realm, handler->realm().c_str()); | 143 EXPECT_STREQ(tests[i].challenge_realm, handler->realm().c_str()); |
| 143 } else { | 144 } else { |
| 144 EXPECT_STREQ("", tests[i].challenge_scheme); | 145 EXPECT_EQ(HttpAuth::AUTH_SCHEME_MAX, tests[i].challenge_scheme); |
| 145 EXPECT_STREQ("", tests[i].challenge_realm); | 146 EXPECT_STREQ("", tests[i].challenge_realm); |
| 146 } | 147 } |
| 147 } | 148 } |
| 148 } | 149 } |
| 149 | 150 |
| 150 TEST(HttpAuthTest, HandleChallengeResponse) { | 151 TEST(HttpAuthTest, HandleChallengeResponse) { |
| 151 std::string challenge_used; | 152 std::string challenge_used; |
| 152 const char* const kMockChallenge = | 153 const char* const kMockChallenge = |
| 153 "HTTP/1.1 401 Unauthorized\n" | 154 "HTTP/1.1 401 Unauthorized\n" |
| 154 "WWW-Authenticate: Mock token_here\n"; | 155 "WWW-Authenticate: Mock token_here\n"; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 std::string name; | 420 std::string name; |
| 420 | 421 |
| 421 name = HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_SERVER); | 422 name = HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_SERVER); |
| 422 EXPECT_STREQ("Authorization", name.c_str()); | 423 EXPECT_STREQ("Authorization", name.c_str()); |
| 423 | 424 |
| 424 name = HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_PROXY); | 425 name = HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_PROXY); |
| 425 EXPECT_STREQ("Proxy-Authorization", name.c_str()); | 426 EXPECT_STREQ("Proxy-Authorization", name.c_str()); |
| 426 } | 427 } |
| 427 | 428 |
| 428 } // namespace net | 429 } // namespace net |
| OLD | NEW |