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 "ppapi/proxy/host_resolver_resource_base.h" 6 7#include "base/bind.h" 8#include "ppapi/c/pp_errors.h" 9#include "ppapi/proxy/net_address_resource.h" 10#include "ppapi/proxy/ppapi_messages.h" 11#include "ppapi/shared_impl/tracked_callback.h" 12#include "ppapi/shared_impl/var.h" 13 14namespace ppapi { 15namespace proxy { 16 17namespace { 18 19int32_t ConvertPPError(int32_t pp_error, bool private_api) { 20 // The private API doesn't return network-specific error codes or 21 // PP_ERROR_NOACCESS. In order to preserve the behavior, we convert those to 22 // PP_ERROR_FAILED. 23 // TODO(yzshen): Consider defining ranges for different kinds of PP_Error 24 // codes, so that we can detect network-specific error codes in a better way. 25 if (private_api && 26 (pp_error <= PP_ERROR_CONNECTION_CLOSED || 27 pp_error == PP_ERROR_NOACCESS)) { 28 return PP_ERROR_FAILED; 29 } 30 31 return pp_error; 32} 33 34} // namespace 35 36HostResolverResourceBase::HostResolverResourceBase(Connection connection, 37 PP_Instance instance, 38 bool private_api) 39 : PluginResource(connection, instance), 40 private_api_(private_api), 41 allow_get_results_(false) { 42 if (private_api) 43 SendCreate(BROWSER, PpapiHostMsg_HostResolver_CreatePrivate()); 44 else 45 SendCreate(BROWSER, PpapiHostMsg_HostResolver_Create()); 46} 47 48HostResolverResourceBase::~HostResolverResourceBase() { 49} 50 51int32_t HostResolverResourceBase::ResolveImpl( 52 const char* host, 53 uint16_t port, 54 const PP_HostResolver_Private_Hint* hint, 55 scoped_refptr<TrackedCallback> callback) { 56 allow_get_results_ = false; 57 if (!host || !hint) 58 return PP_ERROR_BADARGUMENT; 59 if (ResolveInProgress()) 60 return PP_ERROR_INPROGRESS; 61 62 resolve_callback_ = callback; 63 64 HostPortPair host_port; 65 host_port.host = host; 66 host_port.port = port; 67 68 SendResolve(host_port, hint); 69 return PP_OK_COMPLETIONPENDING; 70} 71 72PP_Var HostResolverResourceBase::GetCanonicalNameImpl() { 73 if (!allow_get_results_) 74 return PP_MakeUndefined(); 75 76 return StringVar::StringToPPVar(canonical_name_); 77} 78 79uint32_t HostResolverResourceBase::GetSizeImpl() { 80 if (!allow_get_results_) 81 return 0; 82 return static_cast<uint32_t>(net_address_list_.size()); 83} 84 85scoped_refptr<NetAddressResource> HostResolverResourceBase::GetNetAddressImpl( 86 uint32_t index) { 87 if (!allow_get_results_ || index >= GetSizeImpl()) 88 return scoped_refptr<NetAddressResource>(); 89 90 return net_address_list_[index]; 91} 92 93void HostResolverResourceBase::OnPluginMsgResolveReply( 94 const ResourceMessageReplyParams& params, 95 const std::string& canonical_name, 96 const std::vector<PP_NetAddress_Private>& net_address_list) { 97 if (params.result() == PP_OK) { 98 allow_get_results_ = true; 99 canonical_name_ = canonical_name; 100 101 net_address_list_.clear(); 102 for (std::vector<PP_NetAddress_Private>::const_iterator iter = 103 net_address_list.begin(); 104 iter != net_address_list.end(); 105 ++iter) { 106 net_address_list_.push_back( 107 new NetAddressResource(connection(), pp_instance(), *iter)); 108 } 109 } else { 110 canonical_name_.clear(); 111 net_address_list_.clear(); 112 } 113 resolve_callback_->Run(ConvertPPError(params.result(), private_api_)); 114} 115 116void HostResolverResourceBase::SendResolve( 117 const HostPortPair& host_port, 118 const PP_HostResolver_Private_Hint* hint) { 119 PpapiHostMsg_HostResolver_Resolve msg(host_port, *hint); 120 Call<PpapiPluginMsg_HostResolver_ResolveReply>( 121 BROWSER, 122 msg, 123 base::Bind(&HostResolverResourceBase::OnPluginMsgResolveReply, 124 base::Unretained(this))); 125} 126 127bool HostResolverResourceBase::ResolveInProgress() const { 128 return TrackedCallback::IsPending(resolve_callback_); 129} 130 131} // namespace proxy 132} // namespace ppapi 133