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