1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_HTTP_HTTP_AUTH_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_HTTP_HTTP_AUTH_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set> 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <string> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_util.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T> class scoped_refptr; 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BoundNetLog; 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass HttpAuthHandler; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass HttpAuthHandlerFactory; 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass HttpResponseHeaders; 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Utility class for http authentication. 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass HttpAuth { 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Http authentication can be done the the proxy server, origin server, 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // or both. This enum tracks who the target is. 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum Target { 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTH_NONE = -1, 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We depend on the valid targets (!= AUTH_NONE) being usable as indexes 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // in an array, so start from 0. 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTH_PROXY = 0, 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTH_SERVER = 1, 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTH_NUM_TARGETS = 2, 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // What the HTTP WWW-Authenticate/Proxy-Authenticate headers indicate about 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // the previous authorization attempt. 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick enum AuthorizationResult { 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AUTHORIZATION_RESULT_ACCEPT, // The authorization attempt was accepted, 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // although there still may be additional 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // rounds of challenges. 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AUTHORIZATION_RESULT_REJECT, // The authorization attempt was rejected. 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AUTHORIZATION_RESULT_STALE, // (Digest) The nonce used in the 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // authorization attempt is stale, but 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // otherwise the attempt was valid. 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AUTHORIZATION_RESULT_INVALID, // The authentication challenge headers are 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // poorly formed (the authorization attempt 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // itself may have been fine). 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AUTHORIZATION_RESULT_DIFFERENT_REALM, // The authorization 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // attempt was rejected, 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // but the realm associated 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // with the new challenge 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // is different from the 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // previous attempt. 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick }; 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Describes where the identity used for authentication came from. 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum IdentitySource { 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Came from nowhere -- the identity is not initialized. 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDENT_SRC_NONE, 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The identity came from the auth cache, by doing a path-based 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // lookup (premptive authorization). 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDENT_SRC_PATH_LOOKUP, 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The identity was extracted from a URL of the form: 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://<username>:<password>@host:port 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDENT_SRC_URL, 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The identity was retrieved from the auth cache, by doing a 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // realm lookup. 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDENT_SRC_REALM_LOOKUP, 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The identity was provided by RestartWithAuth -- it likely 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // came from a prompt (or maybe the password manager). 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDENT_SRC_EXTERNAL, 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The identity used the default credentials for the computer, 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // on schemes that support single sign-on. 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDENT_SRC_DEFAULT_CREDENTIALS, 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen enum Scheme { 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AUTH_SCHEME_BASIC = 0, 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AUTH_SCHEME_DIGEST, 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AUTH_SCHEME_NTLM, 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AUTH_SCHEME_NEGOTIATE, 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AUTH_SCHEME_MOCK, 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen AUTH_SCHEME_MAX, 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Helper structure used by HttpNetworkTransaction to track 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the current identity being used for authorization. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct Identity { 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Identity(); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IdentitySource source; 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool invalid; 1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 username; 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 password; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the name of the header containing the auth challenge 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (either WWW-Authenticate or Proxy-Authenticate). 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static std::string GetChallengeHeaderName(Target target); 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the name of the header where the credentials go 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // (either Authorization or Proxy-Authorization). 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static std::string GetAuthorizationHeaderName(Target target); 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns a string representation of a Target value that can be used in log 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // messages. 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static std::string GetAuthTargetString(Target target); 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Returns a string representation of an authentication Scheme. 12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static const char* SchemeToString(Scheme scheme); 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Iterate through the challenge headers, and pick the best one that 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we support. Obtains the implementation class for handling the challenge, 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // and passes it back in |*handler|. If no supported challenge was found, 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |*handler| is set to NULL. 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |disabled_schemes| is the set of schemes that we should not use. 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |origin| is used by the NTLM and Negotiation authentication scheme to 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // construct the service principal name. It is ignored by other schemes. 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void ChooseBestChallenge( 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpAuthHandlerFactory* http_auth_handler_factory, 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseHeaders* headers, 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Target target, 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& origin, 13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::set<Scheme>& disabled_schemes, 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log, 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<HttpAuthHandler>* handler); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Handle a 401/407 response from a server/proxy after a previous 144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // authentication attempt. For connection-based authentication schemes, the 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // new response may be another round in a multi-round authentication sequence. 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // For request-based schemes, a 401/407 response is typically treated like a 147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // rejection of the previous challenge, except in the Digest case when a 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // "stale" attribute is present. 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // |handler| must be non-NULL, and is the HttpAuthHandler from the previous 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // authentication round. 152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // |headers| must be non-NULL and contain the new HTTP response. 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // 155513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // |target| specifies whether the authentication challenge response came 156513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // from a server or a proxy. 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // |disabled_schemes| are the authentication schemes to ignore. 159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // 160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // |challenge_used| is the text of the authentication challenge used in 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // support of the returned AuthorizationResult. If no headers were used for 162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the result (for example, all headers have unknown authentication schemes), 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the value is cleared. 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static AuthorizationResult HandleChallengeResponse( 1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuthHandler* handler, 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const HttpResponseHeaders* headers, 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Target target, 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::set<Scheme>& disabled_schemes, 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string* challenge_used); 1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Breaks up a challenge string into the the auth scheme and parameter list, 172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // according to RFC 2617 Sec 1.2: 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // challenge = auth-scheme 1*SP 1#auth-param 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Depending on the challenge scheme, it may be appropriate to interpret the 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // parameters as either a base-64 encoded string or a comma-delimited list 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // of name-value pairs. param_pairs() and base64_param() methods are provided 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // to support either usage. 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott class ChallengeTokenizer { 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ChallengeTokenizer(std::string::const_iterator begin, 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator end) 183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : begin_(begin), 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick end_(end), 185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scheme_begin_(begin), 186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scheme_end_(begin), 187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick params_begin_(end), 188731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick params_end_(end) { 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Init(begin, end); 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get the original text. 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string challenge_text() const { 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string(begin_, end_); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the auth scheme of the challenge. 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator scheme_begin() const { return scheme_begin_; } 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator scheme_end() const { return scheme_end_; } 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string scheme() const { 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return std::string(scheme_begin_, scheme_end_); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HttpUtil::NameValuePairsIterator param_pairs() const; 205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string base64_param() const; 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Init(std::string::const_iterator begin, 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator end); 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string::const_iterator begin_; 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string::const_iterator end_; 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator scheme_begin_; 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::const_iterator scheme_end_; 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string::const_iterator params_begin_; 218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string::const_iterator params_end_; 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_HTTP_HTTP_AUTH_H_ 225