1// Copyright (c) 2010 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.h"
6
7#include "base/logging.h"
8#include "net/base/net_errors.h"
9
10namespace net {
11
12HttpAuthHandler::HttpAuthHandler()
13    : auth_scheme_(HttpAuth::AUTH_SCHEME_MAX),
14      score_(-1),
15      target_(HttpAuth::AUTH_NONE),
16      properties_(-1),
17      original_callback_(NULL),
18      ALLOW_THIS_IN_INITIALIZER_LIST(
19          wrapper_callback_(
20              this, &HttpAuthHandler::OnGenerateAuthTokenComplete)) {
21}
22
23HttpAuthHandler::~HttpAuthHandler() {
24}
25
26bool HttpAuthHandler::InitFromChallenge(
27    HttpAuth::ChallengeTokenizer* challenge,
28    HttpAuth::Target target,
29    const GURL& origin,
30    const BoundNetLog& net_log) {
31  origin_ = origin;
32  target_ = target;
33  score_ = -1;
34  properties_ = -1;
35  net_log_ = net_log;
36
37  auth_challenge_ = challenge->challenge_text();
38  bool ok = Init(challenge);
39
40  // Init() is expected to set the scheme, realm, score, and properties.  The
41  // realm may be empty.
42  DCHECK(!ok || score_ != -1);
43  DCHECK(!ok || properties_ != -1);
44  DCHECK(!ok || auth_scheme_ != HttpAuth::AUTH_SCHEME_MAX);
45
46  return ok;
47}
48
49namespace {
50
51NetLog::EventType EventTypeFromAuthTarget(HttpAuth::Target target) {
52  switch (target) {
53    case HttpAuth::AUTH_PROXY:
54      return NetLog::TYPE_AUTH_PROXY;
55    case HttpAuth::AUTH_SERVER:
56      return NetLog::TYPE_AUTH_SERVER;
57    default:
58      NOTREACHED();
59      return NetLog::TYPE_CANCELLED;
60  }
61}
62
63}  // namespace
64
65int HttpAuthHandler::GenerateAuthToken(const string16* username,
66                                       const string16* password,
67                                       const HttpRequestInfo* request,
68                                       CompletionCallback* callback,
69                                       std::string* auth_token) {
70  // TODO(cbentzel): Enforce non-NULL callback after cleaning up SocketStream.
71  DCHECK(request);
72  DCHECK((username == NULL) == (password == NULL));
73  DCHECK(username != NULL || AllowsDefaultCredentials());
74  DCHECK(auth_token != NULL);
75  DCHECK(original_callback_ == NULL);
76  original_callback_ = callback;
77  net_log_.BeginEvent(EventTypeFromAuthTarget(target_), NULL);
78  int rv = GenerateAuthTokenImpl(username, password, request,
79                                 &wrapper_callback_, auth_token);
80  if (rv != ERR_IO_PENDING)
81    FinishGenerateAuthToken();
82  return rv;
83}
84
85bool HttpAuthHandler::NeedsIdentity() {
86  return true;
87}
88
89bool HttpAuthHandler::AllowsDefaultCredentials() {
90  return false;
91}
92
93void HttpAuthHandler::OnGenerateAuthTokenComplete(int rv) {
94  CompletionCallback* callback = original_callback_;
95  FinishGenerateAuthToken();
96  if (callback)
97    callback->Run(rv);
98}
99
100void HttpAuthHandler::FinishGenerateAuthToken() {
101  // TOOD(cbentzel): Should this be done in OK case only?
102  net_log_.EndEvent(EventTypeFromAuthTarget(target_), NULL);
103  original_callback_ = NULL;
104}
105
106}  // namespace net
107