1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/browser/api/dns/dns_api.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/browser/browser_context.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/browser/resource_context.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/browser/api/dns/host_resolver_wrapper.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/api/dns.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochusing extensions::core_api::dns::ResolveCallbackResolveInfo;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace Resolve = extensions::core_api::dns::Resolve;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DnsResolveFunction::DnsResolveFunction()
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    : resource_context_(NULL),
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      response_(false),
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_handle_(new net::HostResolver::RequestHandle()),
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      addresses_(new net::AddressList) {}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DnsResolveFunction::~DnsResolveFunction() {}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool DnsResolveFunction::RunAsync() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Resolve::Params> params(Resolve::Params::Create(*args_));
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hostname_ = params->hostname;
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  resource_context_ = browser_context()->GetResourceContext();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = BrowserThread::PostTask(
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      BrowserThread::IO,
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      FROM_HERE,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DnsResolveFunction::WorkOnIOThread, this));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(result);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DnsResolveFunction::WorkOnIOThread() {
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HostResolver* host_resolver =
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      HostResolverWrapper::GetInstance()->GetHostResolver(resource_context_);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(host_resolver);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Yes, we are passing zero as the port. There are some interesting but not
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // presently relevant reasons why HostResolver asks for the port of the
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hostname you'd like to resolve, even though it doesn't use that value in
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // determining its answer.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HostPortPair host_port_pair(hostname_, 0);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HostResolver::RequestInfo request_info(host_port_pair);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resolve_result = host_resolver->Resolve(
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_info,
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      net::DEFAULT_PRIORITY,
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      addresses_.get(),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DnsResolveFunction::OnLookupFinished, this),
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_handle_.get(),
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      net::BoundNetLog());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Balanced in OnLookupFinished.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resolve_result != net::ERR_IO_PENDING)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnLookupFinished(resolve_result);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DnsResolveFunction::RespondOnUIThread() {
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(response_);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DnsResolveFunction::OnLookupFinished(int resolve_result) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ResolveCallbackResolveInfo> resolve_info(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ResolveCallbackResolveInfo());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolve_info->result_code = resolve_result;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resolve_result == net::OK) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!addresses_->empty());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resolve_info->address.reset(
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new std::string(addresses_->front().ToStringWithoutPort()));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results_ = Resolve::Results::Create(*resolve_info);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_ = true;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool post_task_result = BrowserThread::PostTask(
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      BrowserThread::UI,
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      FROM_HERE,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DnsResolveFunction::RespondOnUIThread, this));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(post_task_result);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();  // Added in WorkOnIOThread().
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
104