summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/http/http_auth.cc73
-rw-r--r--net/http/http_auth.h35
-rw-r--r--net/http/http_auth_cache_unittest.cc2
-rw-r--r--net/http/http_auth_handler.cc11
-rw-r--r--net/http/http_auth_handler.h22
-rw-r--r--net/http/http_auth_handler_basic.cc35
-rw-r--r--net/http/http_auth_handler_basic.h16
-rw-r--r--net/http/http_auth_handler_basic_unittest.cc25
-rw-r--r--net/http/http_auth_handler_digest.cc36
-rw-r--r--net/http/http_auth_handler_digest.h20
-rw-r--r--net/http/http_auth_handler_digest_unittest.cc9
-rw-r--r--net/http/http_auth_handler_factory.cc82
-rw-r--r--net/http/http_auth_handler_factory.h96
-rw-r--r--net/http/http_auth_handler_factory_unittest.cc177
-rw-r--r--net/http/http_auth_handler_negotiate.cc15
-rw-r--r--net/http/http_auth_handler_negotiate.h15
-rw-r--r--net/http/http_auth_handler_negotiate_posix.cc11
-rw-r--r--net/http/http_auth_handler_negotiate_win.cc20
-rw-r--r--net/http/http_auth_handler_ntlm.cc51
-rw-r--r--net/http/http_auth_handler_ntlm.h20
-rw-r--r--net/http/http_auth_sspi_win.cc31
-rw-r--r--net/http/http_auth_sspi_win.h7
-rw-r--r--net/http/http_auth_unittest.cc82
-rw-r--r--net/http/http_cache.cc8
-rw-r--r--net/http/http_cache.h5
-rw-r--r--net/http/http_network_layer.cc17
-rw-r--r--net/http/http_network_layer.h11
-rw-r--r--net/http/http_network_layer_unittest.cc9
-rw-r--r--net/http/http_network_session.cc9
-rw-r--r--net/http/http_network_session.h10
-rw-r--r--net/http/http_network_transaction.cc5
-rw-r--r--net/http/http_network_transaction_unittest.cc6
-rwxr-xr-xnet/net.gyp6
-rw-r--r--net/proxy/proxy_script_fetcher_unittest.cc8
-rw-r--r--net/socket_stream/socket_stream.cc11
-rw-r--r--net/socket_stream/socket_stream.h4
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc7
-rw-r--r--net/spdy/spdy_stream_unittest.cc9
-rw-r--r--net/tools/fetch/fetch_client.cc10
-rw-r--r--net/url_request/url_request_context.h8
-rw-r--r--net/url_request/url_request_unittest.h8
41 files changed, 772 insertions, 270 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_)
diff --git a/net/http/http_auth.h b/net/http/http_auth.h
index 38c9918..76deca8 100644
--- a/net/http/http_auth.h
+++ b/net/http/http_auth.h
@@ -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.
@@ -12,6 +12,7 @@ template <class T> class scoped_refptr;
namespace net {
class HttpAuthHandler;
+class HttpAuthHandlerFactory;
class HttpResponseHeaders;
// Utility class for http authentication.
@@ -70,14 +71,6 @@ class HttpAuth {
// (either Authorization or Proxy-Authorization).
static std::string GetAuthorizationHeaderName(Target target);
- // Create a handler to generate credentials for the challenge, and pass
- // it back in |*handler|. If the challenge is unsupported or invalid
- // |*handler| is set to NULL.
- static void CreateAuthHandler(const std::string& challenge,
- Target target,
- const GURL& origin,
- scoped_refptr<HttpAuthHandler>* handler);
-
// Iterate through the challenge headers, and pick the best one that
// we support. Obtains the implementation class for handling the challenge,
// and passes it back in |*handler|. If the existing handler in |*handler|
@@ -91,10 +84,12 @@ class HttpAuth {
// TODO(wtc): Continuing to use the existing handler in |*handler| (for
// NTLM) is new behavior. Rename ChooseBestChallenge to fully encompass
// what it does now.
- static void ChooseBestChallenge(const HttpResponseHeaders* headers,
- Target target,
- const GURL& origin,
- scoped_refptr<HttpAuthHandler>* handler);
+ static void ChooseBestChallenge(
+ HttpAuthHandlerFactory* http_auth_handler_factory,
+ const HttpResponseHeaders* headers,
+ Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler);
// ChallengeTokenizer breaks up a challenge string into the the auth scheme
// and parameter list, according to RFC 2617 Sec 1.2:
@@ -107,7 +102,7 @@ class HttpAuth {
public:
ChallengeTokenizer(std::string::const_iterator begin,
std::string::const_iterator end)
- : props_(begin, end, ','), valid_(true) {
+ : props_(begin, end, ','), valid_(true), expect_base64_token_(false) {
Init(begin, end);
}
@@ -127,6 +122,17 @@ class HttpAuth {
// Returns true if there is none to consume.
bool GetNext();
+ // Inform the tokenizer whether the next token should be treated as a base64
+ // encoded value. If |expect_base64_token| is true, |GetNext| will treat the
+ // next token as a base64 encoded value, and will include the trailing '='
+ // padding rather than attempt to split the token into a name/value pair.
+ // In this case, |name| will be empty, and |value| will contain the token.
+ // Subsequent calls to |GetNext()| will not treat the token like a base64
+ // encoded token unless the caller again calls |set_expect_base64_token|.
+ void set_expect_base64_token(bool expect_base64_token) {
+ expect_base64_token_ = expect_base64_token;
+ }
+
// The name of the current name-value pair.
std::string::const_iterator name_begin() const { return name_begin_; }
std::string::const_iterator name_end() const { return name_end_; }
@@ -164,6 +170,7 @@ class HttpAuth {
std::string::const_iterator value_end_;
bool value_is_quoted_;
+ bool expect_base64_token_;
};
};
diff --git a/net/http/http_auth_cache_unittest.cc b/net/http/http_auth_cache_unittest.cc
index b00e8d0..c233f01 100644
--- a/net/http/http_auth_cache_unittest.cc
+++ b/net/http/http_auth_cache_unittest.cc
@@ -41,7 +41,7 @@ class MockAuthHandler : public HttpAuthHandler {
}
protected:
- virtual bool Init(std::string::const_iterator, std::string::const_iterator) {
+ virtual bool Init(HttpAuth::ChallengeTokenizer* challenge) {
return false; // Unused.
}
diff --git a/net/http/http_auth_handler.cc b/net/http/http_auth_handler.cc
index 9d70ca0..e61de2f 100644
--- a/net/http/http_auth_handler.cc
+++ b/net/http/http_auth_handler.cc
@@ -5,20 +5,19 @@
#include "net/http/http_auth_handler.h"
#include "base/logging.h"
-#include "net/base/net_errors.h"
namespace net {
-bool HttpAuthHandler::InitFromChallenge(std::string::const_iterator begin,
- std::string::const_iterator end,
- HttpAuth::Target target,
- const GURL& origin) {
+bool HttpAuthHandler::InitFromChallenge(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin) {
origin_ = origin;
target_ = target;
score_ = -1;
properties_ = -1;
- bool ok = Init(begin, end);
+ bool ok = Init(challenge);
// Init() is expected to set the scheme, realm, score, and properties. The
// realm may be empty.
diff --git a/net/http/http_auth_handler.h b/net/http/http_auth_handler.h
index 4b8f5261..dc0543e 100644
--- a/net/http/http_auth_handler.h
+++ b/net/http/http_auth_handler.h
@@ -16,14 +16,16 @@ class HttpRequestInfo;
class ProxyInfo;
// HttpAuthHandler is the interface for the authentication schemes
-// (basic, digest, ...)
-// The registry mapping auth-schemes to implementations is hardcoded in
-// HttpAuth::CreateAuthHandler().
+// (basic, digest, NTLM, Negotiate).
+// HttpAuthHandler objects are typically created by an HttpAuthHandlerFactory.
class HttpAuthHandler : public base::RefCounted<HttpAuthHandler> {
public:
- // Initialize the handler by parsing a challenge string.
- bool InitFromChallenge(std::string::const_iterator begin,
- std::string::const_iterator end,
+ // Initializes the handler using a challenge issued by a server.
+ // |challenge| must be non-NULL and have already tokenized the
+ // authentication scheme, but none of the tokens occuring after the
+ // authentication scheme. |target| and |origin| are both stored
+ // for later use, and are not part of the initial challenge.
+ bool InitFromChallenge(HttpAuth::ChallengeTokenizer* challenge,
HttpAuth::Target target,
const GURL& origin);
@@ -109,11 +111,13 @@ class HttpAuthHandler : public base::RefCounted<HttpAuthHandler> {
virtual ~HttpAuthHandler() { }
- // Initialize the handler by parsing a challenge string.
+ // Initializes the handler using a challenge issued by a server.
+ // |challenge| must be non-NULL and have already tokenized the
+ // authentication scheme, but none of the tokens occuring after the
+ // authentication scheme.
// Implementations are expcted to initialize the following members:
// scheme_, realm_, score_, properties_
- virtual bool Init(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) = 0;
+ virtual bool Init(HttpAuth::ChallengeTokenizer* challenge) = 0;
// The lowercase auth-scheme {"basic", "digest", "ntlm", ...}
std::string scheme_;
diff --git a/net/http/http_auth_handler_basic.cc b/net/http/http_auth_handler_basic.cc
index 2c70577..3510ee2 100644
--- a/net/http/http_auth_handler_basic.cc
+++ b/net/http/http_auth_handler_basic.cc
@@ -21,25 +21,23 @@ namespace net {
//
// We allow it to be compatibility with certain embedded webservers that don't
// include a realm (see http://crbug.com/20984.)
-bool HttpAuthHandlerBasic::Init(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) {
+bool HttpAuthHandlerBasic::Init(HttpAuth::ChallengeTokenizer* challenge) {
scheme_ = "basic";
score_ = 1;
properties_ = 0;
// Verify the challenge's auth-scheme.
- HttpAuth::ChallengeTokenizer challenge_tok(challenge_begin, challenge_end);
- if (!challenge_tok.valid() ||
- !LowerCaseEqualsASCII(challenge_tok.scheme(), "basic"))
+ if (!challenge->valid() ||
+ !LowerCaseEqualsASCII(challenge->scheme(), "basic"))
return false;
// Extract the realm (may be missing).
- while (challenge_tok.GetNext()) {
- if (LowerCaseEqualsASCII(challenge_tok.name(), "realm"))
- realm_ = challenge_tok.unquoted_value();
+ while (challenge->GetNext()) {
+ if (LowerCaseEqualsASCII(challenge->name(), "realm"))
+ realm_ = challenge->unquoted_value();
}
- return challenge_tok.valid();
+ return challenge->valid();
}
int HttpAuthHandlerBasic::GenerateAuthToken(
@@ -68,5 +66,24 @@ int HttpAuthHandlerBasic::GenerateDefaultAuthToken(
return ERR_NOT_IMPLEMENTED;
}
+HttpAuthHandlerBasic::Factory::Factory() {
+}
+
+HttpAuthHandlerBasic::Factory::~Factory() {
+}
+
+int HttpAuthHandlerBasic::Factory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ // TODO(cbentzel): Move towards model of parsing in the factory
+ // method and only constructing when valid.
+ scoped_refptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerBasic());
+ if (!tmp_handler->InitFromChallenge(challenge, target, origin))
+ return ERR_INVALID_RESPONSE;
+ handler->swap(tmp_handler);
+ return OK;
+}
} // namespace net
diff --git a/net/http/http_auth_handler_basic.h b/net/http/http_auth_handler_basic.h
index e4d2f25..be63e21 100644
--- a/net/http/http_auth_handler_basic.h
+++ b/net/http/http_auth_handler_basic.h
@@ -6,12 +6,24 @@
#define NET_HTTP_HTTP_AUTH_HANDLER_BASIC_H_
#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
namespace net {
// Code for handling http basic authentication.
class HttpAuthHandlerBasic : public HttpAuthHandler {
public:
+ class Factory : public HttpAuthHandlerFactory {
+ public:
+ Factory();
+ virtual ~Factory();
+
+ virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler);
+ };
+
virtual int GenerateAuthToken(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo*,
@@ -22,10 +34,8 @@ class HttpAuthHandlerBasic : public HttpAuthHandler {
const ProxyInfo* proxy,
std::string* auth_token);
-
protected:
- virtual bool Init(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end);
+ virtual bool Init(HttpAuth::ChallengeTokenizer* challenge);
private:
~HttpAuthHandlerBasic() {}
diff --git a/net/http/http_auth_handler_basic_unittest.cc b/net/http/http_auth_handler_basic_unittest.cc
index 59d9a56..3536c2c 100644
--- a/net/http/http_auth_handler_basic_unittest.cc
+++ b/net/http/http_auth_handler_basic_unittest.cc
@@ -25,12 +25,12 @@ TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) {
{ L"", L"", "Basic Og==" },
};
GURL origin("http://www.example.com");
+ HttpAuthHandlerBasic::Factory factory;
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
std::string challenge = "Basic realm=\"Atlantis\"";
- scoped_refptr<HttpAuthHandlerBasic> basic = new HttpAuthHandlerBasic;
- bool ok = basic->InitFromChallenge(challenge.begin(), challenge.end(),
- HttpAuth::AUTH_SERVER, origin);
- EXPECT_TRUE(ok);
+ scoped_refptr<HttpAuthHandler> basic = new HttpAuthHandlerBasic;
+ EXPECT_EQ(OK, factory.CreateAuthHandlerFromString(
+ challenge, HttpAuth::AUTH_SERVER, origin, &basic));
std::string credentials;
int rv = basic->GenerateAuthToken(tests[i].username,
tests[i].password,
@@ -45,32 +45,33 @@ TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) {
TEST(HttpAuthHandlerBasicTest, InitFromChallenge) {
static const struct {
const char* challenge;
- bool expected_success;
+ int expected_rv;
const char* expected_realm;
} tests[] = {
// No realm (we allow this even though realm is supposed to be required
// according to RFC 2617.)
{
"Basic",
- true,
+ OK,
"",
},
// Realm is empty string.
{
"Basic realm=\"\"",
- true,
+ OK,
"",
},
};
+ HttpAuthHandlerBasic::Factory factory;
GURL origin("http://www.example.com");
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
std::string challenge = tests[i].challenge;
- scoped_refptr<HttpAuthHandlerBasic> basic = new HttpAuthHandlerBasic;
- bool ok = basic->InitFromChallenge(challenge.begin(), challenge.end(),
- HttpAuth::AUTH_SERVER, origin);
- EXPECT_EQ(tests[i].expected_success, ok);
- if (ok)
+ scoped_refptr<HttpAuthHandler> basic = new HttpAuthHandlerBasic;
+ int rv = factory.CreateAuthHandlerFromString(
+ challenge, HttpAuth::AUTH_SERVER, origin, &basic);
+ EXPECT_EQ(tests[i].expected_rv, rv);
+ if (rv == OK)
EXPECT_EQ(tests[i].expected_realm, basic->realm());
}
}
diff --git a/net/http/http_auth_handler_digest.cc b/net/http/http_auth_handler_digest.cc
index 10af291..9441ba8 100644
--- a/net/http/http_auth_handler_digest.cc
+++ b/net/http/http_auth_handler_digest.cc
@@ -216,8 +216,7 @@ std::string HttpAuthHandlerDigest::AssembleCredentials(
// send the realm (See http://crbug.com/20984 for an instance where a
// webserver was not sending the realm with a BASIC challenge).
bool HttpAuthHandlerDigest::ParseChallenge(
- std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) {
+ HttpAuth::ChallengeTokenizer* challenge) {
scheme_ = "digest";
score_ = 2;
properties_ = ENCRYPTS_IDENTITY;
@@ -228,24 +227,23 @@ bool HttpAuthHandlerDigest::ParseChallenge(
qop_ = QOP_UNSPECIFIED;
realm_ = nonce_ = domain_ = opaque_ = std::string();
- HttpAuth::ChallengeTokenizer props(challenge_begin, challenge_end);
-
- if (!props.valid() || !LowerCaseEqualsASCII(props.scheme(), "digest"))
+ if (!challenge->valid() ||
+ !LowerCaseEqualsASCII(challenge->scheme(), "digest"))
return false; // FAIL -- Couldn't match auth-scheme.
// Loop through all the properties.
- while (props.GetNext()) {
- if (props.value().empty()) {
+ while (challenge->GetNext()) {
+ if (challenge->value().empty()) {
DLOG(INFO) << "Invalid digest property";
return false;
}
- if (!ParseChallengeProperty(props.name(), props.unquoted_value()))
+ if (!ParseChallengeProperty(challenge->name(), challenge->unquoted_value()))
return false; // FAIL -- couldn't parse a property.
}
// Check if tokenizer failed.
- if (!props.valid())
+ if (!challenge->valid())
return false; // FAIL
// Check that a minimum set of properties were provided.
@@ -295,4 +293,24 @@ bool HttpAuthHandlerDigest::ParseChallengeProperty(const std::string& name,
return true;
}
+HttpAuthHandlerDigest::Factory::Factory() {
+}
+
+HttpAuthHandlerDigest::Factory::~Factory() {
+}
+
+int HttpAuthHandlerDigest::Factory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ // TODO(cbentzel): Move towards model of parsing in the factory
+ // method and only constructing when valid.
+ scoped_refptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerDigest());
+ if (!tmp_handler->InitFromChallenge(challenge, target, origin))
+ return ERR_INVALID_RESPONSE;
+ handler->swap(tmp_handler);
+ return OK;
+}
+
} // namespace net
diff --git a/net/http/http_auth_handler_digest.h b/net/http/http_auth_handler_digest.h
index 686f354..f718a14 100644
--- a/net/http/http_auth_handler_digest.h
+++ b/net/http/http_auth_handler_digest.h
@@ -6,6 +6,7 @@
#define NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_
#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
// This is needed for the FRIEND_TEST() macro.
#include "testing/gtest/include/gtest/gtest_prod.h"
@@ -15,6 +16,17 @@ namespace net {
// Code for handling http digest authentication.
class HttpAuthHandlerDigest : public HttpAuthHandler {
public:
+ class Factory : public HttpAuthHandlerFactory {
+ public:
+ Factory();
+ virtual ~Factory();
+
+ virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler);
+ };
+
virtual int GenerateAuthToken(const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
@@ -26,10 +38,9 @@ class HttpAuthHandlerDigest : public HttpAuthHandler {
std::string* auth_token);
protected:
- virtual bool Init(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) {
+ virtual bool Init(HttpAuth::ChallengeTokenizer* challenge) {
nonce_count_ = 0;
- return ParseChallenge(challenge_begin, challenge_end);
+ return ParseChallenge(challenge);
}
private:
@@ -62,8 +73,7 @@ class HttpAuthHandlerDigest : public HttpAuthHandler {
// Parse the challenge, saving the results into this instance.
// Returns true on success.
- bool ParseChallenge(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end);
+ bool ParseChallenge(HttpAuth::ChallengeTokenizer* challenge);
// Parse an individual property. Returns true on success.
bool ParseChallengeProperty(const std::string& name,
diff --git a/net/http/http_auth_handler_digest_unittest.cc b/net/http/http_auth_handler_digest_unittest.cc
index eb5649b..e75ada4 100644
--- a/net/http/http_auth_handler_digest_unittest.cc
+++ b/net/http/http_auth_handler_digest_unittest.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.
@@ -104,7 +104,8 @@ TEST(HttpAuthHandlerDigestTest, ParseChallenge) {
std::string challenge(tests[i].challenge);
scoped_refptr<HttpAuthHandlerDigest> digest = new HttpAuthHandlerDigest;
- bool ok = digest->ParseChallenge(challenge.begin(), challenge.end());
+ HttpAuth::ChallengeTokenizer tok(challenge.begin(), challenge.end());
+ bool ok = digest->ParseChallenge(&tok);
EXPECT_EQ(tests[i].parsed_success, ok);
EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str());
@@ -252,8 +253,8 @@ TEST(HttpAuthHandlerDigestTest, AssembleCredentials) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
scoped_refptr<HttpAuthHandlerDigest> digest = new HttpAuthHandlerDigest;
std::string challenge = tests[i].challenge;
- EXPECT_TRUE(digest->InitFromChallenge(
- challenge.begin(), challenge.end(), HttpAuth::AUTH_SERVER, origin));
+ HttpAuth::ChallengeTokenizer tok(challenge.begin(), challenge.end());
+ EXPECT_TRUE(digest->InitFromChallenge(&tok, HttpAuth::AUTH_SERVER, origin));
std::string creds = digest->AssembleCredentials(tests[i].req_method,
tests[i].req_path, tests[i].username, tests[i].password,
diff --git a/net/http/http_auth_handler_factory.cc b/net/http/http_auth_handler_factory.cc
new file mode 100644
index 0000000..36f1fcf
--- /dev/null
+++ b/net/http/http_auth_handler_factory.cc
@@ -0,0 +1,82 @@
+// 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.
+
+#include "net/http/http_auth_handler_factory.h"
+
+#include "base/stl_util-inl.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"
+#include "net/http/http_auth_handler_ntlm.h"
+
+namespace net {
+
+int HttpAuthHandlerFactory::CreateAuthHandlerFromString(
+ const std::string& challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ HttpAuth::ChallengeTokenizer props(challenge.begin(), challenge.end());
+ return CreateAuthHandler(&props, target, origin, handler);
+}
+
+// static
+HttpAuthHandlerFactory* HttpAuthHandlerFactory::CreateDefault() {
+ HttpAuthHandlerRegistryFactory* registry_factory =
+ new HttpAuthHandlerRegistryFactory();
+ registry_factory->RegisterSchemeFactory(
+ "basic", new HttpAuthHandlerBasic::Factory());
+ registry_factory->RegisterSchemeFactory(
+ "digest", new HttpAuthHandlerDigest::Factory());
+ registry_factory->RegisterSchemeFactory(
+ "negotiate", new HttpAuthHandlerNegotiate::Factory());
+ registry_factory->RegisterSchemeFactory(
+ "ntlm", new HttpAuthHandlerNTLM::Factory());
+ return registry_factory;
+}
+
+HttpAuthHandlerRegistryFactory::HttpAuthHandlerRegistryFactory() {
+}
+
+HttpAuthHandlerRegistryFactory::~HttpAuthHandlerRegistryFactory() {
+ STLDeleteContainerPairSecondPointers(factory_map_.begin(),
+ factory_map_.end());
+}
+
+void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory(
+ const std::string& scheme,
+ HttpAuthHandlerFactory* factory) {
+ std::string lower_scheme = StringToLowerASCII(scheme);
+ FactoryMap::iterator it = factory_map_.find(lower_scheme);
+ if (it != factory_map_.end()) {
+ delete it->second;
+ }
+ if (factory)
+ factory_map_[lower_scheme] = factory;
+ else
+ factory_map_.erase(it);
+}
+
+int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ if (!challenge->valid()) {
+ *handler = NULL;
+ return ERR_INVALID_RESPONSE;
+ }
+ std::string lower_scheme = StringToLowerASCII(challenge->scheme());
+ FactoryMap::iterator it = factory_map_.find(lower_scheme);
+ if (it == factory_map_.end()) {
+ *handler = NULL;
+ return ERR_UNSUPPORTED_AUTH_SCHEME;
+ }
+ DCHECK(it->second);
+ return it->second->CreateAuthHandler(challenge, target, origin, handler);
+}
+
+} // namespace net
diff --git a/net/http/http_auth_handler_factory.h b/net/http/http_auth_handler_factory.h
new file mode 100644
index 0000000..d0fec29
--- /dev/null
+++ b/net/http/http_auth_handler_factory.h
@@ -0,0 +1,96 @@
+// 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.
+
+#ifndef NET_HTTP_HTTP_AUTH_HANDLER_FACTORY_H
+#define NET_HTTP_HTTP_AUTH_HANDLER_FACTORY_H
+
+#include <map>
+
+#include "net/http/http_auth.h"
+
+class GURL;
+
+namespace net {
+
+class HttpAuthHandler;
+
+// An HttpAuthHandlerFactory is used to create HttpAuthHandler objects.
+class HttpAuthHandlerFactory {
+ public:
+ HttpAuthHandlerFactory() {}
+ virtual ~HttpAuthHandlerFactory() {}
+
+ // Creates an HttpAuthHandler object based on the authentication
+ // challenge specified by |*challenge|. |challenge| must point to a valid
+ // non-NULL tokenizer.
+ //
+ // If an HttpAuthHandler object is successfully created it is passed back to
+ // the caller through |*handler| and OK is returned.
+ //
+ // If |*challenge| specifies an unsupported authentication scheme, |*handler|
+ // is set to NULL and ERR_UNSUPPORTED_AUTH_SCHEME is returned.
+ //
+ // If |*challenge| is improperly formed, |*handler| is set to NULL and
+ // ERR_INVALID_RESPONSE is returned.
+ //
+ // |*challenge| should not be reused after a call to |CreateAuthHandler()|,
+ virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) = 0;
+
+ // Creates an HTTP authentication handler based on the authentication
+ // challenge string |challenge|.
+ // This is a convenience function which creates a ChallengeTokenizer for
+ // |challenge| and calls |CreateAuthHandler|. See |CreateAuthHandler| for
+ // more details on return values.
+ int CreateAuthHandlerFromString(const std::string& challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler);
+
+ // Creates a standard HttpAuthHandlerFactory. The caller is responsible
+ // for deleting the factory.
+ // The default factory support Basic, Digest, NTLM, and Negotiate schemes.
+ static HttpAuthHandlerFactory* CreateDefault();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HttpAuthHandlerFactory);
+};
+
+// The HttpAuthHandlerRegistryFactory dispatches create requests out
+// to other factories based on the auth scheme.
+class HttpAuthHandlerRegistryFactory : public HttpAuthHandlerFactory {
+ public:
+ HttpAuthHandlerRegistryFactory();
+ virtual ~HttpAuthHandlerRegistryFactory();
+
+ // Registers a |factory| that will be used for a particular HTTP
+ // authentication scheme such as Basic, Digest, or Negotiate.
+ // The |*factory| object is assumed to be new-allocated, and its lifetime
+ // will be managed by this HttpAuthHandlerRegistryFactory object (including
+ // deleting it when it is no longer used.
+ // A NULL |factory| value means that HttpAuthHandlers's will not be created
+ // for |scheme|. If a factory object used to exist for |scheme|, it will be
+ // deleted.
+ void RegisterSchemeFactory(const std::string& scheme,
+ HttpAuthHandlerFactory* factory);
+
+ // Creates an auth handler by dispatching out to the registered factories
+ // based on the first token in |challenge|.
+ virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler);
+
+ private:
+ typedef std::map<std::string, HttpAuthHandlerFactory*> FactoryMap;
+
+ FactoryMap factory_map_;
+ DISALLOW_COPY_AND_ASSIGN(HttpAuthHandlerRegistryFactory);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_HTTP_AUTH_HANDLER_FACTORY_H
diff --git a/net/http/http_auth_handler_factory_unittest.cc b/net/http/http_auth_handler_factory_unittest.cc
new file mode 100644
index 0000000..e67bcca
--- /dev/null
+++ b/net/http/http_auth_handler_factory_unittest.cc
@@ -0,0 +1,177 @@
+// 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.
+
+#include "base/scoped_ptr.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory {
+ public:
+ explicit MockHttpAuthHandlerFactory(int return_code) :
+ return_code_(return_code) {}
+ virtual ~MockHttpAuthHandlerFactory() {}
+
+ virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ *handler = NULL;
+ return return_code_;
+ }
+
+ private:
+ int return_code_;
+};
+
+TEST(HttpAuthHandlerFactoryTest, RegistryFactory) {
+ HttpAuthHandlerRegistryFactory registry_factory;
+ GURL gurl("www.google.com");
+ const int kBasicReturnCode = ERR_INVALID_SPDY_STREAM;
+ MockHttpAuthHandlerFactory* mock_factory_basic =
+ new MockHttpAuthHandlerFactory(kBasicReturnCode);
+
+ const int kDigestReturnCode = ERR_PAC_SCRIPT_FAILED;
+ MockHttpAuthHandlerFactory* mock_factory_digest =
+ new MockHttpAuthHandlerFactory(kDigestReturnCode);
+
+ const int kDigestReturnCodeReplace = ERR_SYN_REPLY_NOT_RECEIVED;
+ MockHttpAuthHandlerFactory* mock_factory_digest_replace =
+ new MockHttpAuthHandlerFactory(kDigestReturnCodeReplace);
+
+ scoped_refptr<HttpAuthHandler> handler;
+
+ // No schemes should be supported in the beginning.
+ EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
+ registry_factory.CreateAuthHandlerFromString(
+ "Basic", HttpAuth::AUTH_SERVER, gurl, &handler));
+
+ // Test what happens with a single scheme.
+ registry_factory.RegisterSchemeFactory("Basic", mock_factory_basic);
+ EXPECT_EQ(kBasicReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "Basic", HttpAuth::AUTH_SERVER, gurl, &handler));
+ EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
+ registry_factory.CreateAuthHandlerFromString(
+ "Digest", HttpAuth::AUTH_SERVER, gurl, &handler));
+
+ // Test multiple schemes
+ registry_factory.RegisterSchemeFactory("Digest", mock_factory_digest);
+ EXPECT_EQ(kBasicReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "Basic", HttpAuth::AUTH_SERVER, gurl, &handler));
+ EXPECT_EQ(kDigestReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "Digest", HttpAuth::AUTH_SERVER, gurl, &handler));
+
+ // Test case-insensitivity
+ EXPECT_EQ(kBasicReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "basic", HttpAuth::AUTH_SERVER, gurl, &handler));
+
+ // Test replacement of existing auth scheme
+ registry_factory.RegisterSchemeFactory("Digest", mock_factory_digest_replace);
+ EXPECT_EQ(kBasicReturnCode,
+ registry_factory.CreateAuthHandlerFromString(
+ "Basic", HttpAuth::AUTH_SERVER, gurl, &handler));
+ EXPECT_EQ(kDigestReturnCodeReplace,
+ registry_factory.CreateAuthHandlerFromString(
+ "Digest", HttpAuth::AUTH_SERVER, gurl, &handler));
+}
+
+TEST(HttpAuthHandlerFactoryTest, DefaultFactory) {
+ scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory(
+ HttpAuthHandlerFactory::CreateDefault());
+
+ GURL server_origin("http://www.example.com");
+ GURL proxy_origin("http://cache.example.com:3128");
+ {
+ scoped_refptr<HttpAuthHandler> handler;
+ int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
+ "Basic realm=\"FooBar\"",
+ HttpAuth::AUTH_SERVER,
+ server_origin,
+ &handler);
+ EXPECT_EQ(OK, rv);
+ EXPECT_FALSE(handler.get() == NULL);
+ EXPECT_STREQ("basic", handler->scheme().c_str());
+ EXPECT_STREQ("FooBar", handler->realm().c_str());
+ EXPECT_EQ(HttpAuth::AUTH_SERVER, handler->target());
+ EXPECT_FALSE(handler->encrypts_identity());
+ EXPECT_FALSE(handler->is_connection_based());
+ }
+ {
+ scoped_refptr<HttpAuthHandler> handler;
+ int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
+ "UNSUPPORTED realm=\"FooBar\"",
+ HttpAuth::AUTH_SERVER,
+ server_origin,
+ &handler);
+ EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME, rv);
+ EXPECT_TRUE(handler.get() == NULL);
+ }
+ {
+ scoped_refptr<HttpAuthHandler> handler;
+ int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
+ "Digest realm=\"FooBar\", nonce=\"xyz\"",
+ HttpAuth::AUTH_PROXY,
+ proxy_origin,
+ &handler);
+ EXPECT_EQ(OK, rv);
+ EXPECT_FALSE(handler.get() == NULL);
+ EXPECT_STREQ("digest", handler->scheme().c_str());
+ EXPECT_STREQ("FooBar", handler->realm().c_str());
+ EXPECT_EQ(HttpAuth::AUTH_PROXY, handler->target());
+ EXPECT_TRUE(handler->encrypts_identity());
+ EXPECT_FALSE(handler->is_connection_based());
+ }
+ {
+ scoped_refptr<HttpAuthHandler> handler;
+ int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
+ "NTLM",
+ HttpAuth::AUTH_SERVER,
+ server_origin,
+ &handler);
+ EXPECT_EQ(OK, rv);
+ EXPECT_FALSE(handler.get() == NULL);
+ EXPECT_STREQ("ntlm", handler->scheme().c_str());
+ EXPECT_STREQ("", handler->realm().c_str());
+ EXPECT_EQ(HttpAuth::AUTH_SERVER, handler->target());
+ EXPECT_TRUE(handler->encrypts_identity());
+ EXPECT_TRUE(handler->is_connection_based());
+ }
+#if defined(OS_WIN)
+ {
+ scoped_refptr<HttpAuthHandler> handler;
+ int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
+ "Negotiate",
+ HttpAuth::AUTH_SERVER,
+ server_origin,
+ &handler);
+ EXPECT_EQ(OK, rv);
+ EXPECT_FALSE(handler.get() == NULL);
+ EXPECT_STREQ("negotiate", handler->scheme().c_str());
+ EXPECT_STREQ("", handler->realm().c_str());
+ EXPECT_EQ(HttpAuth::AUTH_SERVER, handler->target());
+ EXPECT_TRUE(handler->encrypts_identity());
+ EXPECT_TRUE(handler->is_connection_based());
+ }
+#else // !defined(OS_WIN)
+ {
+ scoped_refptr<HttpAuthHandler> handler;
+ int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
+ "Negotiate",
+ HttpAuth::AUTH_SERVER,
+ server_origin,
+ &handler);
+ EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME, rv);
+ EXPECT_TRUE(handler.get() == NULL);
+ }
+#endif // !defined(OS_WIN)
+}
+
+} // namespace net
diff --git a/net/http/http_auth_handler_negotiate.cc b/net/http/http_auth_handler_negotiate.cc
new file mode 100644
index 0000000..1e99c71
--- /dev/null
+++ b/net/http/http_auth_handler_negotiate.cc
@@ -0,0 +1,15 @@
+// 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.
+
+#include "net/http/http_auth_handler_negotiate.h"
+
+namespace net {
+
+HttpAuthHandlerNegotiate::Factory::Factory() {
+}
+
+HttpAuthHandlerNegotiate::Factory::~Factory() {
+}
+
+} // namespace net
diff --git a/net/http/http_auth_handler_negotiate.h b/net/http/http_auth_handler_negotiate.h
index b057f5c..c8e5585 100644
--- a/net/http/http_auth_handler_negotiate.h
+++ b/net/http/http_auth_handler_negotiate.h
@@ -10,6 +10,7 @@
#include <string>
#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
#if defined(OS_WIN)
#include "net/http/http_auth_sspi_win.h"
@@ -24,6 +25,17 @@ namespace net {
class HttpAuthHandlerNegotiate : public HttpAuthHandler {
public:
+ class Factory : public HttpAuthHandlerFactory {
+ public:
+ Factory();
+ virtual ~Factory();
+
+ virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler);
+ };
+
HttpAuthHandlerNegotiate();
virtual bool NeedsIdentity();
@@ -43,8 +55,7 @@ class HttpAuthHandlerNegotiate : public HttpAuthHandler {
std::string* auth_token);
protected:
- virtual bool Init(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end);
+ virtual bool Init(HttpAuth::ChallengeTokenizer* challenge);
private:
~HttpAuthHandlerNegotiate();
diff --git a/net/http/http_auth_handler_negotiate_posix.cc b/net/http/http_auth_handler_negotiate_posix.cc
index f70b58b..40ab439 100644
--- a/net/http/http_auth_handler_negotiate_posix.cc
+++ b/net/http/http_auth_handler_negotiate_posix.cc
@@ -37,8 +37,7 @@ bool HttpAuthHandlerNegotiate::AllowDefaultCredentials() {
return false;
}
-bool HttpAuthHandlerNegotiate::Init(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) {
+bool HttpAuthHandlerNegotiate::Init(HttpAuth::ChallengeTokenizer* tok) {
return false;
}
@@ -62,4 +61,12 @@ int HttpAuthHandlerNegotiate::GenerateDefaultAuthToken(
return ERR_NOT_IMPLEMENTED;
}
+int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ return ERR_UNSUPPORTED_AUTH_SCHEME;
+}
+
} // namespace net
diff --git a/net/http/http_auth_handler_negotiate_win.cc b/net/http/http_auth_handler_negotiate_win.cc
index c005590..917fc1d 100644
--- a/net/http/http_auth_handler_negotiate_win.cc
+++ b/net/http/http_auth_handler_negotiate_win.cc
@@ -32,13 +32,11 @@ int HttpAuthHandlerNegotiate::GenerateAuthToken(
// The Negotiate challenge header looks like:
// WWW-Authenticate: NEGOTIATE auth-data
-bool HttpAuthHandlerNegotiate::Init(
- std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) {
+bool HttpAuthHandlerNegotiate::Init(HttpAuth::ChallengeTokenizer* challenge) {
scheme_ = "negotiate";
score_ = 4;
properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED;
- return auth_sspi_.ParseChallenge(challenge_begin, challenge_end);
+ return auth_sspi_.ParseChallenge(challenge);
}
// Require identity on first pass instead of second.
@@ -76,4 +74,18 @@ int HttpAuthHandlerNegotiate::GenerateDefaultAuthToken(
auth_token);
}
+int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ // TODO(cbentzel): Move towards model of parsing in the factory
+ // method and only constructing when valid.
+ scoped_refptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate());
+ if (!tmp_handler->InitFromChallenge(challenge, target, origin))
+ return ERR_INVALID_RESPONSE;
+ handler->swap(tmp_handler);
+ return OK;
+}
+
} // namespace net
diff --git a/net/http/http_auth_handler_ntlm.cc b/net/http/http_auth_handler_ntlm.cc
index e191ce4..1e0c3f0 100644
--- a/net/http/http_auth_handler_ntlm.cc
+++ b/net/http/http_auth_handler_ntlm.cc
@@ -56,17 +56,6 @@ int HttpAuthHandlerNTLM::GenerateAuthToken(
if (rv != OK)
return rv;
} else {
- // Decode |auth_data_| into the input buffer.
- int len = auth_data_.length();
-
- // 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.
- while (len > 0 && len % 4 != 0 && auth_data_[len - 1] == '=')
- len--;
- auth_data_.erase(len);
-
if (!base::Base64Decode(auth_data_, &decoded_auth_data)) {
LOG(ERROR) << "Unexpected problem Base64 decoding.";
return ERR_UNEXPECTED;
@@ -97,33 +86,45 @@ int HttpAuthHandlerNTLM::GenerateAuthToken(
// The NTLM challenge header looks like:
// WWW-Authenticate: NTLM auth-data
bool HttpAuthHandlerNTLM::ParseChallenge(
- std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) {
+ HttpAuth::ChallengeTokenizer* tok) {
scheme_ = "ntlm";
score_ = 3;
properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED;
#if defined(NTLM_SSPI)
- return auth_sspi_.ParseChallenge(challenge_begin, challenge_end);
+ return auth_sspi_.ParseChallenge(tok);
#else
auth_data_.clear();
// Verify the challenge's auth-scheme.
- HttpAuth::ChallengeTokenizer challenge_tok(challenge_begin, challenge_end);
- if (!challenge_tok.valid() ||
- !LowerCaseEqualsASCII(challenge_tok.scheme(), "ntlm"))
+ if (!tok->valid() || !LowerCaseEqualsASCII(tok->scheme(), "ntlm"))
return false;
- // Extract the auth-data. We can't use challenge_tok.GetNext() because
- // auth-data is base64-encoded and may contain '=' padding at the end,
- // which would be mistaken for a name=value pair.
- challenge_begin += 4; // Skip over "NTLM".
- HttpUtil::TrimLWS(&challenge_begin, &challenge_end);
+ tok->set_expect_base64_token(true);
+ if (tok->GetNext())
+ auth_data_.assign(tok->value_begin(), tok->value_end());
+ return true;
+#endif // defined(NTLM_SSPI)
+}
+
+HttpAuthHandlerNTLM::Factory::Factory() {
+}
- auth_data_.assign(challenge_begin, challenge_end);
+HttpAuthHandlerNTLM::Factory::~Factory() {
+}
- return true;
-#endif
+int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ // TODO(cbentzel): Move towards model of parsing in the factory
+ // method and only constructing when valid.
+ scoped_refptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNTLM());
+ if (!tmp_handler->InitFromChallenge(challenge, target, origin))
+ return ERR_INVALID_RESPONSE;
+ handler->swap(tmp_handler);
+ return OK;
}
} // namespace net
diff --git a/net/http/http_auth_handler_ntlm.h b/net/http/http_auth_handler_ntlm.h
index c4b9dab..759d3a2 100644
--- a/net/http/http_auth_handler_ntlm.h
+++ b/net/http/http_auth_handler_ntlm.h
@@ -27,12 +27,24 @@
#include "base/basictypes.h"
#include "base/string16.h"
#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
namespace net {
// Code for handling HTTP NTLM authentication.
class HttpAuthHandlerNTLM : public HttpAuthHandler {
public:
+ class Factory : public HttpAuthHandlerFactory {
+ public:
+ Factory();
+ virtual ~Factory();
+
+ virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler);
+ };
+
#if defined(NTLM_PORTABLE)
// A function that generates n random bytes in the output buffer.
typedef void (*GenerateRandomProc)(uint8* output, size_t n);
@@ -81,9 +93,8 @@ class HttpAuthHandlerNTLM : public HttpAuthHandler {
std::string* auth_token);
protected:
- virtual bool Init(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) {
- return ParseChallenge(challenge_begin, challenge_end);
+ virtual bool Init(HttpAuth::ChallengeTokenizer* tok) {
+ return ParseChallenge(tok);
}
// This function acquires a credentials handle in the SSPI implementation.
@@ -102,8 +113,7 @@ class HttpAuthHandlerNTLM : public HttpAuthHandler {
// Parse the challenge, saving the results into this instance.
// Returns true on success.
- bool ParseChallenge(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end);
+ bool ParseChallenge(HttpAuth::ChallengeTokenizer* tok);
// Given an input token received from the server, generate the next output
// token to be sent to the server.
diff --git a/net/http/http_auth_sspi_win.cc b/net/http/http_auth_sspi_win.cc
index c858d36..d8a22c2 100644
--- a/net/http/http_auth_sspi_win.cc
+++ b/net/http/http_auth_sspi_win.cc
@@ -129,30 +129,19 @@ void HttpAuthSSPI::ResetSecurityContext() {
}
}
-bool HttpAuthSSPI::ParseChallenge(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end) {
+bool HttpAuthSSPI::ParseChallenge(HttpAuth::ChallengeTokenizer* tok) {
// Verify the challenge's auth-scheme.
- HttpAuth::ChallengeTokenizer challenge_tok(challenge_begin, challenge_end);
- if (!challenge_tok.valid() ||
- !LowerCaseEqualsASCII(challenge_tok.scheme(),
- StringToLowerASCII(scheme_).c_str()))
+ if (!tok->valid() ||
+ !LowerCaseEqualsASCII(tok->scheme(), StringToLowerASCII(scheme_).c_str()))
return false;
- // Extract the auth-data. We can't use challenge_tok.GetNext() because
- // auth-data is base64-encoded and may contain '=' padding at the end,
- // which would be mistaken for a name=value pair.
- challenge_begin += scheme_.length(); // Skip over scheme name.
- HttpUtil::TrimLWS(&challenge_begin, &challenge_end);
- std::string encoded_auth_token(challenge_begin, challenge_end);
- int encoded_length = encoded_auth_token.length();
- // 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.
- while (encoded_length > 0 && encoded_length % 4 != 0 &&
- encoded_auth_token[encoded_length - 1] == '=')
- encoded_length--;
- encoded_auth_token.erase(encoded_length);
+ tok->set_expect_base64_token(true);
+ if (!tok->GetNext()) {
+ decoded_server_auth_token_.clear();
+ return true;
+ }
+
+ std::string encoded_auth_token = tok->value();
std::string decoded_auth_token;
bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token);
if (!base64_rv) {
diff --git a/net/http/http_auth_sspi_win.h b/net/http/http_auth_sspi_win.h
index b94ffbc..526e25b 100644
--- a/net/http/http_auth_sspi_win.h
+++ b/net/http/http_auth_sspi_win.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 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.
@@ -16,6 +16,8 @@
#include <string>
+#include "net/http/http_auth.h"
+
class GURL;
namespace net {
@@ -32,8 +34,7 @@ class HttpAuthSSPI {
bool NeedsIdentity() const;
bool IsFinalRound() const;
- bool ParseChallenge(std::string::const_iterator challenge_begin,
- std::string::const_iterator challenge_end);
+ bool ParseChallenge(HttpAuth::ChallengeTokenizer* tok);
// Generates an authentication token.
// The return value is an error code. If it's not |OK|, the value of
diff --git a/net/http/http_auth_unittest.cc b/net/http/http_auth_unittest.cc
index a960d70..14308a0 100644
--- a/net/http/http_auth_unittest.cc
+++ b/net/http/http_auth_unittest.cc
@@ -1,12 +1,14 @@
-// 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.
#include "testing/gtest/include/gtest/gtest.h"
#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
@@ -69,6 +71,9 @@ TEST(HttpAuthTest, ChooseBestChallenge) {
};
GURL origin("http://www.example.com");
+ scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory(
+ HttpAuthHandlerFactory::CreateDefault());
+
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
// Make a HttpResponseHeaders object.
std::string headers_with_status_line("HTTP/1.1 401 Unauthorized\n");
@@ -80,7 +85,8 @@ TEST(HttpAuthTest, ChooseBestChallenge) {
headers_with_status_line.length())));
scoped_refptr<HttpAuthHandler> handler;
- HttpAuth::ChooseBestChallenge(headers.get(),
+ HttpAuth::ChooseBestChallenge(http_auth_handler_factory.get(),
+ headers.get(),
HttpAuth::AUTH_SERVER,
origin,
&handler);
@@ -122,6 +128,9 @@ TEST(HttpAuthTest, ChooseBestChallengeConnectionBased) {
GURL origin("http://www.example.com");
scoped_refptr<HttpAuthHandler> handler;
+ scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory(
+ HttpAuthHandlerFactory::CreateDefault());
+
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
// Make a HttpResponseHeaders object.
std::string headers_with_status_line("HTTP/1.1 401 Unauthorized\n");
@@ -133,7 +142,8 @@ TEST(HttpAuthTest, ChooseBestChallengeConnectionBased) {
headers_with_status_line.length())));
scoped_refptr<HttpAuthHandler> old_handler = handler;
- HttpAuth::ChooseBestChallenge(headers.get(),
+ HttpAuth::ChooseBestChallenge(http_auth_handler_factory.get(),
+ headers.get(),
HttpAuth::AUTH_SERVER,
origin,
&handler);
@@ -230,6 +240,20 @@ TEST(HttpAuthTest, ChallengeTokenizerNoProperty) {
EXPECT_FALSE(challenge.GetNext());
}
+// Use a challenge with Base64 encoded token.
+TEST(HttpAuthTest, ChallengeTokenizerBase64) {
+ std::string challenge_str = "NTLM SGVsbG8sIFdvcmxkCg===";
+ HttpAuth::ChallengeTokenizer challenge(challenge_str.begin(),
+ challenge_str.end());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("NTLM"), challenge.scheme());
+ challenge.set_expect_base64_token(true);
+ EXPECT_TRUE(challenge.GetNext());
+ // Notice the two equal statements below due to padding removal.
+ EXPECT_EQ(std::string("SGVsbG8sIFdvcmxkCg=="), challenge.value());
+ EXPECT_FALSE(challenge.GetNext());
+}
+
TEST(HttpAuthTest, GetChallengeHeaderName) {
std::string name;
@@ -250,56 +274,4 @@ TEST(HttpAuthTest, GetAuthorizationHeaderName) {
EXPECT_STREQ("Proxy-Authorization", name.c_str());
}
-TEST(HttpAuthTest, CreateAuthHandler) {
- GURL server_origin("http://www.example.com");
- GURL proxy_origin("http://cache.example.com:3128");
- {
- scoped_refptr<HttpAuthHandler> handler;
- HttpAuth::CreateAuthHandler("Basic realm=\"FooBar\"",
- HttpAuth::AUTH_SERVER,
- server_origin,
- &handler);
- EXPECT_FALSE(handler.get() == NULL);
- EXPECT_STREQ("basic", handler->scheme().c_str());
- EXPECT_STREQ("FooBar", handler->realm().c_str());
- EXPECT_EQ(HttpAuth::AUTH_SERVER, handler->target());
- EXPECT_FALSE(handler->encrypts_identity());
- EXPECT_FALSE(handler->is_connection_based());
- }
- {
- scoped_refptr<HttpAuthHandler> handler;
- HttpAuth::CreateAuthHandler("UNSUPPORTED realm=\"FooBar\"",
- HttpAuth::AUTH_SERVER,
- server_origin,
- &handler);
- EXPECT_TRUE(handler.get() == NULL);
- }
- {
- scoped_refptr<HttpAuthHandler> handler;
- HttpAuth::CreateAuthHandler("Digest realm=\"FooBar\", nonce=\"xyz\"",
- HttpAuth::AUTH_PROXY,
- proxy_origin,
- &handler);
- EXPECT_FALSE(handler.get() == NULL);
- EXPECT_STREQ("digest", handler->scheme().c_str());
- EXPECT_STREQ("FooBar", handler->realm().c_str());
- EXPECT_EQ(HttpAuth::AUTH_PROXY, handler->target());
- EXPECT_TRUE(handler->encrypts_identity());
- EXPECT_FALSE(handler->is_connection_based());
- }
- {
- scoped_refptr<HttpAuthHandler> handler;
- HttpAuth::CreateAuthHandler("NTLM",
- HttpAuth::AUTH_SERVER,
- server_origin,
- &handler);
- EXPECT_FALSE(handler.get() == NULL);
- EXPECT_STREQ("ntlm", handler->scheme().c_str());
- EXPECT_STREQ("", handler->realm().c_str());
- EXPECT_EQ(HttpAuth::AUTH_SERVER, handler->target());
- EXPECT_TRUE(handler->encrypts_identity());
- EXPECT_TRUE(handler->is_connection_based());
- }
-}
-
} // namespace net
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index b76fd07..52b9ebfb 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 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.
@@ -127,6 +127,7 @@ HttpCache::HttpCache(NetworkChangeNotifier* network_change_notifier,
HostResolver* host_resolver,
ProxyService* proxy_service,
SSLConfigService* ssl_config_service,
+ HttpAuthHandlerFactory* http_auth_handler_factory,
const FilePath& cache_dir,
int cache_size)
: disk_cache_dir_(cache_dir),
@@ -134,7 +135,7 @@ HttpCache::HttpCache(NetworkChangeNotifier* network_change_notifier,
type_(DISK_CACHE),
network_layer_(HttpNetworkLayer::CreateFactory(
network_change_notifier, host_resolver, proxy_service,
- ssl_config_service)),
+ ssl_config_service, http_auth_handler_factory)),
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
enable_range_support_(true),
cache_size_(cache_size) {
@@ -156,12 +157,13 @@ HttpCache::HttpCache(NetworkChangeNotifier* network_change_notifier,
HostResolver* host_resolver,
ProxyService* proxy_service,
SSLConfigService* ssl_config_service,
+ HttpAuthHandlerFactory* http_auth_handler_factory,
int cache_size)
: mode_(NORMAL),
type_(MEMORY_CACHE),
network_layer_(HttpNetworkLayer::CreateFactory(
network_change_notifier, host_resolver, proxy_service,
- ssl_config_service)),
+ ssl_config_service, http_auth_handler_factory)),
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
enable_range_support_(true),
cache_size_(cache_size) {
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index d85c12c..fd0c445 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -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.
@@ -35,6 +35,7 @@ class Entry;
namespace net {
class HostResolver;
+class HttpAuthHandlerFactory;
class HttpNetworkSession;
class HttpRequestInfo;
class HttpResponseInfo;
@@ -68,6 +69,7 @@ class HttpCache : public HttpTransactionFactory,
HostResolver* host_resolver,
ProxyService* proxy_service,
SSLConfigService* ssl_config_service,
+ HttpAuthHandlerFactory* http_auth_handler_factory,
const FilePath& cache_dir,
int cache_size);
@@ -87,6 +89,7 @@ class HttpCache : public HttpTransactionFactory,
HostResolver* host_resolver,
ProxyService* proxy_service,
SSLConfigService* ssl_config_service,
+ HttpAuthHandlerFactory* http_auth_handler_factory,
int cache_size);
// Initialize the cache from its component parts, which is useful for
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc
index 089807c..068b276 100644
--- a/net/http/http_network_layer.cc
+++ b/net/http/http_network_layer.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.
@@ -23,12 +23,14 @@ HttpTransactionFactory* HttpNetworkLayer::CreateFactory(
NetworkChangeNotifier* network_change_notifier,
HostResolver* host_resolver,
ProxyService* proxy_service,
- SSLConfigService* ssl_config_service) {
+ SSLConfigService* ssl_config_service,
+ HttpAuthHandlerFactory* http_auth_handler_factory) {
DCHECK(proxy_service);
return new HttpNetworkLayer(ClientSocketFactory::GetDefaultFactory(),
network_change_notifier,
- host_resolver, proxy_service, ssl_config_service);
+ host_resolver, proxy_service, ssl_config_service,
+ http_auth_handler_factory);
}
// static
@@ -47,7 +49,8 @@ HttpNetworkLayer::HttpNetworkLayer(
NetworkChangeNotifier* network_change_notifier,
HostResolver* host_resolver,
ProxyService* proxy_service,
- SSLConfigService* ssl_config_service)
+ SSLConfigService* ssl_config_service,
+ HttpAuthHandlerFactory* http_auth_handler_factory)
: socket_factory_(socket_factory),
network_change_notifier_(network_change_notifier),
host_resolver_(host_resolver),
@@ -55,6 +58,7 @@ HttpNetworkLayer::HttpNetworkLayer(
ssl_config_service_(ssl_config_service),
session_(NULL),
spdy_session_pool_(NULL),
+ http_auth_handler_factory_(http_auth_handler_factory),
suspended_(false) {
DCHECK(proxy_service_);
DCHECK(ssl_config_service_.get());
@@ -66,6 +70,7 @@ HttpNetworkLayer::HttpNetworkLayer(HttpNetworkSession* session)
ssl_config_service_(NULL),
session_(session),
spdy_session_pool_(session->spdy_session_pool()),
+ http_auth_handler_factory_(NULL),
suspended_(false) {
DCHECK(session_.get());
}
@@ -101,12 +106,14 @@ HttpNetworkSession* HttpNetworkLayer::GetSession() {
SpdySessionPool* spdy_pool = new SpdySessionPool;
session_ = new HttpNetworkSession(
network_change_notifier_, host_resolver_, proxy_service_,
- socket_factory_, ssl_config_service_, spdy_pool);
+ socket_factory_, ssl_config_service_, spdy_pool,
+ http_auth_handler_factory_);
// These were just temps for lazy-initializing HttpNetworkSession.
network_change_notifier_ = NULL;
host_resolver_ = NULL;
proxy_service_ = NULL;
socket_factory_ = NULL;
+ http_auth_handler_factory_ = NULL;
}
return session_;
}
diff --git a/net/http/http_network_layer.h b/net/http/http_network_layer.h
index 3050298..2d4130d 100644
--- a/net/http/http_network_layer.h
+++ b/net/http/http_network_layer.h
@@ -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.
@@ -15,6 +15,7 @@ namespace net {
class ClientSocketFactory;
class HostResolver;
+class HttpAuthHandlerFactory;
class HttpNetworkSession;
class NetworkChangeNotifier;
class ProxyInfo;
@@ -29,7 +30,8 @@ class HttpNetworkLayer : public HttpTransactionFactory {
HttpNetworkLayer(ClientSocketFactory* socket_factory,
NetworkChangeNotifier* network_change_notifier,
HostResolver* host_resolver, ProxyService* proxy_service,
- SSLConfigService* ssl_config_service);
+ SSLConfigService* ssl_config_service,
+ HttpAuthHandlerFactory* http_auth_handler_factory);
// Construct a HttpNetworkLayer with an existing HttpNetworkSession which
// contains a valid ProxyService.
explicit HttpNetworkLayer(HttpNetworkSession* session);
@@ -41,7 +43,8 @@ class HttpNetworkLayer : public HttpTransactionFactory {
NetworkChangeNotifier* network_change_notifier,
HostResolver* host_resolver,
ProxyService* proxy_service,
- SSLConfigService* ssl_config_service);
+ SSLConfigService* ssl_config_service,
+ HttpAuthHandlerFactory* http_auth_handler_factory);
// Create a transaction factory that instantiate a network layer over an
// existing network session. Network session contains some valuable
// information (e.g. authentication data) that we want to share across
@@ -81,6 +84,8 @@ class HttpNetworkLayer : public HttpTransactionFactory {
scoped_refptr<HttpNetworkSession> session_;
scoped_refptr<SpdySessionPool> spdy_session_pool_;
+ HttpAuthHandlerFactory* http_auth_handler_factory_;
+
bool suspended_;
static bool force_spdy_;
};
diff --git a/net/http/http_network_layer_unittest.cc b/net/http/http_network_layer_unittest.cc
index 8425304..b1b0c8a 100644
--- a/net/http/http_network_layer_unittest.cc
+++ b/net/http/http_network_layer_unittest.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.
@@ -17,7 +17,7 @@ class HttpNetworkLayerTest : public PlatformTest {
TEST_F(HttpNetworkLayerTest, CreateAndDestroy) {
net::HttpNetworkLayer factory(
NULL, NULL, new net::MockHostResolver, net::ProxyService::CreateNull(),
- new net::SSLConfigServiceDefaults);
+ new net::SSLConfigServiceDefaults, NULL);
scoped_ptr<net::HttpTransaction> trans;
int rv = factory.CreateTransaction(&trans);
@@ -28,7 +28,7 @@ TEST_F(HttpNetworkLayerTest, CreateAndDestroy) {
TEST_F(HttpNetworkLayerTest, Suspend) {
net::HttpNetworkLayer factory(
NULL, NULL, new net::MockHostResolver, net::ProxyService::CreateNull(),
- new net::SSLConfigServiceDefaults);
+ new net::SSLConfigServiceDefaults, NULL);
scoped_ptr<net::HttpTransaction> trans;
int rv = factory.CreateTransaction(&trans);
@@ -69,7 +69,8 @@ TEST_F(HttpNetworkLayerTest, GET) {
net::HttpNetworkLayer factory(&mock_socket_factory, NULL,
new net::MockHostResolver,
net::ProxyService::CreateNull(),
- new net::SSLConfigServiceDefaults);
+ new net::SSLConfigServiceDefaults,
+ NULL);
TestCompletionCallback callback;
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index f63105c..79af40f 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -1,10 +1,11 @@
-// Copyright (c) 2009 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.
#include "net/http/http_network_session.h"
#include "base/logging.h"
+#include "net/http/http_auth_handler_factory.h"
#include "net/spdy/spdy_session_pool.h"
namespace net {
@@ -25,7 +26,8 @@ HttpNetworkSession::HttpNetworkSession(
ProxyService* proxy_service,
ClientSocketFactory* client_socket_factory,
SSLConfigService* ssl_config_service,
- SpdySessionPool* spdy_session_pool)
+ SpdySessionPool* spdy_session_pool,
+ HttpAuthHandlerFactory* http_auth_handler_factory)
: network_change_notifier_(network_change_notifier),
tcp_socket_pool_(new TCPClientSocketPool(
max_sockets_, max_sockets_per_group_,
@@ -34,7 +36,8 @@ HttpNetworkSession::HttpNetworkSession(
host_resolver_(host_resolver),
proxy_service_(proxy_service),
ssl_config_service_(ssl_config_service),
- spdy_session_pool_(spdy_session_pool) {
+ spdy_session_pool_(spdy_session_pool),
+ http_auth_handler_factory_(http_auth_handler_factory) {
DCHECK(proxy_service);
DCHECK(ssl_config_service);
}
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 5049b41..3681970 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 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.
@@ -16,6 +16,7 @@
namespace net {
class ClientSocketFactory;
+class HttpAuthHandlerFactory;
class SpdySessionPool;
class NetworkChangeNotifier;
@@ -28,7 +29,8 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
ProxyService* proxy_service,
ClientSocketFactory* client_socket_factory,
SSLConfigService* ssl_config_service,
- SpdySessionPool* spdy_session_pool);
+ SpdySessionPool* spdy_session_pool,
+ HttpAuthHandlerFactory* http_auth_handler_factory);
HttpAuthCache* auth_cache() { return &auth_cache_; }
SSLClientAuthCache* ssl_client_auth_cache() {
@@ -45,6 +47,9 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
const scoped_refptr<SpdySessionPool>& spdy_session_pool() {
return spdy_session_pool_;
}
+ HttpAuthHandlerFactory* http_auth_handler_factory() {
+ return http_auth_handler_factory_;
+ }
// Replace the current socket pool with a new one. This effectively
// abandons the current pool. This is only used for debugging.
@@ -84,6 +89,7 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
scoped_refptr<ProxyService> proxy_service_;
scoped_refptr<SSLConfigService> ssl_config_service_;
scoped_refptr<SpdySessionPool> spdy_session_pool_;
+ HttpAuthHandlerFactory* http_auth_handler_factory_;
};
} // namespace net
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 7a664a0..4be611d 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -1825,8 +1825,9 @@ int HttpNetworkTransaction::HandleAuthChallenge() {
if (target != HttpAuth::AUTH_SERVER ||
!(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA)) {
// Find the best authentication challenge that we support.
- HttpAuth::ChooseBestChallenge(headers, target, auth_origin,
- &auth_handler_[target]);
+ HttpAuth::ChooseBestChallenge(session_->http_auth_handler_factory(),
+ headers, target,
+ auth_origin, &auth_handler_[target]);
}
if (!auth_handler_[target]) {
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 548ee16..3d204bf 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -42,6 +42,7 @@ class SessionDependencies {
: host_resolver(new MockHostResolver),
proxy_service(ProxyService::CreateNull()),
ssl_config_service(new SSLConfigServiceDefaults),
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
spdy_session_pool(new SpdySessionPool) {}
// Custom proxy service dependency.
@@ -49,12 +50,14 @@ class SessionDependencies {
: host_resolver(new MockHostResolver),
proxy_service(proxy_service),
ssl_config_service(new SSLConfigServiceDefaults),
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
spdy_session_pool(new SpdySessionPool) {}
scoped_refptr<MockHostResolverBase> host_resolver;
scoped_refptr<ProxyService> proxy_service;
scoped_refptr<SSLConfigService> ssl_config_service;
MockClientSocketFactory socket_factory;
+ scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
scoped_refptr<SpdySessionPool> spdy_session_pool;
};
@@ -71,7 +74,8 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
session_deps->proxy_service,
&session_deps->socket_factory,
session_deps->ssl_config_service,
- session_deps->spdy_session_pool);
+ session_deps->spdy_session_pool,
+ session_deps->http_auth_handler_factory.get());
}
class HttpNetworkTransactionTest : public PlatformTest {
diff --git a/net/net.gyp b/net/net.gyp
index 00f0615..b6f6062 100755
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -312,13 +312,16 @@
'http/http_auth.h',
'http/http_auth_cache.cc',
'http/http_auth_cache.h',
- 'http/http_auth_handler.h',
'http/http_auth_handler.cc',
+ 'http/http_auth_handler.h',
'http/http_auth_handler_basic.cc',
'http/http_auth_handler_basic.h',
'http/http_auth_handler_digest.cc',
'http/http_auth_handler_digest.h',
+ 'http/http_auth_handler_factory.cc',
+ 'http/http_auth_handler_factory.h',
'http/http_auth_handler_negotiate.h',
+ 'http/http_auth_handler_negotiate.cc',
'http/http_auth_handler_negotiate_posix.cc',
'http/http_auth_handler_negotiate_win.cc',
'http/http_auth_handler_ntlm.cc',
@@ -638,6 +641,7 @@
'http/http_auth_cache_unittest.cc',
'http/http_auth_handler_basic_unittest.cc',
'http/http_auth_handler_digest_unittest.cc',
+ 'http/http_auth_handler_factory_unittest.cc',
'http/http_auth_sspi_win_unittest.cc',
'http/http_auth_unittest.cc',
'http/http_byte_range_unittest.cc',
diff --git a/net/proxy/proxy_script_fetcher_unittest.cc b/net/proxy/proxy_script_fetcher_unittest.cc
index 741e7d4..7c38470 100644
--- a/net/proxy/proxy_script_fetcher_unittest.cc
+++ b/net/proxy/proxy_script_fetcher_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 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.
@@ -37,8 +37,10 @@ class RequestContext : public URLRequestContext {
ssl_config_service_ = new net::SSLConfigServiceDefaults;
http_transaction_factory_ =
- new net::HttpCache(net::HttpNetworkLayer::CreateFactory(
- NULL, host_resolver_, proxy_service_, ssl_config_service_),
+ new net::HttpCache(
+ net::HttpNetworkLayer::CreateFactory(
+ NULL, host_resolver_, proxy_service_, ssl_config_service_,
+ NULL),
disk_cache::CreateInMemoryCacheBackend(0));
}
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc
index aae234e..4d80df2 100644
--- a/net/socket_stream/socket_stream.cc
+++ b/net/socket_stream/socket_stream.cc
@@ -43,6 +43,7 @@ SocketStream::SocketStream(const GURL& url, Delegate* delegate)
delegate_(delegate),
max_pending_send_allowed_(kMaxPendingSendAllowed),
next_state_(STATE_NONE),
+ http_auth_handler_factory_(NULL),
factory_(ClientSocketFactory::GetDefaultFactory()),
proxy_mode_(kDirectConnection),
proxy_url_(url),
@@ -107,9 +108,10 @@ void SocketStream::set_context(URLRequestContext* context) {
}
}
- if (context_)
+ if (context_) {
host_resolver_ = context_->host_resolver();
-
+ http_auth_handler_factory_ = context_->http_auth_handler_factory();
+ }
}
void SocketStream::Connect() {
@@ -869,8 +871,9 @@ int SocketStream::HandleAuthChallenge(const HttpResponseHeaders* headers) {
}
auth_identity_.invalid = true;
- HttpAuth::ChooseBestChallenge(headers, HttpAuth::AUTH_PROXY, auth_origin,
- &auth_handler_);
+ HttpAuth::ChooseBestChallenge(http_auth_handler_factory_, headers,
+ HttpAuth::AUTH_PROXY,
+ auth_origin, &auth_handler_);
if (!auth_handler_) {
LOG(ERROR) << "Can't perform auth to the proxy " << auth_origin;
return ERR_TUNNEL_CONNECTION_FAILED;
diff --git a/net/socket_stream/socket_stream.h b/net/socket_stream/socket_stream.h
index cf6a6b0..5b1ae3e 100644
--- a/net/socket_stream/socket_stream.h
+++ b/net/socket_stream/socket_stream.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 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.
@@ -30,6 +30,7 @@ namespace net {
class AuthChallengeInfo;
class ClientSocketFactory;
class HostResolver;
+class HttpAuthHandlerFactory;
class LoadLog;
class SSLConfigService;
class SingleRequestHostResolver;
@@ -266,6 +267,7 @@ class SocketStream : public base::RefCountedThreadSafe<SocketStream> {
State next_state_;
scoped_refptr<HostResolver> host_resolver_;
+ HttpAuthHandlerFactory* http_auth_handler_factory_;
ClientSocketFactory* factory_;
ProxyMode proxy_mode_;
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index c4caf88..888685a 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -12,6 +12,7 @@
#include "net/base/ssl_config_service_defaults.h"
#include "net/base/test_completion_callback.h"
#include "net/base/upload_data.h"
+#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_transaction_unittest.h"
#include "net/proxy/proxy_config_service_fixed.h"
@@ -39,6 +40,7 @@ class SessionDependencies {
: host_resolver(new MockHostResolver),
proxy_service(CreateNullProxyService()),
ssl_config_service(new SSLConfigServiceDefaults),
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
spdy_session_pool(new SpdySessionPool) {
// Note: The CancelledTransaction test does cleanup by running all tasks
// in the message loop (RunAllPending). Unfortunately, that doesn't clean
@@ -54,12 +56,14 @@ class SessionDependencies {
: host_resolver(new MockHostResolver),
proxy_service(proxy_service),
ssl_config_service(new SSLConfigServiceDefaults),
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
spdy_session_pool(new SpdySessionPool) {}
scoped_refptr<MockHostResolverBase> host_resolver;
scoped_refptr<ProxyService> proxy_service;
scoped_refptr<SSLConfigService> ssl_config_service;
MockClientSocketFactory socket_factory;
+ scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
scoped_refptr<SpdySessionPool> spdy_session_pool;
};
@@ -76,7 +80,8 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
session_deps->proxy_service,
&session_deps->socket_factory,
session_deps->ssl_config_service,
- session_deps->spdy_session_pool);
+ session_deps->spdy_session_pool,
+ session_deps->http_auth_handler_factory.get());
}
// Chop a frame into an array of MockWrites.
diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc
index 1af987c..eb8ca5fc 100644
--- a/net/spdy/spdy_stream_unittest.cc
+++ b/net/spdy/spdy_stream_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 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.
@@ -9,6 +9,7 @@
#include "net/base/ssl_config_service.h"
#include "net/base/ssl_config_service_defaults.h"
#include "net/base/test_completion_callback.h"
+#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_info.h"
@@ -51,6 +52,7 @@ class SessionDependencies {
: host_resolver(new MockHostResolver),
proxy_service(CreateNullProxyService()),
ssl_config_service(new SSLConfigServiceDefaults),
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
spdy_session_pool(new SpdySessionPool) {}
// Custom proxy service dependency.
@@ -58,12 +60,14 @@ class SessionDependencies {
: host_resolver(new MockHostResolver),
proxy_service(proxy_service),
ssl_config_service(new SSLConfigServiceDefaults),
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
spdy_session_pool(new SpdySessionPool) {}
scoped_refptr<MockHostResolverBase> host_resolver;
scoped_refptr<ProxyService> proxy_service;
scoped_refptr<SSLConfigService> ssl_config_service;
MockClientSocketFactory socket_factory;
+ scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
scoped_refptr<SpdySessionPool> spdy_session_pool;
};
@@ -73,7 +77,8 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
session_deps->proxy_service,
&session_deps->socket_factory,
session_deps->ssl_config_service,
- session_deps->spdy_session_pool);
+ session_deps->spdy_session_pool,
+ session_deps->http_auth_handler_factory.get());
}
class SpdyStreamTest : public testing::Test {
diff --git a/net/tools/fetch/fetch_client.cc b/net/tools/fetch/fetch_client.cc
index 120b5ca..197a0454 100644
--- a/net/tools/fetch/fetch_client.cc
+++ b/net/tools/fetch/fetch_client.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 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.
@@ -15,6 +15,7 @@
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/ssl_config_service.h"
+#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_request_info.h"
@@ -139,13 +140,16 @@ int main(int argc, char**argv) {
scoped_refptr<net::SSLConfigService> ssl_config_service(
net::SSLConfigService::CreateSystemSSLConfigService());
net::HttpTransactionFactory* factory = NULL;
+ scoped_ptr<net::HttpAuthHandlerFactory> http_auth_handler_factory(
+ net::HttpAuthHandlerFactory::CreateDefault());
if (use_cache) {
factory = new net::HttpCache(NULL, host_resolver, proxy_service,
- ssl_config_service, 0);
+ ssl_config_service,
+ http_auth_handler_factory.get(), 0);
} else {
factory = new net::HttpNetworkLayer(
net::ClientSocketFactory::GetDefaultFactory(), NULL, host_resolver,
- proxy_service, ssl_config_service);
+ proxy_service, ssl_config_service, http_auth_handler_factory.get());
}
{
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h
index d72f84d..fb2608f 100644
--- a/net/url_request/url_request_context.h
+++ b/net/url_request/url_request_context.h
@@ -23,6 +23,7 @@
namespace net {
class CookiePolicy;
class FtpTransactionFactory;
+class HttpAuthHandlerFactory;
class HttpTransactionFactory;
class SocketStream;
}
@@ -77,6 +78,12 @@ class URLRequestContext :
// Gets the FTP authentication cache for this context.
net::FtpAuthCache* ftp_auth_cache() { return &ftp_auth_cache_; }
+ // Gets the HTTP Authentication Handler Factory for this context.
+ // The factory is only valid for the lifetime of this URLRequestContext
+ net::HttpAuthHandlerFactory* http_auth_handler_factory() {
+ return http_auth_handler_factory_;
+ }
+
// Gets the value of 'Accept-Charset' header field.
const std::string& accept_charset() const { return accept_charset_; }
@@ -133,6 +140,7 @@ class URLRequestContext :
scoped_refptr<net::SSLConfigService> ssl_config_service_;
net::HttpTransactionFactory* http_transaction_factory_;
net::FtpTransactionFactory* ftp_transaction_factory_;
+ net::HttpAuthHandlerFactory* http_auth_handler_factory_;
scoped_refptr<net::CookieStore> cookie_store_;
net::CookiePolicy* cookie_policy_;
scoped_refptr<net::TransportSecurityState> transport_security_state_;
diff --git a/net/url_request/url_request_unittest.h b/net/url_request/url_request_unittest.h
index 6ea2c15..e0868ff 100644
--- a/net/url_request/url_request_unittest.h
+++ b/net/url_request/url_request_unittest.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 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.
@@ -30,6 +30,7 @@
#include "net/base/ssl_config_service_defaults.h"
#include "net/disk_cache/disk_cache.h"
#include "net/ftp/ftp_network_layer.h"
+#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
#include "net/socket/ssl_test_util.h"
@@ -151,17 +152,20 @@ class TestURLRequestContext : public URLRequestContext {
virtual ~TestURLRequestContext() {
delete ftp_transaction_factory_;
delete http_transaction_factory_;
+ delete http_auth_handler_factory_;
}
private:
void Init() {
ftp_transaction_factory_ = new net::FtpNetworkLayer(host_resolver_);
ssl_config_service_ = new net::SSLConfigServiceDefaults;
+ http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault();
http_transaction_factory_ =
new net::HttpCache(
net::HttpNetworkLayer::CreateFactory(NULL, host_resolver_,
proxy_service_,
- ssl_config_service_),
+ ssl_config_service_,
+ http_auth_handler_factory_),
disk_cache::CreateInMemoryCacheBackend(0));
// In-memory cookie store.
cookie_store_ = new net::CookieMonster(NULL);