privet_http_asynchronous_factory_impl.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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
13namespace local_discovery {
14
15namespace {
16
17std::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
30PrivetHTTPAsynchronousFactoryImpl::PrivetHTTPAsynchronousFactoryImpl(
31    ServiceDiscoveryClient* service_discovery_client,
32    net::URLRequestContextGetter* request_context)
33    : service_discovery_client_(service_discovery_client),
34      request_context_(request_context) {}
35
36PrivetHTTPAsynchronousFactoryImpl::~PrivetHTTPAsynchronousFactoryImpl() {}
37
38scoped_ptr<PrivetHTTPResolution>
39PrivetHTTPAsynchronousFactoryImpl::CreatePrivetHTTP(
40    const std::string& name,
41    const net::HostPortPair& address,
42    const ResultCallback& callback) {
43  return scoped_ptr<PrivetHTTPResolution>(
44      new ResolutionImpl(name,
45                         address,
46                         callback,
47                         service_discovery_client_,
48                         request_context_.get()));
49}
50
51PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolutionImpl(
52    const std::string& name,
53    const net::HostPortPair& address,
54    const ResultCallback& callback,
55    ServiceDiscoveryClient* service_discovery_client,
56    net::URLRequestContextGetter* request_context)
57    : name_(name),
58      hostport_(address),
59      callback_(callback),
60      request_context_(request_context) {
61  net::AddressFamily address_family = net::ADDRESS_FAMILY_UNSPECIFIED;
62
63  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kPrivetIPv6Only)) {
64    address_family = net::ADDRESS_FAMILY_IPV6;
65  }
66
67  resolver_ = service_discovery_client->CreateLocalDomainResolver(
68      address.host(),
69      address_family,
70      base::Bind(&ResolutionImpl::ResolveComplete, base::Unretained(this)));
71}
72
73PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::~ResolutionImpl() {}
74
75void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::Start() {
76  resolver_->Start();
77}
78
79const std::string&
80PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::GetName() {
81  return name_;
82}
83
84void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolveComplete(
85    bool success,
86    const net::IPAddressNumber& address_ipv4,
87    const net::IPAddressNumber& address_ipv6) {
88  if (!success) {
89    callback_.Run(scoped_ptr<PrivetHTTPClient>());
90    return;
91  }
92
93  net::IPAddressNumber address = address_ipv4;
94  if (address.empty())
95    address = address_ipv6;
96
97  DCHECK(!address.empty());
98
99  net::HostPortPair new_address =
100      net::HostPortPair(IPAddressToHostString(address), hostport_.port());
101  callback_.Run(scoped_ptr<PrivetHTTPClient>(
102      new PrivetHTTPClientImpl(name_, new_address, request_context_.get())));
103}
104
105}  // namespace local_discovery
106