| 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 |