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