Index: net/http/http_auth_controller.h |
diff --git a/net/http/http_auth_controller.h b/net/http/http_auth_controller.h |
index 637b7227375a4320dade7af0bcfac59565ac6ee1..cbb9fee4852d51e9eef372f023fbb38a5c26766f 100644 |
--- a/net/http/http_auth_controller.h |
+++ b/net/http/http_auth_controller.h |
@@ -5,12 +5,14 @@ |
#ifndef NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
#define NET_HTTP_HTTP_AUTH_CONTROLLER_H_ |
+#include <queue> |
#include <set> |
#include <string> |
#include "base/basictypes.h" |
#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/memory/weak_ptr.h" |
#include "base/threading/non_thread_safe.h" |
#include "net/base/completion_callback.h" |
#include "net/base/net_export.h" |
@@ -28,13 +30,18 @@ class HttpAuthHandlerFactory; |
class HttpAuthCache; |
class HttpRequestHeaders; |
struct HttpRequestInfo; |
+class HttpResponseInfo; |
+// HttpAuthController handles HTTP authentication for a single authentication |
+// target during a network transaction. An authentication target is a single |
+// proxy server or a single protection space for an HTTP server as defined in |
+// http://tools.ietf.org/html/rfc7235#section-2.2. |
class NET_EXPORT_PRIVATE HttpAuthController |
: public base::RefCounted<HttpAuthController>, |
NON_EXPORTED_BASE(public base::NonThreadSafe) { |
public: |
- // The arguments are self explanatory except possibly for |auth_url|, which |
- // should be both the auth target and auth path in a single url argument. |
+ // |http_auth_cache| and |http_auth_handler_factory| should remain valid for |
+ // the lifetime of the HttpAuthController. |
HttpAuthController(HttpAuth::Target target, |
const GURL& auth_url, |
HttpAuthCache* http_auth_cache, |
@@ -44,37 +51,87 @@ class NET_EXPORT_PRIVATE HttpAuthController |
// value is a net error code. |OK| will be returned both in the case that |
// a token is correctly generated synchronously, as well as when no tokens |
// were necessary. |
- virtual int MaybeGenerateAuthToken(const HttpRequestInfo* request, |
- const CompletionCallback& callback, |
- const BoundNetLog& net_log); |
+ // TODO(asanka): Move towards model of generating tokens during |
+ // HandleAuthChallenge() and after ResetAuth() rather than just before sending |
+ // a new request. |
+ int MaybeGenerateAuthToken(const HttpRequestInfo* request, |
+ const CompletionCallback& callback, |
+ const BoundNetLog& net_log); |
+ |
+ // Checks for and handles HTTP authentication challenge headers appropriate |
+ // for |target_|. Returns OK on success. If the operation will be blocking, |
+ // returns ERR_IO_PENDING and invokes |callback| with the result. Returns a |
+ // network error code on failure (either synchronously, or via |callback|). |
+ // |
+ // The initial invocation of HandleAuthChallenge() must specify a |response| |
+ // containing an authentication challenge appropriate for the authentication |
+ // target (i.e. a 401 for AUTH_SERVER and 407 for AUTH_PROXY). Subsequent |
+ // calls to HandleAuthChallenge() must specify in |response| the server |
+ // response obtained after sending the request generated by |
+ // MaybeGenerateAuthToken() and AddAuthorizationHeader(). |
+ // |
+ // After a successful call: |
+ // * HaveAuthHandler() => |
+ // A suitable handler was found that can respond to the challenge. |
+ // |
+ // If HaveAuthHandler() is false, then HttpAuthController can't respond |
+ // to the challenge. |
+ // |
+ // * HaveAuth() => |
+ // A suitable handler was found and a suitable identity is available to |
+ // proceed with responding to the authentication challenge. |
+ // MaybeGenerateAuthToken() is likely to successfully generate a token. |
+ // |
+ // If HaveAuth() is false, then auth_info() will return an |
+ // AuthChallengeInfo that can be used to inform the acquisition of |
+ // credentials from an external source (e.g. by prompting the user). |
+ // Once credentials are available, call ResetAuth(). |
+ int HandleAuthChallenge(const HttpResponseInfo& response, |
+ const CompletionCallback& callback, |
+ const BoundNetLog& net_log); |
// Adds either the proxy auth header, or the origin server auth header, |
// as specified by |target_|. |
- virtual void AddAuthorizationHeader( |
- HttpRequestHeaders* authorization_headers); |
+ void AddAuthorizationHeader(HttpRequestHeaders* authorization_headers); |
- // Checks for and handles HTTP status code 401 or 407. |
- // |HandleAuthChallenge()| returns OK on success, or a network error code |
- // otherwise. It may also populate |auth_info_|. |
- virtual int HandleAuthChallenge(scoped_refptr<HttpResponseHeaders> headers, |
- bool do_not_send_server_auth, |
- bool establishing_tunnel, |
- const BoundNetLog& net_log); |
+ // Store the supplied |credentials| for use with the next invocation of |
+ // MaybeGenerateAuthToken(). In addition, the credentials will also be stored |
+ // in the |http_auth_cache| that was passed into the constructor, potentially |
+ // making it available for other HttpAuthControllers. |
+ // TODO(asanka): Rename to SetCredentials(). |
+ void ResetAuth(const AuthCredentials& credentials); |
- // Store the supplied credentials and prepare to restart the auth. |
- virtual void ResetAuth(const AuthCredentials& credentials); |
+ // Returns whether this HttpAuthController has an active HttpAuthHandler. |
+ bool HaveAuthHandler() const; |
- virtual bool HaveAuthHandler() const; |
+ // Returns |true| if the HttpAuthController is ready to generate an |
+ // authentication token. |
+ // TODO(asanka): Rename this to avoid confusion with HaveAuthHandler(). |
+ bool HaveAuth() const; |
- virtual bool HaveAuth() const; |
+ // TODO(asanka): Rename to auth_challenge_info(). |
+ scoped_refptr<AuthChallengeInfo> auth_info(); |
- virtual scoped_refptr<AuthChallengeInfo> auth_info(); |
+ // TODO(asanka): This method is only used by tests. Make it private once tests |
+ // are updated. |
+ bool IsAuthSchemeDisabled(const std::string& scheme) const; |
- virtual bool IsAuthSchemeDisabled(const std::string& scheme) const; |
- virtual void DisableAuthScheme(const std::string& scheme); |
- virtual void DisableEmbeddedIdentity(); |
+ // Disallow using URL embedded identities to respond to authentication |
+ // challenges. |
+ void DisableEmbeddedIdentity(); |
private: |
+ struct CandidateChallenge { |
+ std::string scheme; |
+ std::string challenge; |
+ int priority; |
+ |
+ friend bool operator<(const CandidateChallenge& left, |
+ const CandidateChallenge& right) { |
+ return left.priority < right.priority; |
+ } |
+ }; |
+ |
// Actions for InvalidateCurrentHandler() |
enum InvalidateHandlerAction { |
INVALIDATE_HANDLER_AND_CACHED_CREDENTIALS, |
@@ -82,14 +139,35 @@ class NET_EXPORT_PRIVATE HttpAuthController |
INVALIDATE_HANDLER |
}; |
- // So that we can mock this object. |
+ enum State { |
+ STATE_NONE, |
+ STATE_CHOOSE_CHALLENGE, |
+ STATE_TRY_NEXT_CHALLENGE, |
+ STATE_TRY_NEXT_CHALLENGE_COMPLETE, |
+ STATE_CHOOSE_IDENTITY, |
+ STATE_HANDLE_ANOTHER_CHALLENGE, |
+ STATE_HANDLE_ANOTHER_CHALLENGE_COMPLETE, |
+ STATE_GENERATE_TOKEN, |
+ STATE_GENERATE_TOKEN_COMPLETE, |
+ }; |
+ |
+ int DoLoop(int result); |
+ int DoChooseChallenge(); |
+ int DoTryNextChallenge(); |
+ int DoTryNextChallengeComplete(int result); |
+ int DoChooseIdentity(); |
+ int DoHandleAnotherChallenge(); |
+ int DoHandleAnotherChallengeComplete(int result); |
+ int DoGenerateToken(); |
+ int DoGenerateTokenComplete(int result); |
+ |
friend class base::RefCounted<HttpAuthController>; |
virtual ~HttpAuthController(); |
- // Searches the auth cache for an entry that encompasses the request's path. |
- // If such an entry is found, updates |identity_| and |handler_| with the |
- // cache entry's data and returns true. |
+ // Searches the auth cache for an entry that encompasses the path for the |
+ // request. If such an entry is found, updates |identity_| and |handler_| |
+ // with the cache entry's data and returns true. |
bool SelectPreemptiveAuth(const BoundNetLog& net_log); |
// Invalidates the current handler. If |action| is |
@@ -115,6 +193,10 @@ class NET_EXPORT_PRIVATE HttpAuthController |
// otherwise. |
bool DisableOnAuthHandlerResult(int result); |
+ // Disables |scheme| from being considered for handling authentication |
+ // challenges in the future. |
+ void DisableAuthScheme(const std::string& scheme); |
+ |
void OnIOComplete(int result); |
// Indicates if this handler is for Proxy auth or Server auth. |
@@ -131,13 +213,13 @@ class NET_EXPORT_PRIVATE HttpAuthController |
const std::string auth_path_; |
// |handler_| encapsulates the logic for the particular auth-scheme. |
- // This includes the challenge's parameters. If NULL, then there is no |
+ // This includes the challenge parameters. If NULL, then there is no |
// associated auth handler. |
scoped_ptr<HttpAuthHandler> handler_; |
// |identity_| holds the credentials that should be used by |
// the handler_ to generate challenge responses. This identity can come from |
- // a number of places (url, cache, prompt). |
+ // a number of places (URL, cache, prompt). |
HttpAuth::Identity identity_; |
// |auth_token_| contains the opaque string to pass to the proxy or |
@@ -165,6 +247,16 @@ class NET_EXPORT_PRIVATE HttpAuthController |
HttpAuthSchemeSet disabled_schemes_; |
CompletionCallback callback_; |
+ |
+ State next_state_ = STATE_NONE; |
+ CompletionCallback io_callback_; |
+ HttpResponseInfo const* response_info_ = nullptr; |
+ HttpRequestInfo const* request_info_ = nullptr; |
+ std::string selected_auth_challenge_; |
+ BoundNetLog net_log_; |
+ std::priority_queue<CandidateChallenge> candidate_challenges_; |
+ |
+ base::WeakPtrFactory<HttpAuthController> weak_ptr_factory_; |
}; |
} // namespace net |