blob: 20f8342cc958f1ecb99ca71da798d7c901e628bc [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/network_hints/browser/network_hints_message_filter.h"
#include "base/logging.h"
#include "base/macros.h"
#include "components/network_hints/common/network_hints_common.h"
#include "components/network_hints/common/network_hints_messages.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/dns/host_resolver.h"
#include "net/dns/single_request_host_resolver.h"
#include "url/gurl.h"
namespace network_hints {
namespace {
const int kDefaultPort = 80;
class DnsLookupRequest {
public:
DnsLookupRequest(net::HostResolver* host_resolver,
const std::string& hostname)
: hostname_(hostname),
resolver_(host_resolver) {
}
// Return underlying network resolver status.
// net::OK ==> Host was found synchronously.
// net:ERR_IO_PENDING ==> Network will callback later with result.
// anything else ==> Host was not found synchronously.
int Start() {
net::HostResolver::RequestInfo resolve_info(
net::HostPortPair(hostname_, kDefaultPort));
// Make a note that this is a speculative resolve request. This allows
// separating it from real navigations in the observer's callback, and
// lets the HostResolver know it can be de-prioritized.
resolve_info.set_is_speculative(true);
return resolver_.Resolve(
resolve_info,
net::DEFAULT_PRIORITY,
&addresses_,
base::Bind(&DnsLookupRequest::OnLookupFinished, base::Owned(this)),
net::BoundNetLog());
}
private:
void OnLookupFinished(int result) {
VLOG(2) << __FUNCTION__ << ": " << hostname_ << ", result=" << result;
}
const std::string hostname_;
net::SingleRequestHostResolver resolver_;
net::AddressList addresses_;
DISALLOW_COPY_AND_ASSIGN(DnsLookupRequest);
};
} // namespace
NetworkHintsMessageFilter::NetworkHintsMessageFilter(
net::HostResolver* host_resolver)
: content::BrowserMessageFilter(NetworkHintsMsgStart),
host_resolver_(host_resolver) {
DCHECK(host_resolver_);
}
NetworkHintsMessageFilter::~NetworkHintsMessageFilter() {
}
bool NetworkHintsMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NetworkHintsMessageFilter, message)
IPC_MESSAGE_HANDLER(NetworkHintsMsg_DNSPrefetch, OnDnsPrefetch)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void NetworkHintsMessageFilter::OnDnsPrefetch(
const LookupRequest& lookup_request) {
DCHECK(host_resolver_);
for (const std::string& hostname : lookup_request.hostname_list) {
DnsLookupRequest* request = new DnsLookupRequest(host_resolver_, hostname);
// Note: DnsLookupRequest will be freed by the base::Owned call when
// resolving has completed.
request->Start();
}
}
} // namespace network_hints