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