| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/host_resolver.h" | 5 #include "net/base/host_resolver.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <ws2tcpip.h> | 8 #include <ws2tcpip.h> |
| 9 #include <wspiapi.h> | 9 #include <wspiapi.h> |
| 10 #elif defined(OS_POSIX) | 10 #elif defined(OS_POSIX) |
| 11 #include <netdb.h> | 11 #include <netdb.h> |
| 12 #endif | 12 #endif |
| 13 | 13 |
| 14 #include <string> | 14 #include <string> |
| 15 | 15 |
| 16 #include "base/compiler_specific.h" | 16 #include "base/compiler_specific.h" |
| 17 #include "base/message_loop.h" | 17 #include "base/message_loop.h" |
| 18 #include "base/ref_counted.h" | 18 #include "base/ref_counted.h" |
| 19 #include "net/base/address_list.h" | 19 #include "net/base/address_list.h" |
| 20 #include "net/base/completion_callback.h" | 20 #include "net/base/completion_callback.h" |
| 21 #include "net/base/dns_resolution_observer.h" |
| 21 #include "net/base/host_resolver_unittest.h" | 22 #include "net/base/host_resolver_unittest.h" |
| 22 #include "net/base/net_errors.h" | 23 #include "net/base/net_errors.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 25 |
| 25 using net::RuleBasedHostMapper; | 26 using net::RuleBasedHostMapper; |
| 26 using net::ScopedHostMapper; | 27 using net::ScopedHostMapper; |
| 27 using net::WaitingHostMapper; | 28 using net::WaitingHostMapper; |
| 28 | 29 |
| 29 // TODO(eroman): | 30 // TODO(eroman): |
| 30 // - Test mixing async with sync (in particular how does sync update the | 31 // - Test mixing async with sync (in particular how does sync update the |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 class Delegate { | 76 class Delegate { |
| 76 public: | 77 public: |
| 77 virtual ~Delegate() {} | 78 virtual ~Delegate() {} |
| 78 virtual void OnCompleted(ResolveRequest* resolve) = 0; | 79 virtual void OnCompleted(ResolveRequest* resolve) = 0; |
| 79 }; | 80 }; |
| 80 | 81 |
| 81 ResolveRequest(net::HostResolver* resolver, | 82 ResolveRequest(net::HostResolver* resolver, |
| 82 const std::string& hostname, | 83 const std::string& hostname, |
| 83 int port, | 84 int port, |
| 84 Delegate* delegate) | 85 Delegate* delegate) |
| 85 : hostname_(hostname), port_(port), resolver_(resolver), | 86 : info_(hostname, port), resolver_(resolver), delegate_(delegate), |
| 86 delegate_(delegate), | |
| 87 ALLOW_THIS_IN_INITIALIZER_LIST( | 87 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 88 callback_(this, &ResolveRequest::OnLookupFinished)) { | 88 callback_(this, &ResolveRequest::OnLookupFinished)) { |
| 89 // Start the request. | 89 // Start the request. |
| 90 int err = resolver->Resolve(hostname, port, &addrlist_, &callback_, &req_); | 90 int err = resolver->Resolve(info_, &addrlist_, &callback_, &req_); |
| 91 EXPECT_EQ(net::ERR_IO_PENDING, err); |
| 92 } |
| 93 |
| 94 ResolveRequest(net::HostResolver* resolver, |
| 95 const net::HostResolver::RequestInfo& info, |
| 96 Delegate* delegate) |
| 97 : info_(info), resolver_(resolver), delegate_(delegate), |
| 98 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 99 callback_(this, &ResolveRequest::OnLookupFinished)) { |
| 100 // Start the request. |
| 101 int err = resolver->Resolve(info, &addrlist_, &callback_, &req_); |
| 91 EXPECT_EQ(net::ERR_IO_PENDING, err); | 102 EXPECT_EQ(net::ERR_IO_PENDING, err); |
| 92 } | 103 } |
| 93 | 104 |
| 94 void Cancel() { | 105 void Cancel() { |
| 95 resolver_->CancelRequest(req_); | 106 resolver_->CancelRequest(req_); |
| 96 } | 107 } |
| 97 | 108 |
| 98 const std::string& hostname() const { | 109 const std::string& hostname() const { |
| 99 return hostname_; | 110 return info_.hostname(); |
| 100 } | 111 } |
| 101 | 112 |
| 102 int port() const { | 113 int port() const { |
| 103 return port_; | 114 return info_.port(); |
| 104 } | 115 } |
| 105 | 116 |
| 106 int result() const { | 117 int result() const { |
| 107 return result_; | 118 return result_; |
| 108 } | 119 } |
| 109 | 120 |
| 110 const net::AddressList& addrlist() const { | 121 const net::AddressList& addrlist() const { |
| 111 return addrlist_; | 122 return addrlist_; |
| 112 } | 123 } |
| 113 | 124 |
| 114 net::HostResolver* resolver() const { | 125 net::HostResolver* resolver() const { |
| 115 return resolver_; | 126 return resolver_; |
| 116 } | 127 } |
| 117 | 128 |
| 118 private: | 129 private: |
| 119 void OnLookupFinished(int result) { | 130 void OnLookupFinished(int result) { |
| 120 result_ = result; | 131 result_ = result; |
| 121 delegate_->OnCompleted(this); | 132 delegate_->OnCompleted(this); |
| 122 } | 133 } |
| 123 | 134 |
| 124 // The request details. | 135 // The request details. |
| 125 std::string hostname_; | 136 net::HostResolver::RequestInfo info_; |
| 126 int port_; | |
| 127 net::HostResolver::Request* req_; | 137 net::HostResolver::Request* req_; |
| 128 | 138 |
| 129 // The result of the resolve. | 139 // The result of the resolve. |
| 130 int result_; | 140 int result_; |
| 131 net::AddressList addrlist_; | 141 net::AddressList addrlist_; |
| 132 | 142 |
| 133 net::HostResolver* resolver_; | 143 net::HostResolver* resolver_; |
| 134 | 144 |
| 135 Delegate* delegate_; | 145 Delegate* delegate_; |
| 136 net::CompletionCallbackImpl<ResolveRequest> callback_; | 146 net::CompletionCallbackImpl<ResolveRequest> callback_; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 161 | 171 |
| 162 TEST_F(HostResolverTest, SynchronousLookup) { | 172 TEST_F(HostResolverTest, SynchronousLookup) { |
| 163 net::HostResolver host_resolver; | 173 net::HostResolver host_resolver; |
| 164 net::AddressList adrlist; | 174 net::AddressList adrlist; |
| 165 const int kPortnum = 80; | 175 const int kPortnum = 80; |
| 166 | 176 |
| 167 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); | 177 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); |
| 168 mapper->AddRule("just.testing", "192.168.1.42"); | 178 mapper->AddRule("just.testing", "192.168.1.42"); |
| 169 ScopedHostMapper scoped_mapper(mapper.get()); | 179 ScopedHostMapper scoped_mapper(mapper.get()); |
| 170 | 180 |
| 171 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, NULL, | 181 net::HostResolver::RequestInfo info("just.testing", kPortnum); |
| 172 NULL); | 182 int err = host_resolver.Resolve(info, &adrlist, NULL, NULL); |
| 173 EXPECT_EQ(net::OK, err); | 183 EXPECT_EQ(net::OK, err); |
| 174 | 184 |
| 175 const struct addrinfo* ainfo = adrlist.head(); | 185 const struct addrinfo* ainfo = adrlist.head(); |
| 176 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); | 186 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); |
| 177 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); | 187 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); |
| 178 | 188 |
| 179 const struct sockaddr* sa = ainfo->ai_addr; | 189 const struct sockaddr* sa = ainfo->ai_addr; |
| 180 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; | 190 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; |
| 181 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); | 191 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); |
| 182 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); | 192 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); |
| 183 } | 193 } |
| 184 | 194 |
| 185 TEST_F(HostResolverTest, AsynchronousLookup) { | 195 TEST_F(HostResolverTest, AsynchronousLookup) { |
| 186 net::HostResolver host_resolver; | 196 net::HostResolver host_resolver; |
| 187 net::AddressList adrlist; | 197 net::AddressList adrlist; |
| 188 const int kPortnum = 80; | 198 const int kPortnum = 80; |
| 189 | 199 |
| 190 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); | 200 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); |
| 191 mapper->AddRule("just.testing", "192.168.1.42"); | 201 mapper->AddRule("just.testing", "192.168.1.42"); |
| 192 ScopedHostMapper scoped_mapper(mapper.get()); | 202 ScopedHostMapper scoped_mapper(mapper.get()); |
| 193 | 203 |
| 194 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, | 204 net::HostResolver::RequestInfo info("just.testing", kPortnum); |
| 195 &callback_, NULL); | 205 int err = host_resolver.Resolve(info, &adrlist, &callback_, NULL); |
| 196 EXPECT_EQ(net::ERR_IO_PENDING, err); | 206 EXPECT_EQ(net::ERR_IO_PENDING, err); |
| 197 | 207 |
| 198 MessageLoop::current()->Run(); | 208 MessageLoop::current()->Run(); |
| 199 | 209 |
| 200 ASSERT_TRUE(callback_called_); | 210 ASSERT_TRUE(callback_called_); |
| 201 ASSERT_EQ(net::OK, callback_result_); | 211 ASSERT_EQ(net::OK, callback_result_); |
| 202 | 212 |
| 203 const struct addrinfo* ainfo = adrlist.head(); | 213 const struct addrinfo* ainfo = adrlist.head(); |
| 204 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); | 214 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); |
| 205 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); | 215 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); |
| 206 | 216 |
| 207 const struct sockaddr* sa = ainfo->ai_addr; | 217 const struct sockaddr* sa = ainfo->ai_addr; |
| 208 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; | 218 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; |
| 209 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); | 219 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); |
| 210 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); | 220 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); |
| 211 } | 221 } |
| 212 | 222 |
| 213 TEST_F(HostResolverTest, CanceledAsynchronousLookup) { | 223 TEST_F(HostResolverTest, CanceledAsynchronousLookup) { |
| 214 scoped_refptr<WaitingHostMapper> mapper = new WaitingHostMapper(); | 224 scoped_refptr<WaitingHostMapper> mapper = new WaitingHostMapper(); |
| 215 ScopedHostMapper scoped_mapper(mapper.get()); | 225 ScopedHostMapper scoped_mapper(mapper.get()); |
| 216 | 226 |
| 217 { | 227 { |
| 218 net::HostResolver host_resolver; | 228 net::HostResolver host_resolver; |
| 219 net::AddressList adrlist; | 229 net::AddressList adrlist; |
| 220 const int kPortnum = 80; | 230 const int kPortnum = 80; |
| 221 | 231 |
| 222 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, | 232 net::HostResolver::RequestInfo info("just.testing", kPortnum); |
| 223 &callback_, NULL); | 233 int err = host_resolver.Resolve(info, &adrlist, &callback_, NULL); |
| 224 EXPECT_EQ(net::ERR_IO_PENDING, err); | 234 EXPECT_EQ(net::ERR_IO_PENDING, err); |
| 225 | 235 |
| 226 // Make sure we will exit the queue even when callback is not called. | 236 // Make sure we will exit the queue even when callback is not called. |
| 227 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 237 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 228 new MessageLoop::QuitTask(), | 238 new MessageLoop::QuitTask(), |
| 229 1000); | 239 1000); |
| 230 MessageLoop::current()->Run(); | 240 MessageLoop::current()->Run(); |
| 231 } | 241 } |
| 232 | 242 |
| 233 mapper->Signal(); | 243 mapper->Signal(); |
| 234 | 244 |
| 235 EXPECT_FALSE(callback_called_); | 245 EXPECT_FALSE(callback_called_); |
| 236 } | 246 } |
| 237 | 247 |
| 238 TEST_F(HostResolverTest, NumericIPv4Address) { | 248 TEST_F(HostResolverTest, NumericIPv4Address) { |
| 239 // Stevens says dotted quads with AI_UNSPEC resolve to a single sockaddr_in. | 249 // Stevens says dotted quads with AI_UNSPEC resolve to a single sockaddr_in. |
| 240 | 250 |
| 241 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); | 251 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); |
| 242 mapper->AllowDirectLookup("*"); | 252 mapper->AllowDirectLookup("*"); |
| 243 ScopedHostMapper scoped_mapper(mapper.get()); | 253 ScopedHostMapper scoped_mapper(mapper.get()); |
| 244 | 254 |
| 245 net::HostResolver host_resolver; | 255 net::HostResolver host_resolver; |
| 246 net::AddressList adrlist; | 256 net::AddressList adrlist; |
| 247 const int kPortnum = 5555; | 257 const int kPortnum = 5555; |
| 248 int err = host_resolver.Resolve("127.1.2.3", kPortnum, &adrlist, NULL, NULL); | 258 net::HostResolver::RequestInfo info("127.1.2.3", kPortnum); |
| 259 int err = host_resolver.Resolve(info, &adrlist, NULL, NULL); |
| 249 EXPECT_EQ(net::OK, err); | 260 EXPECT_EQ(net::OK, err); |
| 250 | 261 |
| 251 const struct addrinfo* ainfo = adrlist.head(); | 262 const struct addrinfo* ainfo = adrlist.head(); |
| 252 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); | 263 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); |
| 253 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); | 264 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); |
| 254 | 265 |
| 255 const struct sockaddr* sa = ainfo->ai_addr; | 266 const struct sockaddr* sa = ainfo->ai_addr; |
| 256 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; | 267 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; |
| 257 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); | 268 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); |
| 258 EXPECT_TRUE(htonl(0x7f010203) == sa_in->sin_addr.s_addr); | 269 EXPECT_TRUE(htonl(0x7f010203) == sa_in->sin_addr.s_addr); |
| 259 } | 270 } |
| 260 | 271 |
| 261 TEST_F(HostResolverTest, NumericIPv6Address) { | 272 TEST_F(HostResolverTest, NumericIPv6Address) { |
| 262 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); | 273 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); |
| 263 mapper->AllowDirectLookup("*"); | 274 mapper->AllowDirectLookup("*"); |
| 264 ScopedHostMapper scoped_mapper(mapper.get()); | 275 ScopedHostMapper scoped_mapper(mapper.get()); |
| 265 | 276 |
| 266 // Resolve a plain IPv6 address. Don't worry about [brackets], because | 277 // Resolve a plain IPv6 address. Don't worry about [brackets], because |
| 267 // the caller should have removed them. | 278 // the caller should have removed them. |
| 268 net::HostResolver host_resolver; | 279 net::HostResolver host_resolver; |
| 269 net::AddressList adrlist; | 280 net::AddressList adrlist; |
| 270 const int kPortnum = 5555; | 281 const int kPortnum = 5555; |
| 271 int err = host_resolver.Resolve("2001:db8::1", kPortnum, &adrlist, NULL, | 282 net::HostResolver::RequestInfo info("2001:db8::1", kPortnum); |
| 272 NULL); | 283 int err = host_resolver.Resolve(info, &adrlist, NULL, NULL); |
| 273 // On computers without IPv6 support, getaddrinfo cannot convert IPv6 | 284 // On computers without IPv6 support, getaddrinfo cannot convert IPv6 |
| 274 // address literals to addresses (getaddrinfo returns EAI_NONAME). So this | 285 // address literals to addresses (getaddrinfo returns EAI_NONAME). So this |
| 275 // test has to allow host_resolver.Resolve to fail. | 286 // test has to allow host_resolver.Resolve to fail. |
| 276 if (err == net::ERR_NAME_NOT_RESOLVED) | 287 if (err == net::ERR_NAME_NOT_RESOLVED) |
| 277 return; | 288 return; |
| 278 EXPECT_EQ(net::OK, err); | 289 EXPECT_EQ(net::OK, err); |
| 279 | 290 |
| 280 const struct addrinfo* ainfo = adrlist.head(); | 291 const struct addrinfo* ainfo = adrlist.head(); |
| 281 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); | 292 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); |
| 282 EXPECT_EQ(sizeof(struct sockaddr_in6), ainfo->ai_addrlen); | 293 EXPECT_EQ(sizeof(struct sockaddr_in6), ainfo->ai_addrlen); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 295 } | 306 } |
| 296 | 307 |
| 297 TEST_F(HostResolverTest, EmptyHost) { | 308 TEST_F(HostResolverTest, EmptyHost) { |
| 298 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); | 309 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); |
| 299 mapper->AllowDirectLookup("*"); | 310 mapper->AllowDirectLookup("*"); |
| 300 ScopedHostMapper scoped_mapper(mapper.get()); | 311 ScopedHostMapper scoped_mapper(mapper.get()); |
| 301 | 312 |
| 302 net::HostResolver host_resolver; | 313 net::HostResolver host_resolver; |
| 303 net::AddressList adrlist; | 314 net::AddressList adrlist; |
| 304 const int kPortnum = 5555; | 315 const int kPortnum = 5555; |
| 305 int err = host_resolver.Resolve("", kPortnum, &adrlist, NULL, NULL); | 316 net::HostResolver::RequestInfo info("", kPortnum); |
| 317 int err = host_resolver.Resolve(info, &adrlist, NULL, NULL); |
| 306 EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, err); | 318 EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, err); |
| 307 } | 319 } |
| 308 | 320 |
| 309 // Helper class used by HostResolverTest.DeDupeRequests. It receives request | 321 // Helper class used by HostResolverTest.DeDupeRequests. It receives request |
| 310 // completion notifications for all the resolves, so it can tally up and | 322 // completion notifications for all the resolves, so it can tally up and |
| 311 // determine when we are done. | 323 // determine when we are done. |
| 312 class DeDupeRequestsVerifier : public ResolveRequest::Delegate { | 324 class DeDupeRequestsVerifier : public ResolveRequest::Delegate { |
| 313 public: | 325 public: |
| 314 explicit DeDupeRequestsVerifier(CapturingHostMapper* mapper) | 326 explicit DeDupeRequestsVerifier(CapturingHostMapper* mapper) |
| 315 : count_a_(0), count_b_(0), mapper_(mapper) {} | 327 : count_a_(0), count_b_(0), mapper_(mapper) {} |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 // in the job and start another request. | 462 // in the job and start another request. |
| 451 if (80 == resolve->port()) { | 463 if (80 == resolve->port()) { |
| 452 EXPECT_EQ("a", resolve->hostname()); | 464 EXPECT_EQ("a", resolve->hostname()); |
| 453 | 465 |
| 454 req_to_cancel1_->Cancel(); | 466 req_to_cancel1_->Cancel(); |
| 455 req_to_cancel2_->Cancel(); | 467 req_to_cancel2_->Cancel(); |
| 456 | 468 |
| 457 // Start a request (so we can make sure the canceled requests don't | 469 // Start a request (so we can make sure the canceled requests don't |
| 458 // complete before "finalrequest" finishes. | 470 // complete before "finalrequest" finishes. |
| 459 final_request_.reset(new ResolveRequest( | 471 final_request_.reset(new ResolveRequest( |
| 460 resolve->resolver(), "finalrequest", 70, this)); | 472 resolve->resolver(), "finalrequest", 70, this)); |
| 461 | 473 |
| 462 } else if (83 == resolve->port()) { | 474 } else if (83 == resolve->port()) { |
| 463 EXPECT_EQ("a", resolve->hostname()); | 475 EXPECT_EQ("a", resolve->hostname()); |
| 464 } else if (resolve->hostname() == "finalrequest") { | 476 } else if (resolve->hostname() == "finalrequest") { |
| 465 EXPECT_EQ(70, resolve->addrlist().GetPort()); | 477 EXPECT_EQ(70, resolve->addrlist().GetPort()); |
| 466 | 478 |
| 467 // End this test, we are done. | 479 // End this test, we are done. |
| 468 MessageLoop::current()->Quit(); | 480 MessageLoop::current()->Quit(); |
| 469 } else { | 481 } else { |
| 470 FAIL() << "Unexpected completion: " << resolve->hostname() << ", " | 482 FAIL() << "Unexpected completion: " << resolve->hostname() << ", " |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 ResolveRequest req3(&host_resolver, "a", 82, &verifier); | 623 ResolveRequest req3(&host_resolver, "a", 82, &verifier); |
| 612 ResolveRequest req4(&host_resolver, "a", 83, &verifier); | 624 ResolveRequest req4(&host_resolver, "a", 83, &verifier); |
| 613 | 625 |
| 614 // Ready, Set, GO!!! | 626 // Ready, Set, GO!!! |
| 615 mapper->Signal(); | 627 mapper->Signal(); |
| 616 | 628 |
| 617 // |verifier| will send quit message once all the requests have finished. | 629 // |verifier| will send quit message once all the requests have finished. |
| 618 MessageLoop::current()->Run(); | 630 MessageLoop::current()->Run(); |
| 619 } | 631 } |
| 620 | 632 |
| 633 // Helper class used by HostResolverTest.BypassCache. |
| 634 class BypassCacheVerifier : public ResolveRequest::Delegate { |
| 635 public: |
| 636 BypassCacheVerifier() {} |
| 637 |
| 638 virtual void OnCompleted(ResolveRequest* resolve) { |
| 639 EXPECT_EQ("a", resolve->hostname()); |
| 640 net::HostResolver* resolver = resolve->resolver(); |
| 641 |
| 642 if (80 == resolve->port()) { |
| 643 // On completing the first request, start another request for "a". |
| 644 // Since caching is enabled, this should complete synchronously. |
| 645 |
| 646 // Note that |junk_callback| shouldn't be used since we are going to |
| 647 // complete synchronously. We can't specify NULL though since that would |
| 648 // mean synchronous mode so we give it a value of 1. |
| 649 net::CompletionCallback* junk_callback = |
| 650 reinterpret_cast<net::CompletionCallback*> (1); |
| 651 net::AddressList addrlist; |
| 652 |
| 653 net::HostResolver::RequestInfo info("a", 70); |
| 654 int error = resolver->Resolve(info, &addrlist, junk_callback, NULL); |
| 655 EXPECT_EQ(net::OK, error); |
| 656 |
| 657 // Ok good. Now make sure that if we ask to bypass the cache, it can no |
| 658 // longer service the request synchronously. |
| 659 info = net::HostResolver::RequestInfo("a", 71); |
| 660 info.set_allow_cached_response(false); |
| 661 final_request_.reset(new ResolveRequest(resolver, info, this)); |
| 662 } else if (71 == resolve->port()) { |
| 663 // Test is done. |
| 664 MessageLoop::current()->Quit(); |
| 665 } else { |
| 666 FAIL() << "Unexpected port number"; |
| 667 } |
| 668 } |
| 669 |
| 670 private: |
| 671 scoped_ptr<ResolveRequest> final_request_; |
| 672 DISALLOW_COPY_AND_ASSIGN(BypassCacheVerifier); |
| 673 }; |
| 674 |
| 675 TEST_F(HostResolverTest, BypassCache) { |
| 676 net::HostResolver host_resolver; |
| 677 |
| 678 // The class will receive callbacks for when each resolve completes. It |
| 679 // checks that the right things happened. |
| 680 BypassCacheVerifier verifier; |
| 681 |
| 682 // Start a request. |
| 683 ResolveRequest req1(&host_resolver, "a", 80, &verifier); |
| 684 |
| 685 // |verifier| will send quit message once all the requests have finished. |
| 686 MessageLoop::current()->Run(); |
| 687 } |
| 688 |
| 689 bool operator==(const net::HostResolver::RequestInfo& a, |
| 690 const net::HostResolver::RequestInfo& b) { |
| 691 return a.hostname() == b.hostname() && |
| 692 a.port() == b.port() && |
| 693 a.allow_cached_response() == b.allow_cached_response() && |
| 694 a.is_speculative() == b.is_speculative() && |
| 695 a.referrer() == b.referrer(); |
| 696 } |
| 697 |
| 698 // Observer that just makes note of how it was called. The test code can then |
| 699 // inspect to make sure it was called with the right parameters. |
| 700 class CapturingObserver : public net::DnsResolutionObserver { |
| 701 public: |
| 702 // DnsResolutionObserver methods: |
| 703 virtual void OnStartResolution(int id, |
| 704 const net::HostResolver::RequestInfo& info) { |
| 705 start_log.push_back(StartEntry(id, info)); |
| 706 } |
| 707 |
| 708 virtual void OnFinishResolutionWithStatus( |
| 709 int id, |
| 710 bool was_resolved, |
| 711 const net::HostResolver::RequestInfo& info) { |
| 712 finish_log.push_back(FinishEntry(id, was_resolved, info)); |
| 713 } |
| 714 |
| 715 // Tuple (id, info). |
| 716 struct StartEntry { |
| 717 StartEntry(int id, const net::HostResolver::RequestInfo& info) |
| 718 : id(id), info(info) {} |
| 719 |
| 720 bool operator==(const StartEntry& other) const { |
| 721 return id == other.id && info == other.info; |
| 722 } |
| 723 |
| 724 int id; |
| 725 net::HostResolver::RequestInfo info; |
| 726 }; |
| 727 |
| 728 // Tuple (id, was_resolved, info). |
| 729 struct FinishEntry { |
| 730 FinishEntry(int id, bool was_resolved, |
| 731 const net::HostResolver::RequestInfo& info) |
| 732 : id(id), was_resolved(was_resolved), info(info) {} |
| 733 |
| 734 bool operator==(const FinishEntry& other) const { |
| 735 return id == other.id && |
| 736 was_resolved == other.was_resolved && |
| 737 info == other.info; |
| 738 } |
| 739 |
| 740 int id; |
| 741 bool was_resolved; |
| 742 net::HostResolver::RequestInfo info; |
| 743 }; |
| 744 |
| 745 std::vector<StartEntry> start_log; |
| 746 std::vector<FinishEntry> finish_log; |
| 747 }; |
| 748 |
| 749 // Test that registering, unregistering, and notifying of observers works. |
| 750 TEST_F(HostResolverTest, Observers) { |
| 751 net::HostResolver host_resolver; |
| 752 |
| 753 CapturingObserver observer; |
| 754 |
| 755 host_resolver.AddObserver(&observer); |
| 756 |
| 757 net::AddressList addrlist; |
| 758 |
| 759 // Resolve "host1". |
| 760 net::HostResolver::RequestInfo info1("host1", 70); |
| 761 host_resolver.Resolve(info1, &addrlist, NULL, NULL); |
| 762 |
| 763 EXPECT_EQ(1U, observer.start_log.size()); |
| 764 EXPECT_EQ(1U, observer.finish_log.size()); |
| 765 EXPECT_TRUE( |
| 766 observer.start_log[0] == CapturingObserver::StartEntry(0, info1)); |
| 767 EXPECT_TRUE( |
| 768 observer.finish_log[0] == CapturingObserver::FinishEntry(0, true, info1)); |
| 769 |
| 770 // Resolve "host2", setting referrer to "http://foobar.com" |
| 771 net::HostResolver::RequestInfo info2("host2", 70); |
| 772 info2.set_referrer(GURL("http://foobar.com")); |
| 773 host_resolver.Resolve(info2, &addrlist, NULL, NULL); |
| 774 |
| 775 EXPECT_EQ(2U, observer.start_log.size()); |
| 776 EXPECT_EQ(2U, observer.finish_log.size()); |
| 777 EXPECT_TRUE(observer.start_log[1] == CapturingObserver::StartEntry(1, info2)); |
| 778 EXPECT_TRUE(observer.finish_log[1] == CapturingObserver::FinishEntry( |
| 779 1, true, info2)); |
| 780 |
| 781 // Unregister the observer. |
| 782 host_resolver.RemoveObserver(&observer); |
| 783 |
| 784 // Resolve "host3" |
| 785 net::HostResolver::RequestInfo info3("host3", 70); |
| 786 host_resolver.Resolve(info3, &addrlist, NULL, NULL); |
| 787 |
| 788 // No effect this time, since observer was removed. |
| 789 EXPECT_EQ(2U, observer.start_log.size()); |
| 790 EXPECT_EQ(2U, observer.finish_log.size()); |
| 791 } |
| 792 |
| 621 } // namespace | 793 } // namespace |
| OLD | NEW |