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 "net/http/http_auth_handler_mock.h" | 5 #include "net/http/http_auth_handler_mock.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "base/thread_task_runner_handle.h" | 11 #include "base/thread_task_runner_handle.h" |
12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
13 #include "net/http/http_auth_challenge_tokenizer.h" | 13 #include "net/http/http_auth_challenge_tokenizer.h" |
14 #include "net/http/http_request_info.h" | 14 #include "net/http/http_request_info.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 namespace net { | 17 namespace net { |
18 | 18 |
19 HttpAuthHandlerMock::HttpAuthHandlerMock() | 19 HttpAuthHandlerMock::HttpAuthHandlerMock() |
20 : generate_rv_(OK), weak_factory_(this) {} | 20 : expected_auth_scheme_("mock"), weak_factory_(this) {} |
21 | 21 |
22 HttpAuthHandlerMock::~HttpAuthHandlerMock() { | 22 HttpAuthHandlerMock::~HttpAuthHandlerMock() { |
23 } | 23 } |
24 | 24 |
25 void HttpAuthHandlerMock::SetResolveExpectation(Resolve resolve) { | |
26 EXPECT_EQ(RESOLVE_INIT, resolve_); | |
27 resolve_ = resolve; | |
28 } | |
29 | |
30 bool HttpAuthHandlerMock::NeedsCanonicalName() { | |
31 switch (resolve_) { | |
32 case RESOLVE_SYNC: | |
33 case RESOLVE_ASYNC: | |
34 return true; | |
35 case RESOLVE_SKIP: | |
36 resolve_ = RESOLVE_TESTED; | |
37 return false; | |
38 default: | |
39 NOTREACHED(); | |
40 return false; | |
41 } | |
42 } | |
43 | |
44 int HttpAuthHandlerMock::ResolveCanonicalName( | |
45 HostResolver* host_resolver, const CompletionCallback& callback) { | |
46 EXPECT_NE(RESOLVE_TESTED, resolve_); | |
47 int rv = OK; | |
48 switch (resolve_) { | |
49 case RESOLVE_SYNC: | |
50 resolve_ = RESOLVE_TESTED; | |
51 break; | |
52 case RESOLVE_ASYNC: | |
53 EXPECT_TRUE(callback_.is_null()); | |
54 rv = ERR_IO_PENDING; | |
55 callback_ = callback; | |
56 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
57 FROM_HERE, base::Bind(&HttpAuthHandlerMock::OnResolveCanonicalName, | |
58 weak_factory_.GetWeakPtr())); | |
59 break; | |
60 default: | |
61 NOTREACHED(); | |
62 break; | |
63 } | |
64 return rv; | |
65 } | |
66 | |
67 void HttpAuthHandlerMock::SetGenerateExpectation(bool async, int rv) { | 25 void HttpAuthHandlerMock::SetGenerateExpectation(bool async, int rv) { |
68 generate_async_ = async; | 26 generate_async_ = async; |
69 generate_rv_ = rv; | 27 generate_rv_ = rv; |
70 } | 28 } |
71 | 29 |
72 HttpAuth::AuthorizationResult HttpAuthHandlerMock::HandleAnotherChallenge( | 30 HttpAuth::AuthorizationResult HttpAuthHandlerMock::HandleAnotherChallenge( |
73 HttpAuthChallengeTokenizer* challenge) { | 31 HttpAuthChallengeTokenizer* challenge) { |
74 // If we receive a second challenge for a regular scheme, assume it's a | 32 // If we receive a second challenge for a regular scheme, assume it's a |
75 // rejection. Receiving an empty second challenge when expecting multiple | 33 // rejection. Receiving an empty second challenge when expecting multiple |
76 // rounds is also considered a rejection. | 34 // rounds is also considered a rejection. |
77 if (!expect_multiple_challenges() || challenge->base64_param().empty()) | 35 if (!expect_multiple_challenges_ || challenge->base64_param().empty()) |
78 return HttpAuth::AUTHORIZATION_RESULT_REJECT; | 36 return HttpAuth::AUTHORIZATION_RESULT_REJECT; |
79 if (!challenge->SchemeIs("mock")) | 37 if (!challenge->SchemeIs(auth_scheme_)) |
80 return HttpAuth::AUTHORIZATION_RESULT_INVALID; | 38 return HttpAuth::AUTHORIZATION_RESULT_INVALID; |
| 39 auth_token_ = auth_scheme_; |
| 40 auth_token_.append(" continuation,"); |
| 41 auth_token_.append(challenge->base64_param()); |
81 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; | 42 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; |
82 } | 43 } |
83 | 44 |
84 bool HttpAuthHandlerMock::NeedsIdentity() { | 45 bool HttpAuthHandlerMock::NeedsIdentity() { |
85 return first_round_; | 46 return first_round_; |
86 } | 47 } |
87 | 48 |
88 bool HttpAuthHandlerMock::AllowsDefaultCredentials() { | 49 bool HttpAuthHandlerMock::AllowsDefaultCredentials() { |
89 return allows_default_credentials_; | 50 return allows_default_credentials_; |
90 } | 51 } |
91 | 52 |
92 bool HttpAuthHandlerMock::AllowsExplicitCredentials() { | 53 bool HttpAuthHandlerMock::AllowsExplicitCredentials() { |
93 return allows_explicit_credentials_; | 54 return allows_explicit_credentials_; |
94 } | 55 } |
95 | 56 |
96 bool HttpAuthHandlerMock::Init(HttpAuthChallengeTokenizer* challenge) { | 57 bool HttpAuthHandlerMock::Init(HttpAuthChallengeTokenizer* challenge) { |
97 auth_scheme_ = "mock"; | 58 EXPECT_TRUE(challenge->SchemeIs(expected_auth_scheme_)) |
| 59 << "Mismatched scheme for challenge: " << challenge->challenge_text(); |
| 60 EXPECT_TRUE(auth_scheme_.empty()) << "Init was already called."; |
| 61 EXPECT_TRUE(HttpAuth::IsValidNormalizedScheme(expected_auth_scheme_)) |
| 62 << "Invalid expected auth scheme."; |
| 63 auth_scheme_ = expected_auth_scheme_; |
| 64 auth_token_ = expected_auth_scheme_ + " auth_token"; |
| 65 if (challenge->params_end() != challenge->params_begin()) { |
| 66 auth_token_ += ","; |
| 67 auth_token_.append(challenge->params_begin(), challenge->params_end()); |
| 68 } |
98 return true; | 69 return true; |
99 } | 70 } |
100 | 71 |
101 int HttpAuthHandlerMock::GenerateAuthTokenImpl( | 72 int HttpAuthHandlerMock::GenerateAuthTokenImpl( |
102 const AuthCredentials* credentials, | 73 const AuthCredentials* credentials, |
103 const HttpRequestInfo* request, | 74 const HttpRequestInfo* request, |
104 const CompletionCallback& callback, | 75 const CompletionCallback& callback, |
105 std::string* auth_token) { | 76 std::string* auth_token) { |
106 first_round_ = false; | 77 first_round_ = false; |
107 request_url_ = request->url; | 78 request_url_ = request->url; |
| 79 |
| 80 if (!credentials || credentials->Empty()) { |
| 81 EXPECT_TRUE(AllowsDefaultCredentials()) << "Credentials must be specified " |
| 82 "if the handler doesn't support " |
| 83 "default credentials."; |
| 84 } else { |
| 85 EXPECT_TRUE(AllowsExplicitCredentials()) << "Explicit credentials can only " |
| 86 "be specified if the handler " |
| 87 "supports it."; |
| 88 } |
| 89 |
108 if (generate_async_) { | 90 if (generate_async_) { |
109 EXPECT_TRUE(callback_.is_null()); | 91 EXPECT_TRUE(callback_.is_null()) << "GenerateAuthTokenImpl() called while " |
110 EXPECT_TRUE(auth_token_ == NULL); | 92 "a pending request is in progress"; |
| 93 EXPECT_EQ(nullptr, generate_auth_token_buffer_) |
| 94 << "GenerateAuthTokenImpl() called before previous token was retrieved"; |
111 callback_ = callback; | 95 callback_ = callback; |
112 auth_token_ = auth_token; | 96 generate_auth_token_buffer_ = auth_token; |
113 base::ThreadTaskRunnerHandle::Get()->PostTask( | 97 base::ThreadTaskRunnerHandle::Get()->PostTask( |
114 FROM_HERE, base::Bind(&HttpAuthHandlerMock::OnGenerateAuthToken, | 98 FROM_HERE, base::Bind(&HttpAuthHandlerMock::OnGenerateAuthToken, |
115 weak_factory_.GetWeakPtr())); | 99 weak_factory_.GetWeakPtr())); |
116 return ERR_IO_PENDING; | 100 return ERR_IO_PENDING; |
117 } else { | 101 } else { |
118 if (generate_rv_ == OK) | 102 if (generate_rv_ == OK) |
119 *auth_token = "auth_token"; | 103 *auth_token = auth_token_; |
120 return generate_rv_; | 104 return generate_rv_; |
121 } | 105 } |
122 } | 106 } |
123 | 107 |
124 void HttpAuthHandlerMock::OnResolveCanonicalName() { | |
125 EXPECT_EQ(RESOLVE_ASYNC, resolve_); | |
126 EXPECT_TRUE(!callback_.is_null()); | |
127 resolve_ = RESOLVE_TESTED; | |
128 CompletionCallback callback = callback_; | |
129 callback_.Reset(); | |
130 callback.Run(OK); | |
131 } | |
132 | |
133 void HttpAuthHandlerMock::OnGenerateAuthToken() { | 108 void HttpAuthHandlerMock::OnGenerateAuthToken() { |
134 EXPECT_TRUE(generate_async_); | 109 EXPECT_TRUE(generate_async_); |
135 EXPECT_TRUE(!callback_.is_null()); | 110 EXPECT_TRUE(!callback_.is_null()); |
136 if (generate_rv_ == OK) | 111 if (generate_rv_ == OK) |
137 *auth_token_ = "auth_token"; | 112 *generate_auth_token_buffer_ = auth_token_; |
138 auth_token_ = NULL; | 113 generate_auth_token_buffer_ = nullptr; |
139 CompletionCallback callback = callback_; | 114 CompletionCallback callback = callback_; |
140 callback_.Reset(); | 115 callback_.Reset(); |
141 callback.Run(generate_rv_); | 116 callback.Run(generate_rv_); |
142 } | 117 } |
143 | 118 |
144 HttpAuthHandlerMock::Factory::Factory() | 119 HttpAuthHandlerMock::Factory::Factory() {} |
145 : do_init_from_challenge_(false) { | |
146 // TODO(cbentzel): Default do_init_from_challenge_ to true. | |
147 } | |
148 | 120 |
149 HttpAuthHandlerMock::Factory::~Factory() { | 121 HttpAuthHandlerMock::Factory::~Factory() { |
150 } | 122 } |
151 | 123 |
152 void HttpAuthHandlerMock::Factory::AddMockHandler( | 124 void HttpAuthHandlerMock::Factory::AddMockHandler( |
153 HttpAuthHandler* handler, HttpAuth::Target target) { | 125 scoped_ptr<HttpAuthHandler> handler, |
154 handlers_[target].push_back(handler); | 126 CreateReason reason, |
| 127 HttpAuth::Target target) { |
| 128 if (reason == CREATE_PREEMPTIVE) |
| 129 preemptive_handlers_[target].push_back(handler.Pass()); |
| 130 else |
| 131 challenge_handlers_[target].push_back(handler.Pass()); |
155 } | 132 } |
156 | 133 |
157 bool HttpAuthHandlerMock::Factory::HaveAuthHandlers( | 134 bool HttpAuthHandlerMock::Factory::HaveAuthHandlers( |
158 HttpAuth::Target target) const { | 135 HttpAuth::Target target) const { |
159 return !handlers_[target].empty(); | 136 return !challenge_handlers_[target].empty() || |
| 137 !preemptive_handlers_[target].empty(); |
160 } | 138 } |
161 | 139 |
162 int HttpAuthHandlerMock::Factory::CreateAuthHandler( | 140 int HttpAuthHandlerMock::Factory::CreateAuthHandler( |
163 HttpAuthChallengeTokenizer* challenge, | 141 HttpAuthChallengeTokenizer* challenge, |
164 HttpAuth::Target target, | 142 HttpAuth::Target target, |
165 const GURL& origin, | 143 const GURL& origin, |
166 CreateReason reason, | 144 CreateReason reason, |
167 int nonce_count, | 145 int nonce_count, |
168 const BoundNetLog& net_log, | 146 const BoundNetLog& net_log, |
169 scoped_ptr<HttpAuthHandler>* handler) { | 147 scoped_ptr<HttpAuthHandler>* handler) { |
170 if (handlers_[target].empty()) | 148 ScopedVector<HttpAuthHandler>& handler_list = |
| 149 reason == CREATE_PREEMPTIVE ? preemptive_handlers_[target] |
| 150 : challenge_handlers_[target]; |
| 151 if (handler_list.empty()) |
171 return ERR_UNEXPECTED; | 152 return ERR_UNEXPECTED; |
172 scoped_ptr<HttpAuthHandler> tmp_handler(handlers_[target][0]); | 153 scoped_ptr<HttpAuthHandler> tmp_handler(handler_list.front()); |
173 std::vector<HttpAuthHandler*>& handlers = handlers_[target].get(); | 154 handler_list.weak_erase(handler_list.begin()); |
174 handlers.erase(handlers.begin()); | 155 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
175 if (do_init_from_challenge_ && | |
176 !tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | |
177 return ERR_INVALID_RESPONSE; | 156 return ERR_INVALID_RESPONSE; |
178 handler->swap(tmp_handler); | 157 handler->swap(tmp_handler); |
179 return OK; | 158 return OK; |
180 } | 159 } |
181 | 160 |
182 } // namespace net | 161 } // namespace net |
OLD | NEW |