Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / net / spdyproxy / proxy_advisor.cc
blobf15851acc400a4d6b202f3dc5e1a737e9d71a652
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.
5 #include "chrome/browser/net/spdyproxy/proxy_advisor.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/stl_util.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/common/pref_names.h"
14 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "net/base/load_flags.h"
17 #include "net/base/request_priority.h"
18 #include "net/http/http_status_code.h"
19 #include "net/proxy/proxy_info.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/url_request/url_request_context.h"
22 #include "net/url_request/url_request_context_getter.h"
24 // Ensure data reduction features are available.
25 #if !defined(OS_ANDROID) && !defined(OS_IOS)
26 #error proxy_advisor should only be included in Android or iOS builds.
27 #endif
29 using content::BrowserThread;
30 using data_reduction_proxy::DataReductionProxySettings;
32 namespace {
33 const char kOmniboxMotivation[] = "omnibox";
34 const char kLowThresholdOmniboxMotivation[] = "low_threshold_omnibox";
35 const char kStartupDNSMotivation[] = "startup_dns";
36 const char kEarlyLoadMotivation[] = "early_load";
37 const char kLearnedReferralMotivation[] = "learned_referral";
38 const char kLowThresholdLearnedReferralMotivation[] =
39 "low_threshold_learned_referral";
40 const char kSelfReferralMotivation[] = "self_referral";
41 const char kPageScanMotivation[] = "page_scan";
43 // Maps a ResolutionMotivation to a string for use in the advisory HEAD
44 // request.
45 const char* MotivationName(
46 chrome_browser_net::UrlInfo::ResolutionMotivation motivation,
47 bool is_preconnect) {
48 switch (motivation) {
49 case chrome_browser_net::UrlInfo::OMNIBOX_MOTIVATED:
50 return
51 is_preconnect ? kOmniboxMotivation : kLowThresholdOmniboxMotivation;
52 case chrome_browser_net::UrlInfo::STARTUP_LIST_MOTIVATED:
53 return kStartupDNSMotivation;
54 case chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED:
55 return kEarlyLoadMotivation;
56 case chrome_browser_net::UrlInfo::LEARNED_REFERAL_MOTIVATED:
57 return is_preconnect ?
58 kLearnedReferralMotivation : kLowThresholdLearnedReferralMotivation;
59 case chrome_browser_net::UrlInfo::SELF_REFERAL_MOTIVATED:
60 return kSelfReferralMotivation;
61 case chrome_browser_net::UrlInfo::PAGE_SCAN_MOTIVATED:
62 return kPageScanMotivation;
63 default:
64 // Other motivations should never be passed to here.
65 NOTREACHED();
66 break;
68 NOTREACHED();
69 return "";
72 } // namespace
74 ProxyAdvisor::ProxyAdvisor(PrefService* pref_service,
75 net::URLRequestContextGetter* context_getter)
76 : context_getter_(context_getter) {
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79 // pref_service may be null in mock test subclasses.
80 if (pref_service) {
81 proxy_pref_member_.Init(
82 data_reduction_proxy::prefs::kDataReductionProxyEnabled,
83 pref_service,
84 base::Bind(&ProxyAdvisor::UpdateProxyState, base::Unretained(this)));
85 proxy_pref_member_.MoveToThread(
86 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
90 ProxyAdvisor::~ProxyAdvisor() {
91 STLDeleteElements(&inflight_requests_);
94 void ProxyAdvisor::OnResponseStarted(net::URLRequest* request) {
95 const net::URLRequestStatus& status(request->status());
96 if (!status.is_success()) {
97 DLOG(WARNING) << "Proxy advisory failed "
98 << "status:" << status.status()
99 << " error:" << status.error();
100 } else if (request->GetResponseCode() != net::HTTP_OK) {
101 DLOG(WARNING) << "Proxy advisory status: " << request->GetResponseCode();
103 RequestComplete(request);
106 void ProxyAdvisor::OnReadCompleted(net::URLRequest* request, int bytes_read) {
107 // No-op for now, as we don't care yet.
110 void ProxyAdvisor::Advise(
111 const GURL& url,
112 chrome_browser_net::UrlInfo::ResolutionMotivation motivation,
113 bool is_preconnect) {
114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
116 if (!WouldProxyURL(url))
117 return;
119 std::string motivation_name(MotivationName(motivation, is_preconnect));
120 std::string header_value = motivation_name + " " + url.spec();
121 net::URLRequestContext* context = context_getter_->GetURLRequestContext();
122 std::string endpoint =
123 DataReductionProxySettings::GetDataReductionProxyOrigin() + "preconnect";
124 scoped_ptr<net::URLRequest> request = context->CreateRequest(
125 GURL(endpoint), net::DEFAULT_PRIORITY, this, NULL);
126 request->set_method("HEAD");
127 request->SetExtraRequestHeaderByName(
128 "Proxy-Host-Advisory", header_value, false);
129 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
130 net::LOAD_DO_NOT_SAVE_COOKIES |
131 net::LOAD_BYPASS_PROXY |
132 net::LOAD_DISABLE_CACHE);
133 net::URLRequest* raw_request = request.get();
134 inflight_requests_.insert(request.release());
135 raw_request->Start();
138 // TODO(marq): Move this into DataReductionProxySettings, and add support for
139 // inspecting the current proxy configs -- if ResolveProxy on |url| can be
140 // done synchronously, then this is no longer an approximation.
141 bool ProxyAdvisor::WouldProxyURL(const GURL& url) {
142 if (!proxy_pref_member_.GetValue())
143 return false;
145 if (url.SchemeIsSecure())
146 return false;
148 return true;
151 void ProxyAdvisor::RequestComplete(net::URLRequest* request) {
152 DCHECK_EQ(1u, inflight_requests_.count(request));
153 scoped_ptr<net::URLRequest> scoped_request_for_deletion(request);
154 inflight_requests_.erase(request);
155 // |scoped_request_for_deletion| will delete |request|
158 void ProxyAdvisor::UpdateProxyState() {
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
160 // Delete all inflight requests. Each request's destructor will call Cancel().
161 STLDeleteElements(&inflight_requests_);