http_auth_handler_mock.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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.h"
9#include "base/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
14namespace net {
15
16HttpAuthHandlerMock::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
28HttpAuthHandlerMock::~HttpAuthHandlerMock() {
29}
30
31void HttpAuthHandlerMock::SetResolveExpectation(Resolve resolve) {
32  EXPECT_EQ(RESOLVE_INIT, resolve_);
33  resolve_ = resolve;
34}
35
36bool 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
50int 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
74void HttpAuthHandlerMock::SetGenerateExpectation(bool async, int rv) {
75  generate_async_ = async;
76  generate_rv_ = rv;
77}
78
79HttpAuth::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
90bool HttpAuthHandlerMock::NeedsIdentity() {
91  return first_round_;
92}
93
94bool HttpAuthHandlerMock::AllowsDefaultCredentials() {
95  return allows_default_credentials_;
96}
97
98bool HttpAuthHandlerMock::AllowsExplicitCredentials() {
99  return allows_explicit_credentials_;
100}
101
102bool 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
109int 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
133void 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
142void 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
153HttpAuthHandlerMock::Factory::Factory()
154    : do_init_from_challenge_(false) {
155  // TODO(cbentzel): Default do_init_from_challenge_ to true.
156}
157
158HttpAuthHandlerMock::Factory::~Factory() {
159}
160
161void HttpAuthHandlerMock::Factory::AddMockHandler(
162    HttpAuthHandler* handler, HttpAuth::Target target) {
163  handlers_[target].push_back(handler);
164}
165
166int 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