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