- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / local_discovery / privet_http_asynchronous_factory.cc
1 // Copyright 2013 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.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.h"
11 #include "chrome/browser/local_discovery/privet_http_impl.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/common/local_discovery/service_discovery_client.h"
14
15 namespace local_discovery {
16
17 namespace {
18
19 std::string IPAddressToHostString(const net::IPAddressNumber& address) {
20   std::string address_str = net::IPAddressToString(address);
21
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());
25   }
26
27   return address_str;
28 }
29
30 }  // namespace
31
32 class PrivetHTTPAsynchronousFactoryImpl : public PrivetHTTPAsynchronousFactory {
33  public:
34   PrivetHTTPAsynchronousFactoryImpl(
35       ServiceDiscoveryClient* service_discovery_client,
36       net::URLRequestContextGetter* request_context);
37   virtual ~PrivetHTTPAsynchronousFactoryImpl();
38
39   virtual scoped_ptr<PrivetHTTPResolution> CreatePrivetHTTP(
40       const std::string& name,
41       const net::HostPortPair& address,
42       const ResultCallback& callback) OVERRIDE;
43
44  private:
45   class ResolutionImpl : public PrivetHTTPResolution {
46    public:
47     ResolutionImpl(const std::string& name,
48                    const net::HostPortPair& address,
49                    const ResultCallback& callback,
50                    ServiceDiscoveryClient* service_discovery_client,
51                    net::URLRequestContextGetter* request_context);
52     virtual ~ResolutionImpl();
53
54     virtual void Start() OVERRIDE;
55    private:
56     void ResolveComplete(bool success,
57                          const net::IPAddressNumber& address_ipv4,
58                          const net::IPAddressNumber& address_ipv6);
59
60     std::string name_;
61     scoped_ptr<LocalDomainResolver> resolver_;
62     net::HostPortPair hostport_;
63     ResultCallback callback_;
64     scoped_refptr<net::URLRequestContextGetter> request_context_;
65   };
66
67   ServiceDiscoveryClient* service_discovery_client_;
68   scoped_refptr<net::URLRequestContextGetter> request_context_;
69 };
70
71 PrivetHTTPAsynchronousFactoryImpl::PrivetHTTPAsynchronousFactoryImpl(
72     ServiceDiscoveryClient* service_discovery_client,
73     net::URLRequestContextGetter* request_context)
74     : service_discovery_client_(service_discovery_client),
75       request_context_(request_context) {
76 }
77
78 PrivetHTTPAsynchronousFactoryImpl::~PrivetHTTPAsynchronousFactoryImpl() {
79 }
80
81 // static
82 scoped_ptr<PrivetHTTPAsynchronousFactory>
83     PrivetHTTPAsynchronousFactory::CreateInstance(
84         ServiceDiscoveryClient* service_discovery_client,
85         net::URLRequestContextGetter* request_context) {
86   return make_scoped_ptr<PrivetHTTPAsynchronousFactory>(
87       new PrivetHTTPAsynchronousFactoryImpl(service_discovery_client,
88                                             request_context));
89 }
90
91 scoped_ptr<PrivetHTTPResolution>
92     PrivetHTTPAsynchronousFactoryImpl::CreatePrivetHTTP(
93         const std::string& name,
94         const net::HostPortPair& address,
95         const ResultCallback& callback) {
96   return scoped_ptr<PrivetHTTPResolution>(
97       new ResolutionImpl(name, address, callback, service_discovery_client_,
98                          request_context_.get()));
99 }
100
101 PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolutionImpl(
102     const std::string& name,
103     const net::HostPortPair& address,
104     const ResultCallback& callback,
105     ServiceDiscoveryClient* service_discovery_client,
106     net::URLRequestContextGetter* request_context)
107     : name_(name), hostport_(address), callback_(callback),
108       request_context_(request_context) {
109   net::AddressFamily address_family = net::ADDRESS_FAMILY_UNSPECIFIED;
110
111   if (CommandLine::ForCurrentProcess()->HasSwitch(
112           switches::kPrivetIPv6Only)) {
113     address_family = net::ADDRESS_FAMILY_IPV6;
114   }
115
116   resolver_ = service_discovery_client->CreateLocalDomainResolver(
117       address.host(), address_family,
118       base::Bind(&ResolutionImpl::ResolveComplete, base::Unretained(this)));
119 }
120
121 PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::~ResolutionImpl() {
122 }
123
124 void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::Start() {
125   resolver_->Start();
126 }
127
128 void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolveComplete(
129     bool success,
130     const net::IPAddressNumber& address_ipv4,
131     const net::IPAddressNumber& address_ipv6) {
132   if (!success) {
133     callback_.Run(scoped_ptr<PrivetHTTPClient>());
134     return;
135   }
136
137   net::IPAddressNumber address = address_ipv4;
138   if (address.empty())
139     address = address_ipv6;
140
141   DCHECK(!address.empty());
142
143   net::HostPortPair new_address = net::HostPortPair(
144       IPAddressToHostString(address), hostport_.port());
145   callback_.Run(scoped_ptr<PrivetHTTPClient>(
146       new PrivetHTTPClientImpl(name_, new_address, request_context_.get())));
147 }
148
149 }  // namespace local_discovery