1// Copyright (c) 2012 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/chrome_net_benchmarking_message_filter.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/command_line.h"
10#include "base/memory/scoped_ptr.h"
11#include "chrome/browser/net/chrome_url_request_context.h"
12#include "chrome/browser/net/predictor.h"
13#include "chrome/browser/profiles/profile.h"
14#include "chrome/common/benchmarking_messages.h"
15#include "chrome/common/chrome_switches.h"
16#include "net/base/net_errors.h"
17#include "net/disk_cache/disk_cache.h"
18#include "net/dns/host_cache.h"
19#include "net/dns/host_resolver.h"
20#include "net/http/http_cache.h"
21#include "net/http/http_network_layer.h"
22#include "net/http/http_stream_factory.h"
23
24namespace {
25
26void ClearCacheCallback(ChromeNetBenchmarkingMessageFilter* filter,
27                        IPC::Message* reply_msg,
28                        int result) {
29  ChromeViewHostMsg_ClearCache::WriteReplyParams(reply_msg, result);
30  filter->Send(reply_msg);
31}
32
33}  // namespace
34
35ChromeNetBenchmarkingMessageFilter::ChromeNetBenchmarkingMessageFilter(
36    int render_process_id,
37    Profile* profile,
38    net::URLRequestContextGetter* request_context)
39    : render_process_id_(render_process_id),
40      profile_(profile),
41      request_context_(request_context) {
42}
43
44ChromeNetBenchmarkingMessageFilter::~ChromeNetBenchmarkingMessageFilter() {
45}
46
47bool ChromeNetBenchmarkingMessageFilter::OnMessageReceived(
48    const IPC::Message& message, bool* message_was_ok) {
49  bool handled = true;
50  IPC_BEGIN_MESSAGE_MAP_EX(ChromeNetBenchmarkingMessageFilter, message,
51                           *message_was_ok)
52    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CloseCurrentConnections,
53                        OnCloseCurrentConnections)
54    IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_ClearCache, OnClearCache)
55    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ClearHostResolverCache,
56                        OnClearHostResolverCache)
57    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_EnableSpdy, OnEnableSpdy)
58    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ClearPredictorCache,
59                        OnClearPredictorCache)
60    IPC_MESSAGE_UNHANDLED(handled = false)
61  IPC_END_MESSAGE_MAP_EX()
62  return handled;
63}
64
65void ChromeNetBenchmarkingMessageFilter::OnClearCache(IPC::Message* reply_msg) {
66  // This function is disabled unless the user has enabled
67  // benchmarking extensions.
68  if (!CheckBenchmarkingEnabled()) {
69    NOTREACHED() << "Received unexpected benchmarking IPC";
70    return;
71  }
72  int rv = -1;
73
74  disk_cache::Backend* backend = request_context_->GetURLRequestContext()->
75      http_transaction_factory()->GetCache()->GetCurrentBackend();
76  if (backend) {
77    net::CompletionCallback callback =
78        base::Bind(&ClearCacheCallback, make_scoped_refptr(this), reply_msg);
79    rv = backend->DoomAllEntries(callback);
80    if (rv == net::ERR_IO_PENDING) {
81      // The callback will send the reply.
82      return;
83    }
84  }
85  ChromeViewHostMsg_ClearCache::WriteReplyParams(reply_msg, rv);
86  Send(reply_msg);
87}
88
89void ChromeNetBenchmarkingMessageFilter::OnClearHostResolverCache(int* result) {
90  // This function is disabled unless the user has enabled
91  // benchmarking extensions.
92  if (!CheckBenchmarkingEnabled()) {
93    NOTREACHED() << "Received unexpected benchmarking IPC";
94    return;
95  }
96  *result = -1;
97  net::HostCache* cache =
98      request_context_->GetURLRequestContext()->host_resolver()->GetHostCache();
99  if (cache) {
100    cache->clear();
101    *result = 0;
102  }
103}
104
105// TODO(lzheng): This only enables spdy over ssl. Enable spdy for http
106// when needed.
107void ChromeNetBenchmarkingMessageFilter::OnEnableSpdy(bool enable) {
108  // This function is disabled unless the user has enabled
109  // benchmarking extensions.
110  if (!CheckBenchmarkingEnabled()) {
111    NOTREACHED() << "Received unexpected benchmarking IPC";
112    return;
113  }
114  if (enable) {
115    net::HttpStreamFactory::EnableNpnSpdy3();
116    net::HttpNetworkLayer::ForceAlternateProtocol();
117  } else {
118    net::HttpStreamFactory::EnableNpnHttpOnly();
119  }
120}
121
122void ChromeNetBenchmarkingMessageFilter::OnCloseCurrentConnections() {
123  // This function is disabled unless the user has enabled
124  // benchmarking extensions.
125  if (!CheckBenchmarkingEnabled()) {
126    NOTREACHED() << "Received unexpected benchmarking IPC";
127    return;
128  }
129  request_context_->GetURLRequestContext()->
130      http_transaction_factory()->GetCache()->CloseAllConnections();
131}
132
133void ChromeNetBenchmarkingMessageFilter::OnSetCacheMode(bool enabled) {
134  // This function is disabled unless the user has enabled
135  // benchmarking extensions.
136  if (!CheckBenchmarkingEnabled()) {
137    NOTREACHED() << "Received unexpected benchmarking IPC";
138    return;
139  }
140  net::HttpCache::Mode mode = enabled ?
141      net::HttpCache::NORMAL : net::HttpCache::DISABLE;
142  net::HttpCache* http_cache = request_context_->GetURLRequestContext()->
143      http_transaction_factory()->GetCache();
144  http_cache->set_mode(mode);
145}
146
147void ChromeNetBenchmarkingMessageFilter::OnClearPredictorCache(int* result) {
148  // This function is disabled unless the user has enabled
149  // benchmarking extensions.
150  if (!CheckBenchmarkingEnabled()) {
151    NOTREACHED() << "Received unexpected benchmarking IPC";
152    return;
153  }
154  chrome_browser_net::Predictor* predictor = profile_->GetNetworkPredictor();
155  if (predictor)
156    predictor->DiscardAllResults();
157  *result = 0;
158}
159
160bool ChromeNetBenchmarkingMessageFilter::CheckBenchmarkingEnabled() const {
161  static bool checked = false;
162  static bool result = false;
163  if (!checked) {
164    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
165    result = command_line.HasSwitch(switches::kEnableNetBenchmarking);
166    checked = true;
167  }
168  return result;
169}
170
171