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
3 // found in the LICENSE file.
4
5 #include "net/http/http_auth_handler_mock.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/string_util.h"
10 #include "net/base/net_errors.h"
11 #include "net/http/http_auth_challenge_tokenizer.h"
12 #include "net/http/http_request_info.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace net {
16
HttpAuthHandlerMock()17 HttpAuthHandlerMock::HttpAuthHandlerMock()
18 : resolve_(RESOLVE_INIT),
19 generate_async_(false),
20 generate_rv_(OK),
21 auth_token_(NULL),
22 first_round_(true),
23 connection_based_(false),
24 allows_default_credentials_(false),
25 allows_explicit_credentials_(true),
26 weak_factory_(this) {
27 }
28
~HttpAuthHandlerMock()29 HttpAuthHandlerMock::~HttpAuthHandlerMock() {
30 }
31
SetResolveExpectation(Resolve resolve)32 void HttpAuthHandlerMock::SetResolveExpectation(Resolve resolve) {
33 EXPECT_EQ(RESOLVE_INIT, resolve_);
34 resolve_ = resolve;
35 }
36
NeedsCanonicalName()37 bool HttpAuthHandlerMock::NeedsCanonicalName() {
38 switch (resolve_) {
39 case RESOLVE_SYNC:
40 case RESOLVE_ASYNC:
41 return true;
42 case RESOLVE_SKIP:
43 resolve_ = RESOLVE_TESTED;
44 return false;
45 default:
46 NOTREACHED();
47 return false;
48 }
49 }
50
ResolveCanonicalName(HostResolver * host_resolver,const CompletionCallback & callback)51 int HttpAuthHandlerMock::ResolveCanonicalName(
52 HostResolver* host_resolver, const CompletionCallback& callback) {
53 EXPECT_NE(RESOLVE_TESTED, resolve_);
54 int rv = OK;
55 switch (resolve_) {
56 case RESOLVE_SYNC:
57 resolve_ = RESOLVE_TESTED;
58 break;
59 case RESOLVE_ASYNC:
60 EXPECT_TRUE(callback_.is_null());
61 rv = ERR_IO_PENDING;
62 callback_ = callback;
63 base::MessageLoop::current()->PostTask(
64 FROM_HERE,
65 base::Bind(&HttpAuthHandlerMock::OnResolveCanonicalName,
66 weak_factory_.GetWeakPtr()));
67 break;
68 default:
69 NOTREACHED();
70 break;
71 }
72 return rv;
73 }
74
SetGenerateExpectation(bool async,int rv)75 void HttpAuthHandlerMock::SetGenerateExpectation(bool async, int rv) {
76 generate_async_ = async;
77 generate_rv_ = rv;
78 }
79
HandleAnotherChallenge(HttpAuthChallengeTokenizer * challenge)80 HttpAuth::AuthorizationResult HttpAuthHandlerMock::HandleAnotherChallenge(
81 HttpAuthChallengeTokenizer* challenge) {
82 // If we receive an empty challenge for a connection based scheme, or a second
83 // challenge for a non connection based scheme, assume it's a rejection.
84 if (!is_connection_based() || challenge->base64_param().empty())
85 return HttpAuth::AUTHORIZATION_RESULT_REJECT;
86 if (!LowerCaseEqualsASCII(challenge->scheme(), "mock"))
87 return HttpAuth::AUTHORIZATION_RESULT_INVALID;
88 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
89 }
90
NeedsIdentity()91 bool HttpAuthHandlerMock::NeedsIdentity() {
92 return first_round_;
93 }
94
AllowsDefaultCredentials()95 bool HttpAuthHandlerMock::AllowsDefaultCredentials() {
96 return allows_default_credentials_;
97 }
98
AllowsExplicitCredentials()99 bool HttpAuthHandlerMock::AllowsExplicitCredentials() {
100 return allows_explicit_credentials_;
101 }
102
Init(HttpAuthChallengeTokenizer * challenge)103 bool HttpAuthHandlerMock::Init(HttpAuthChallengeTokenizer* challenge) {
104 auth_scheme_ = HttpAuth::AUTH_SCHEME_MOCK;
105 score_ = 1;
106 properties_ = connection_based_ ? IS_CONNECTION_BASED : 0;
107 return true;
108 }
109
GenerateAuthTokenImpl(const AuthCredentials * credentials,const HttpRequestInfo * request,const CompletionCallback & callback,std::string * auth_token)110 int HttpAuthHandlerMock::GenerateAuthTokenImpl(
111 const AuthCredentials* credentials,
112 const HttpRequestInfo* request,
113 const CompletionCallback& callback,
114 std::string* auth_token) {
115 first_round_ = false;
116 request_url_ = request->url;
117 if (generate_async_) {
118 EXPECT_TRUE(callback_.is_null());
119 EXPECT_TRUE(auth_token_ == NULL);
120 callback_ = callback;
121 auth_token_ = auth_token;
122 base::MessageLoop::current()->PostTask(
123 FROM_HERE,
124 base::Bind(&HttpAuthHandlerMock::OnGenerateAuthToken,
125 weak_factory_.GetWeakPtr()));
126 return ERR_IO_PENDING;
127 } else {
128 if (generate_rv_ == OK)
129 *auth_token = "auth_token";
130 return generate_rv_;
131 }
132 }
133
OnResolveCanonicalName()134 void HttpAuthHandlerMock::OnResolveCanonicalName() {
135 EXPECT_EQ(RESOLVE_ASYNC, resolve_);
136 EXPECT_TRUE(!callback_.is_null());
137 resolve_ = RESOLVE_TESTED;
138 CompletionCallback callback = callback_;
139 callback_.Reset();
140 callback.Run(OK);
141 }
142
OnGenerateAuthToken()143 void HttpAuthHandlerMock::OnGenerateAuthToken() {
144 EXPECT_TRUE(generate_async_);
145 EXPECT_TRUE(!callback_.is_null());
146 if (generate_rv_ == OK)
147 *auth_token_ = "auth_token";
148 auth_token_ = NULL;
149 CompletionCallback callback = callback_;
150 callback_.Reset();
151 callback.Run(generate_rv_);
152 }
153
Factory()154 HttpAuthHandlerMock::Factory::Factory()
155 : do_init_from_challenge_(false) {
156 // TODO(cbentzel): Default do_init_from_challenge_ to true.
157 }
158
~Factory()159 HttpAuthHandlerMock::Factory::~Factory() {
160 }
161
AddMockHandler(HttpAuthHandler * handler,HttpAuth::Target target)162 void HttpAuthHandlerMock::Factory::AddMockHandler(
163 HttpAuthHandler* handler, HttpAuth::Target target) {
164 handlers_[target].push_back(handler);
165 }
166
CreateAuthHandler(HttpAuthChallengeTokenizer * challenge,HttpAuth::Target target,const GURL & origin,CreateReason reason,int nonce_count,const BoundNetLog & net_log,scoped_ptr<HttpAuthHandler> * handler)167 int HttpAuthHandlerMock::Factory::CreateAuthHandler(
168 HttpAuthChallengeTokenizer* challenge,
169 HttpAuth::Target target,
170 const GURL& origin,
171 CreateReason reason,
172 int nonce_count,
173 const BoundNetLog& net_log,
174 scoped_ptr<HttpAuthHandler>* handler) {
175 if (handlers_[target].empty())
176 return ERR_UNEXPECTED;
177 scoped_ptr<HttpAuthHandler> tmp_handler(handlers_[target][0]);
178 std::vector<HttpAuthHandler*>& handlers = handlers_[target].get();
179 handlers.erase(handlers.begin());
180 if (do_init_from_challenge_ &&
181 !tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
182 return ERR_INVALID_RESPONSE;
183 handler->swap(tmp_handler);
184 return OK;
185 }
186
187 } // namespace net
188