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.
5 #include "chrome/browser/local_discovery/privet_http_asynchronous_factory_impl.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/browser/local_discovery/service_discovery_shared_client.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "net/base/net_util.h"
15 namespace local_discovery
{
19 std::string
IPAddressToHostString(const net::IPAddressNumber
& address
) {
20 std::string address_str
= net::IPAddressToString(address
);
22 // IPv6 addresses need to be surrounded by brackets.
23 if (address
.size() == net::kIPv6AddressSize
) {
24 address_str
= base::StringPrintf("[%s]", address_str
.c_str());
32 PrivetHTTPAsynchronousFactoryImpl::PrivetHTTPAsynchronousFactoryImpl(
33 net::URLRequestContextGetter
* request_context
)
34 : request_context_(request_context
) {
37 PrivetHTTPAsynchronousFactoryImpl::~PrivetHTTPAsynchronousFactoryImpl() {
40 scoped_ptr
<PrivetHTTPResolution
>
41 PrivetHTTPAsynchronousFactoryImpl::CreatePrivetHTTP(
42 const std::string
& service_name
) {
43 return scoped_ptr
<PrivetHTTPResolution
>(
44 new ResolutionImpl(service_name
, request_context_
.get()));
47 PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolutionImpl(
48 const std::string
& service_name
,
49 net::URLRequestContextGetter
* request_context
)
50 : name_(service_name
), request_context_(request_context
) {
51 service_discovery_client_
= ServiceDiscoverySharedClient::GetInstance();
54 PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::~ResolutionImpl() {
58 PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::GetName() {
62 void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::Start(
63 const ResultCallback
& callback
) {
64 service_resolver_
= service_discovery_client_
->CreateServiceResolver(
65 name_
, base::Bind(&ResolutionImpl::ServiceResolveComplete
,
66 base::Unretained(this), callback
));
67 service_resolver_
->StartResolving();
70 void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ServiceResolveComplete(
71 const ResultCallback
& callback
,
72 ServiceResolver::RequestStatus result
,
73 const ServiceDescription
& description
) {
74 if (result
!= ServiceResolver::STATUS_SUCCESS
)
75 return callback
.Run(scoped_ptr
<PrivetHTTPClient
>());
77 Start(description
.address
, callback
);
80 void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::Start(
81 const net::HostPortPair
& address
,
82 const ResultCallback
& callback
) {
83 #if defined(OS_MACOSX)
84 net::IPAddressNumber ip_address
;
85 DCHECK(net::ParseIPLiteralToNumber(address
.host(), &ip_address
));
86 // MAC already has IP there.
87 callback
.Run(scoped_ptr
<PrivetHTTPClient
>(
88 new PrivetHTTPClientImpl(name_
, address
, request_context_
.get())));
90 net::AddressFamily address_family
= net::ADDRESS_FAMILY_UNSPECIFIED
;
91 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
92 switches::kPrivetIPv6Only
)) {
93 address_family
= net::ADDRESS_FAMILY_IPV6
;
96 domain_resolver_
= service_discovery_client_
->CreateLocalDomainResolver(
97 address
.host(), address_family
,
98 base::Bind(&ResolutionImpl::DomainResolveComplete
, base::Unretained(this),
99 address
.port(), callback
));
100 domain_resolver_
->Start();
104 void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::DomainResolveComplete(
106 const ResultCallback
& callback
,
108 const net::IPAddressNumber
& address_ipv4
,
109 const net::IPAddressNumber
& address_ipv6
) {
111 callback
.Run(scoped_ptr
<PrivetHTTPClient
>());
115 net::IPAddressNumber address
= address_ipv4
;
117 address
= address_ipv6
;
119 DCHECK(!address
.empty());
121 net::HostPortPair new_address
=
122 net::HostPortPair(IPAddressToHostString(address
), port
);
123 callback
.Run(scoped_ptr
<PrivetHTTPClient
>(
124 new PrivetHTTPClientImpl(name_
, new_address
, request_context_
.get())));
127 } // namespace local_discovery