Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Unified Diff: net/http/http_auth_controller.h

Issue 1391053002: [net/http auth] Make HttpAuthHandler challenge handling asynchronous. Base URL: https://chromium.googlesource.com/chromium/src.git@auth-handler-init-split
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/http/http_auth_cache_unittest.cc ('k') | net/http/http_auth_controller.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « net/http/http_auth_cache_unittest.cc ('k') | net/http/http_auth_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698