| 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
|
|
|