1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/http/http_auth_handler_mock.h" 6 7 #include "base/bind.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/strings/string_util.h" 10 #include "net/base/net_errors.h" 11 #include "net/http/http_request_info.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace net { 15 16 HttpAuthHandlerMock::HttpAuthHandlerMock() 17 : resolve_(RESOLVE_INIT), 18 weak_factory_(this), 19 generate_async_(false), 20 generate_rv_(OK), 21 auth_token_(NULL), 22 first_round_(true), 23 connection_based_(false), 24 allows_default_credentials_(false), 25 allows_explicit_credentials_(true) { 26 } 27 28 HttpAuthHandlerMock::~HttpAuthHandlerMock() { 29 } 30 31 void HttpAuthHandlerMock::SetResolveExpectation(Resolve resolve) { 32 EXPECT_EQ(RESOLVE_INIT, resolve_); 33 resolve_ = resolve; 34 } 35 36 bool HttpAuthHandlerMock::NeedsCanonicalName() { 37 switch (resolve_) { 38 case RESOLVE_SYNC: 39 case RESOLVE_ASYNC: 40 return true; 41 case RESOLVE_SKIP: 42 resolve_ = RESOLVE_TESTED; 43 return false; 44 default: 45 NOTREACHED(); 46 return false; 47 } 48 } 49 50 int HttpAuthHandlerMock::ResolveCanonicalName( 51 HostResolver* host_resolver, const CompletionCallback& callback) { 52 EXPECT_NE(RESOLVE_TESTED, resolve_); 53 int rv = OK; 54 switch (resolve_) { 55 case RESOLVE_SYNC: 56 resolve_ = RESOLVE_TESTED; 57 break; 58 case RESOLVE_ASYNC: 59 EXPECT_TRUE(callback_.is_null()); 60 rv = ERR_IO_PENDING; 61 callback_ = callback; 62 base::MessageLoop::current()->PostTask( 63 FROM_HERE, 64 base::Bind(&HttpAuthHandlerMock::OnResolveCanonicalName, 65 weak_factory_.GetWeakPtr())); 66 break; 67 default: 68 NOTREACHED(); 69 break; 70 } 71 return rv; 72 } 73 74 void HttpAuthHandlerMock::SetGenerateExpectation(bool async, int rv) { 75 generate_async_ = async; 76 generate_rv_ = rv; 77 } 78 79 HttpAuth::AuthorizationResult HttpAuthHandlerMock::HandleAnotherChallenge( 80 HttpAuth::ChallengeTokenizer* challenge) { 81 // If we receive an empty challenge for a connection based scheme, or a second 82 // challenge for a non connection based scheme, assume it's a rejection. 83 if (!is_connection_based() || challenge->base64_param().empty()) 84 return HttpAuth::AUTHORIZATION_RESULT_REJECT; 85 if (!LowerCaseEqualsASCII(challenge->scheme(), "mock")) 86 return HttpAuth::AUTHORIZATION_RESULT_INVALID; 87 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; 88 } 89 90 bool HttpAuthHandlerMock::NeedsIdentity() { 91 return first_round_; 92 } 93 94 bool HttpAuthHandlerMock::AllowsDefaultCredentials() { 95 return allows_default_credentials_; 96 } 97 98 bool HttpAuthHandlerMock::AllowsExplicitCredentials() { 99 return allows_explicit_credentials_; 100 } 101 102 bool HttpAuthHandlerMock::Init(HttpAuth::ChallengeTokenizer* challenge) { 103 auth_scheme_ = HttpAuth::AUTH_SCHEME_MOCK; 104 score_ = 1; 105 properties_ = connection_based_ ? IS_CONNECTION_BASED : 0; 106 return true; 107 } 108 109 int HttpAuthHandlerMock::GenerateAuthTokenImpl( 110 const AuthCredentials* credentials, 111 const HttpRequestInfo* request, 112 const CompletionCallback& callback, 113 std::string* auth_token) { 114 first_round_ = false; 115 request_url_ = request->url; 116 if (generate_async_) { 117 EXPECT_TRUE(callback_.is_null()); 118 EXPECT_TRUE(auth_token_ == NULL); 119 callback_ = callback; 120 auth_token_ = auth_token; 121 base::MessageLoop::current()->PostTask( 122 FROM_HERE, 123 base::Bind(&HttpAuthHandlerMock::OnGenerateAuthToken, 124 weak_factory_.GetWeakPtr())); 125 return ERR_IO_PENDING; 126 } else { 127 if (generate_rv_ == OK) 128 *auth_token = "auth_token"; 129 return generate_rv_; 130 } 131 } 132 133 void HttpAuthHandlerMock::OnResolveCanonicalName() { 134 EXPECT_EQ(RESOLVE_ASYNC, resolve_); 135 EXPECT_TRUE(!callback_.is_null()); 136 resolve_ = RESOLVE_TESTED; 137 CompletionCallback callback = callback_; 138 callback_.Reset(); 139 callback.Run(OK); 140 } 141 142 void HttpAuthHandlerMock::OnGenerateAuthToken() { 143 EXPECT_TRUE(generate_async_); 144 EXPECT_TRUE(!callback_.is_null()); 145 if (generate_rv_ == OK) 146 *auth_token_ = "auth_token"; 147 auth_token_ = NULL; 148 CompletionCallback callback = callback_; 149 callback_.Reset(); 150 callback.Run(generate_rv_); 151 } 152 153 HttpAuthHandlerMock::Factory::Factory() 154 : do_init_from_challenge_(false) { 155 // TODO(cbentzel): Default do_init_from_challenge_ to true. 156 } 157 158 HttpAuthHandlerMock::Factory::~Factory() { 159 } 160 161 void HttpAuthHandlerMock::Factory::AddMockHandler( 162 HttpAuthHandler* handler, HttpAuth::Target target) { 163 handlers_[target].push_back(handler); 164 } 165 166 int HttpAuthHandlerMock::Factory::CreateAuthHandler( 167 HttpAuth::ChallengeTokenizer* challenge, 168 HttpAuth::Target target, 169 const GURL& origin, 170 CreateReason reason, 171 int nonce_count, 172 const BoundNetLog& net_log, 173 scoped_ptr<HttpAuthHandler>* handler) { 174 if (handlers_[target].empty()) 175 return ERR_UNEXPECTED; 176 scoped_ptr<HttpAuthHandler> tmp_handler(handlers_[target][0]); 177 std::vector<HttpAuthHandler*>& handlers = handlers_[target].get(); 178 handlers.erase(handlers.begin()); 179 if (do_init_from_challenge_ && 180 !tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) 181 return ERR_INVALID_RESPONSE; 182 handler->swap(tmp_handler); 183 return OK; 184 } 185 186 } // namespace net 187