OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/search/suggestions/suggestions_service.h" | 5 #include "chrome/browser/search/suggestions/suggestions_service.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/metrics/sparse_histogram.h" | 10 #include "base/metrics/sparse_histogram.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/history/history_types.h" | 13 #include "chrome/browser/history/history_types.h" |
14 #include "chrome/browser/metrics/variations/variations_http_header_provider.h" | 14 #include "chrome/browser/metrics/variations/variations_http_header_provider.h" |
15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
16 #include "components/variations/variations_associated_data.h" | 16 #include "components/variations/variations_associated_data.h" |
17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
18 #include "net/base/escape.h" | |
18 #include "net/base/load_flags.h" | 19 #include "net/base/load_flags.h" |
19 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
20 #include "net/http/http_response_headers.h" | 21 #include "net/http/http_response_headers.h" |
21 #include "net/http/http_status_code.h" | 22 #include "net/http/http_status_code.h" |
22 #include "net/http/http_util.h" | 23 #include "net/http/http_util.h" |
23 #include "net/url_request/url_fetcher.h" | 24 #include "net/url_request/url_fetcher.h" |
24 #include "net/url_request/url_request_status.h" | 25 #include "net/url_request/url_request_status.h" |
25 #include "url/gurl.h" | 26 #include "url/gurl.h" |
26 | 27 |
27 namespace suggestions { | 28 namespace suggestions { |
(...skipping 29 matching lines...) Expand all Loading... | |
57 for (it = requestors->begin(); it != requestors->end(); ++it) { | 58 for (it = requestors->begin(); it != requestors->end(); ++it) { |
58 it->Run(suggestions); | 59 it->Run(suggestions); |
59 } | 60 } |
60 std::vector<SuggestionsService::ResponseCallback>().swap(*requestors); | 61 std::vector<SuggestionsService::ResponseCallback>().swap(*requestors); |
61 } | 62 } |
62 | 63 |
63 } // namespace | 64 } // namespace |
64 | 65 |
65 const char kSuggestionsFieldTrialName[] = "ChromeSuggestions"; | 66 const char kSuggestionsFieldTrialName[] = "ChromeSuggestions"; |
66 const char kSuggestionsFieldTrialURLParam[] = "url"; | 67 const char kSuggestionsFieldTrialURLParam[] = "url"; |
68 const char kSuggestionsFieldTrialSuggestionsSuffixParam[] = | |
69 "suggestions_suffix"; | |
70 const char kSuggestionsFieldTrialBlacklistSuffixParam[] = "blacklist_suffix"; | |
67 const char kSuggestionsFieldTrialStateParam[] = "state"; | 71 const char kSuggestionsFieldTrialStateParam[] = "state"; |
68 const char kSuggestionsFieldTrialStateEnabled[] = "enabled"; | 72 const char kSuggestionsFieldTrialStateEnabled[] = "enabled"; |
69 | 73 |
70 SuggestionsService::SuggestionsService(Profile* profile) | 74 SuggestionsService::SuggestionsService(Profile* profile) |
71 : profile_(profile) { | 75 : profile_(profile) { |
72 // Obtain the URL to use to fetch suggestions data from the Variations param. | 76 // Obtain the URL to use to fetch suggestions data from the Variations param. |
73 suggestions_url_ = GURL(GetExperimentParam(kSuggestionsFieldTrialURLParam)); | 77 suggestions_url_ = GURL( |
78 GetExperimentParam(kSuggestionsFieldTrialURLParam) + | |
79 GetExperimentParam(kSuggestionsFieldTrialSuggestionsSuffixParam)); | |
80 blacklist_url_prefix_ = GetExperimentParam(kSuggestionsFieldTrialURLParam) + | |
81 GetExperimentParam(kSuggestionsFieldTrialBlacklistSuffixParam); | |
74 } | 82 } |
75 | 83 |
76 SuggestionsService::~SuggestionsService() { | 84 SuggestionsService::~SuggestionsService() { |
77 } | 85 } |
78 | 86 |
79 // static | 87 // static |
80 bool SuggestionsService::IsEnabled() { | 88 bool SuggestionsService::IsEnabled() { |
81 return GetExperimentParam(kSuggestionsFieldTrialStateParam) == | 89 return GetExperimentParam(kSuggestionsFieldTrialStateParam) == |
82 kSuggestionsFieldTrialStateEnabled; | 90 kSuggestionsFieldTrialStateEnabled; |
83 } | 91 } |
84 | 92 |
85 void SuggestionsService::FetchSuggestionsData( | 93 void SuggestionsService::FetchSuggestionsData( |
86 SuggestionsService::ResponseCallback callback) { | 94 SuggestionsService::ResponseCallback callback) { |
87 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 95 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
88 | 96 |
89 if (pending_request_.get()) { | 97 if (pending_request_.get()) { |
90 // Request already exists, so just add requestor to queue. | 98 // Request already exists, so just add requestor to queue. |
91 waiting_requestors_.push_back(callback); | 99 waiting_requestors_.push_back(callback); |
92 return; | 100 return; |
93 } | 101 } |
94 | 102 |
95 // Form new request. | 103 // Form new request. |
96 DCHECK(waiting_requestors_.empty()); | 104 DCHECK(waiting_requestors_.empty()); |
97 waiting_requestors_.push_back(callback); | 105 waiting_requestors_.push_back(callback); |
98 | 106 |
99 pending_request_.reset(net::URLFetcher::Create( | 107 pending_request_.reset(CreateSuggestionsRequest(suggestions_url_)); |
100 0, suggestions_url_, net::URLFetcher::GET, this)); | |
101 pending_request_->SetLoadFlags(net::LOAD_DISABLE_CACHE); | |
102 pending_request_->SetRequestContext(profile_->GetRequestContext()); | |
103 // Add Chrome experiment state to the request headers. | |
104 net::HttpRequestHeaders headers; | |
105 chrome_variations::VariationsHttpHeaderProvider::GetInstance()-> | |
106 AppendHeaders(pending_request_->GetOriginalURL(), | |
107 profile_->IsOffTheRecord(), false, &headers); | |
108 pending_request_->SetExtraRequestHeaders(headers.ToString()); | |
109 pending_request_->Start(); | 108 pending_request_->Start(); |
110 | 109 |
111 last_request_started_time_ = base::TimeTicks::Now(); | 110 last_request_started_time_ = base::TimeTicks::Now(); |
112 } | 111 } |
113 | 112 |
113 void SuggestionsService::AddBlacklistedURL( | |
114 const std::string& candidate_url, | |
115 SuggestionsService::ResponseCallback callback) { | |
116 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
117 waiting_requestors_.push_back(callback); | |
118 | |
119 if (pending_request_.get()) { | |
120 if (IsBlacklistRequest(pending_request_.get())) { | |
121 // Pending request is a blacklist request. Silently drop the new blacklist | |
122 // request. TODO - handle this case. | |
123 return; | |
124 } else { | |
125 // Pending request is not a blacklist request - cancel it and go on to | |
126 // issueing a blacklist request. | |
Mathieu
2014/05/22 21:50:49
*issuing
manzagop (departed)
2014/05/23 15:20:02
Done.
| |
127 pending_request_.reset(); | |
128 } | |
129 } | |
130 | |
131 // Send blacklisting request. | |
132 GURL url(blacklist_url_prefix_ + | |
133 net::EscapeQueryParamValue(candidate_url, true)); | |
134 pending_request_.reset(CreateSuggestionsRequest(url)); | |
135 pending_request_->Start(); | |
136 last_request_started_time_ = base::TimeTicks::Now(); | |
137 } | |
138 | |
114 void SuggestionsService::OnURLFetchComplete(const net::URLFetcher* source) { | 139 void SuggestionsService::OnURLFetchComplete(const net::URLFetcher* source) { |
115 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 140 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
116 DCHECK_EQ(pending_request_.get(), source); | 141 DCHECK_EQ(pending_request_.get(), source); |
117 | 142 |
118 // The fetcher will be deleted when the request is handled. | 143 // The fetcher will be deleted when the request is handled. |
119 scoped_ptr<const net::URLFetcher> request(pending_request_.release()); | 144 scoped_ptr<const net::URLFetcher> request(pending_request_.release()); |
120 const net::URLRequestStatus& request_status = request->GetStatus(); | 145 const net::URLRequestStatus& request_status = request->GetStatus(); |
121 if (request_status.status() != net::URLRequestStatus::SUCCESS) { | 146 if (request_status.status() != net::URLRequestStatus::SUCCESS) { |
122 UMA_HISTOGRAM_SPARSE_SLOWLY("Suggestions.FailedRequestErrorCode", | 147 UMA_HISTOGRAM_SPARSE_SLOWLY("Suggestions.FailedRequestErrorCode", |
123 -request_status.error()); | 148 -request_status.error()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 } | 187 } |
163 | 188 |
164 void SuggestionsService::Shutdown() { | 189 void SuggestionsService::Shutdown() { |
165 // Cancel pending request. | 190 // Cancel pending request. |
166 pending_request_.reset(NULL); | 191 pending_request_.reset(NULL); |
167 | 192 |
168 // Dispatch empty suggestions to requestors. | 193 // Dispatch empty suggestions to requestors. |
169 DispatchRequestsAndClear(SuggestionsProfile(), &waiting_requestors_); | 194 DispatchRequestsAndClear(SuggestionsProfile(), &waiting_requestors_); |
170 } | 195 } |
171 | 196 |
197 bool SuggestionsService::IsBlacklistRequest(net::URLFetcher* request) const { | |
198 DCHECK(request); | |
199 return StartsWithASCII(request->GetOriginalURL().spec(), | |
200 blacklist_url_prefix_, | |
201 true); | |
202 } | |
203 | |
204 net::URLFetcher* SuggestionsService::CreateSuggestionsRequest(const GURL& url) { | |
205 net::URLFetcher* request = net::URLFetcher::Create( | |
206 0, url, net::URLFetcher::GET, this); | |
207 request->SetLoadFlags(net::LOAD_DISABLE_CACHE); | |
208 request->SetRequestContext(profile_->GetRequestContext()); | |
209 // Add Chrome experiment state to the request headers. | |
210 net::HttpRequestHeaders headers; | |
211 chrome_variations::VariationsHttpHeaderProvider::GetInstance()-> | |
212 AppendHeaders(request->GetOriginalURL(), profile_->IsOffTheRecord(), | |
213 false, &headers); | |
214 request->SetExtraRequestHeaders(headers.ToString()); | |
215 return request; | |
216 } | |
217 | |
172 } // namespace suggestions | 218 } // namespace suggestions |
OLD | NEW |