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