123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// found in the LICENSE file.
423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/local_discovery/privet_http_asynchronous_factory_impl.h"
623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/bind.h"
823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/command_line.h"
923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/strings/stringprintf.h"
1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/local_discovery/privet_http_impl.h"
1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace local_discovery {
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace {
1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)std::string IPAddressToHostString(const net::IPAddressNumber& address) {
1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::string address_str = net::IPAddressToString(address);
1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // IPv6 addresses need to be surrounded by brackets.
2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (address.size() == net::kIPv6AddressSize) {
2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    address_str = base::StringPrintf("[%s]", address_str.c_str());
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return address_str;
2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}  // namespace
2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)PrivetHTTPAsynchronousFactoryImpl::PrivetHTTPAsynchronousFactoryImpl(
3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ServiceDiscoveryClient* service_discovery_client,
3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    net::URLRequestContextGetter* request_context)
3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    : service_discovery_client_(service_discovery_client),
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      request_context_(request_context) {
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)PrivetHTTPAsynchronousFactoryImpl::~PrivetHTTPAsynchronousFactoryImpl() {
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)scoped_ptr<PrivetHTTPResolution>
4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)PrivetHTTPAsynchronousFactoryImpl::CreatePrivetHTTP(
4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& name,
4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const net::HostPortPair& address,
4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const ResultCallback& callback) {
4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return scoped_ptr<PrivetHTTPResolution>(
4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new ResolutionImpl(name,
4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                         address,
4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                         callback,
4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                         service_discovery_client_,
5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                         request_context_.get()));
5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolutionImpl(
5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& name,
5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const net::HostPortPair& address,
5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const ResultCallback& callback,
5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ServiceDiscoveryClient* service_discovery_client,
5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    net::URLRequestContextGetter* request_context)
5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    : name_(name),
6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      hostport_(address),
6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      callback_(callback),
6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      request_context_(request_context) {
6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  net::AddressFamily address_family = net::ADDRESS_FAMILY_UNSPECIFIED;
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kPrivetIPv6Only)) {
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    address_family = net::ADDRESS_FAMILY_IPV6;
6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  resolver_ = service_discovery_client->CreateLocalDomainResolver(
7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      address.host(),
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      address_family,
7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      base::Bind(&ResolutionImpl::ResolveComplete, base::Unretained(this)));
7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::~ResolutionImpl() {
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::Start() {
7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  resolver_->Start();
8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const std::string&
8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::GetName() {
8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return name_;
8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolveComplete(
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    bool success,
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const net::IPAddressNumber& address_ipv4,
9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const net::IPAddressNumber& address_ipv6) {
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!success) {
9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    callback_.Run(scoped_ptr<PrivetHTTPClient>());
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return;
9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  net::IPAddressNumber address = address_ipv4;
9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (address.empty())
9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    address = address_ipv6;
9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(!address.empty());
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  net::HostPortPair new_address =
10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      net::HostPortPair(IPAddressToHostString(address), hostport_.port());
10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  callback_.Run(scoped_ptr<PrivetHTTPClient>(
10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new PrivetHTTPClientImpl(name_, new_address, request_context_.get())));
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}  // namespace local_discovery
109