summaryrefslogtreecommitdiffstats
path: root/net/http/http_auth.cc
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-15 14:25:50 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-15 14:25:50 +0000
commitfa55e1931013409ddbce59ed39f8b12a351fd0c4 (patch)
tree1ff77c48d22f36173c1fa63ae8acb1faf896aa0d /net/http/http_auth.cc
parente8da0a0066695284dbf698c9900617b3b159f33b (diff)
downloadchromium_src-fa55e1931013409ddbce59ed39f8b12a351fd0c4.zip
chromium_src-fa55e1931013409ddbce59ed39f8b12a351fd0c4.tar.gz
chromium_src-fa55e1931013409ddbce59ed39f8b12a351fd0c4.tar.bz2
Added factories for HttpAuthHandler.
The driving rationale for this change was to prevent choosing an AuthHandler when it is not supported on the system due to a missing runtime component (such as not being able to locate a gssapi shared library when seeing a Negotiate scheme). It also has the advantage (currently unused) of determining some per-auth-scheme properties only the first time that a challenge for that scheme is seen (such as maximum token length for the SSPI implementation of NTLM). Finally, it may make unit tests easier to generate since the factory can be easily mocked. BUG=34795 TEST=New unit test for HttpAuthHandlerDispatchFactory. Review URL: http://codereview.chromium.org/582007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39065 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http/http_auth.cc')
-rw-r--r--net/http/http_auth.cc73
1 files changed, 33 insertions, 40 deletions
diff --git a/net/http/http_auth.cc b/net/http/http_auth.cc
index aa97640..83da9ad 100644
--- a/net/http/http_auth.cc
+++ b/net/http/http_auth.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,6 +8,7 @@
#include "base/basictypes.h"
#include "base/string_util.h"
+#include "net/base/net_errors.h"
#include "net/http/http_auth_handler_basic.h"
#include "net/http/http_auth_handler_digest.h"
#include "net/http/http_auth_handler_negotiate.h"
@@ -18,10 +19,14 @@
namespace net {
// static
-void HttpAuth::ChooseBestChallenge(const HttpResponseHeaders* headers,
- Target target,
- const GURL& origin,
- scoped_refptr<HttpAuthHandler>* handler) {
+void HttpAuth::ChooseBestChallenge(
+ HttpAuthHandlerFactory* http_auth_handler_factory,
+ const HttpResponseHeaders* headers,
+ Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ DCHECK(http_auth_handler_factory);
+
// A connection-based authentication scheme must continue to use the
// existing handler object in |*handler|.
if (*handler && (*handler)->is_connection_based()) {
@@ -31,8 +36,7 @@ void HttpAuth::ChooseBestChallenge(const HttpResponseHeaders* headers,
while (headers->EnumerateHeader(&iter, header_name, &challenge)) {
ChallengeTokenizer props(challenge.begin(), challenge.end());
if (LowerCaseEqualsASCII(props.scheme(), (*handler)->scheme().c_str()) &&
- (*handler)->InitFromChallenge(challenge.begin(), challenge.end(),
- target, origin))
+ (*handler)->InitFromChallenge(&props, target, origin))
return;
}
}
@@ -44,45 +48,19 @@ void HttpAuth::ChooseBestChallenge(const HttpResponseHeaders* headers,
void* iter = NULL;
while (headers->EnumerateHeader(&iter, header_name, &cur_challenge)) {
scoped_refptr<HttpAuthHandler> cur;
- CreateAuthHandler(cur_challenge, target, origin, &cur);
+ int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
+ cur_challenge, target, origin, &cur);
+ if (rv != OK) {
+ LOG(WARNING) << "Unable to create AuthHandler. Status: "
+ << ErrorToString(rv) << " Challenge: " << cur_challenge;
+ continue;
+ }
if (cur && (!best || best->score() < cur->score()))
best.swap(cur);
}
handler->swap(best);
}
-// static
-void HttpAuth::CreateAuthHandler(const std::string& challenge,
- Target target,
- const GURL& origin,
- scoped_refptr<HttpAuthHandler>* handler) {
- // Find the right auth handler for the challenge's scheme.
- ChallengeTokenizer props(challenge.begin(), challenge.end());
- if (!props.valid()) {
- *handler = NULL;
- return;
- }
-
- scoped_refptr<HttpAuthHandler> tmp_handler;
- if (LowerCaseEqualsASCII(props.scheme(), "basic")) {
- tmp_handler = new HttpAuthHandlerBasic();
- } else if (LowerCaseEqualsASCII(props.scheme(), "digest")) {
- tmp_handler = new HttpAuthHandlerDigest();
- } else if (LowerCaseEqualsASCII(props.scheme(), "negotiate")) {
- tmp_handler = new HttpAuthHandlerNegotiate();
- } else if (LowerCaseEqualsASCII(props.scheme(), "ntlm")) {
- tmp_handler = new HttpAuthHandlerNTLM();
- }
- if (tmp_handler) {
- if (!tmp_handler->InitFromChallenge(challenge.begin(), challenge.end(),
- target, origin)) {
- // Invalid/unsupported challenge.
- tmp_handler = NULL;
- }
- }
- handler->swap(tmp_handler);
-}
-
void HttpAuth::ChallengeTokenizer::Init(std::string::const_iterator begin,
std::string::const_iterator end) {
// The first space-separated token is the auth-scheme.
@@ -115,6 +93,21 @@ bool HttpAuth::ChallengeTokenizer::GetNext() {
value_end_ = props_.value_end();
name_begin_ = name_end_ = value_end_;
+ if (expect_base64_token_) {
+ expect_base64_token_ = false;
+ // Strip off any padding.
+ // (See https://bugzilla.mozilla.org/show_bug.cgi?id=230351.)
+ //
+ // Our base64 decoder requires that the length be a multiple of 4.
+ int encoded_length = value_end_ - value_begin_;
+ while (encoded_length > 0 && encoded_length % 4 != 0 &&
+ value_begin_[encoded_length - 1] == '=') {
+ --encoded_length;
+ --value_end_;
+ }
+ return true;
+ }
+
// Scan for the equals sign.
std::string::const_iterator equals = std::find(value_begin_, value_end_, '=');
if (equals == value_end_ || equals == value_begin_)