1 // Copyright 2014 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 "chrome/browser/local_discovery/privet_http_asynchronous_factory_impl.h" 6 7 #include "base/bind.h" 8 #include "base/command_line.h" 9 #include "base/strings/stringprintf.h" 10 #include "chrome/browser/local_discovery/privet_http_impl.h" 11 #include "chrome/common/chrome_switches.h" 12 13 namespace local_discovery { 14 15 namespace { 16 17 std::string IPAddressToHostString(const net::IPAddressNumber& address) { 18 std::string address_str = net::IPAddressToString(address); 19 20 // IPv6 addresses need to be surrounded by brackets. 21 if (address.size() == net::kIPv6AddressSize) { 22 address_str = base::StringPrintf("[%s]", address_str.c_str()); 23 } 24 25 return address_str; 26 } 27 28 } // namespace 29 30 PrivetHTTPAsynchronousFactoryImpl::PrivetHTTPAsynchronousFactoryImpl( 31 ServiceDiscoveryClient* service_discovery_client, 32 net::URLRequestContextGetter* request_context) 33 : service_discovery_client_(service_discovery_client), 34 request_context_(request_context) { 35 } 36 37 PrivetHTTPAsynchronousFactoryImpl::~PrivetHTTPAsynchronousFactoryImpl() { 38 } 39 40 scoped_ptr<PrivetHTTPResolution> 41 PrivetHTTPAsynchronousFactoryImpl::CreatePrivetHTTP( 42 const std::string& name, 43 const net::HostPortPair& address, 44 const ResultCallback& callback) { 45 return scoped_ptr<PrivetHTTPResolution>( 46 new ResolutionImpl(name, 47 address, 48 callback, 49 service_discovery_client_, 50 request_context_.get())); 51 } 52 53 PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolutionImpl( 54 const std::string& name, 55 const net::HostPortPair& address, 56 const ResultCallback& callback, 57 ServiceDiscoveryClient* service_discovery_client, 58 net::URLRequestContextGetter* request_context) 59 : name_(name), 60 hostport_(address), 61 callback_(callback), 62 request_context_(request_context) { 63 net::AddressFamily address_family = net::ADDRESS_FAMILY_UNSPECIFIED; 64 65 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kPrivetIPv6Only)) { 66 address_family = net::ADDRESS_FAMILY_IPV6; 67 } 68 69 resolver_ = service_discovery_client->CreateLocalDomainResolver( 70 address.host(), 71 address_family, 72 base::Bind(&ResolutionImpl::ResolveComplete, base::Unretained(this))); 73 } 74 75 PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::~ResolutionImpl() { 76 } 77 78 void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::Start() { 79 resolver_->Start(); 80 } 81 82 const std::string& 83 PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::GetName() { 84 return name_; 85 } 86 87 void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolveComplete( 88 bool success, 89 const net::IPAddressNumber& address_ipv4, 90 const net::IPAddressNumber& address_ipv6) { 91 if (!success) { 92 callback_.Run(scoped_ptr<PrivetHTTPClient>()); 93 return; 94 } 95 96 net::IPAddressNumber address = address_ipv4; 97 if (address.empty()) 98 address = address_ipv6; 99 100 DCHECK(!address.empty()); 101 102 net::HostPortPair new_address = 103 net::HostPortPair(IPAddressToHostString(address), hostport_.port()); 104 callback_.Run(scoped_ptr<PrivetHTTPClient>( 105 new PrivetHTTPClientImpl(name_, new_address, request_context_.get()))); 106 } 107 108 } // namespace local_discovery 109