OLD | NEW |
1 // Copyright 2008, Google Inc. | 1 // Copyright 2008, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 166 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
167 history_service->GetMostRecentKeywordSearchTerms(default_provider_.id(), | 167 history_service->GetMostRecentKeywordSearchTerms(default_provider_.id(), |
168 input_.text(), static_cast<int>(max_matches()), | 168 input_.text(), static_cast<int>(max_matches()), |
169 &history_request_consumer_, | 169 &history_request_consumer_, |
170 NewCallback(this, &SearchProvider::OnGotMostRecentKeywordSearchTerms)); | 170 NewCallback(this, &SearchProvider::OnGotMostRecentKeywordSearchTerms)); |
171 history_request_pending_ = true; | 171 history_request_pending_ = true; |
172 } | 172 } |
173 | 173 |
174 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes, | 174 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes, |
175 bool synchronous_only) { | 175 bool synchronous_only) { |
176 // Don't run Suggest when off the record, the engine doesn't support it, or | 176 if (!IsQuerySuitableForSuggest()) { |
177 // the user has disabled it. Also don't query the server for URLs that aren't | |
178 // http/https/ftp. Sending things like file: and data: is both a waste of | |
179 // time and a disclosure of potentially private, local data. | |
180 if (profile_->IsOffTheRecord() || | |
181 !default_provider_.suggestions_url() || | |
182 !profile_->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled) || | |
183 ((input_.type() == AutocompleteInput::URL) && | |
184 (input_.scheme() != L"http") && (input_.scheme() != L"https") && | |
185 (input_.scheme() != L"ftp"))) { | |
186 StopSuggest(); | 177 StopSuggest(); |
187 return; | 178 return; |
188 } | 179 } |
189 | 180 |
190 // For the minimal_changes case, if we finished the previous query and still | 181 // For the minimal_changes case, if we finished the previous query and still |
191 // have its results, or are allowed to keep running it, just do that, rather | 182 // have its results, or are allowed to keep running it, just do that, rather |
192 // than starting a new query. | 183 // than starting a new query. |
193 if (minimal_changes && | 184 if (minimal_changes && |
194 (have_suggest_results_ || (!done_ && !synchronous_only))) | 185 (have_suggest_results_ || (!done_ && !synchronous_only))) |
195 return; | 186 return; |
196 | 187 |
197 // We can't keep running any previous query, so halt it. | 188 // We can't keep running any previous query, so halt it. |
198 StopSuggest(); | 189 StopSuggest(); |
199 | 190 |
200 // We can't start a new query if we're only allowed synchronous results. | 191 // We can't start a new query if we're only allowed synchronous results. |
201 if (synchronous_only) | 192 if (synchronous_only) |
202 return; | 193 return; |
203 | 194 |
204 // Kick off a timer that will start the URL fetch if it completes before | 195 // Kick off a timer that will start the URL fetch if it completes before |
205 // the user types another character. | 196 // the user types another character. |
206 suggest_results_pending_ = true; | 197 suggest_results_pending_ = true; |
207 MessageLoop::current()->timer_manager()->ResetTimer(timer_.get()); | 198 MessageLoop::current()->timer_manager()->ResetTimer(timer_.get()); |
208 } | 199 } |
209 | 200 |
| 201 bool SearchProvider::IsQuerySuitableForSuggest() const { |
| 202 // Don't run Suggest when off the record, the engine doesn't support it, or |
| 203 // the user has disabled it. |
| 204 if (profile_->IsOffTheRecord() || |
| 205 !default_provider_.suggestions_url() || |
| 206 !profile_->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled)) |
| 207 return false; |
| 208 |
| 209 // If the input type is URL, we take extra care so that private data in URL |
| 210 // isn't sent to the server. |
| 211 if (input_.type() == AutocompleteInput::URL) { |
| 212 // Don't query the server for URLs that aren't http/https/ftp. Sending |
| 213 // things like file: and data: is both a waste of time and a disclosure of |
| 214 // potentially private, local data. |
| 215 if ((input_.scheme() != L"http") && (input_.scheme() != L"https") && |
| 216 (input_.scheme() != L"ftp")) |
| 217 return false; |
| 218 |
| 219 // Don't leak private data in URL |
| 220 const url_parse::Parsed& parts = input_.parts(); |
| 221 |
| 222 // Don't send URLs with usernames, queries or refs. Some of these are |
| 223 // private, and the Suggest server is unlikely to have any useful results |
| 224 // for any of them. |
| 225 // Password is optional and may be omitted. Checking username is |
| 226 // sufficient. |
| 227 if (parts.username.is_nonempty() || parts.query.is_nonempty() || |
| 228 parts.ref.is_nonempty()) |
| 229 return false; |
| 230 // Don't send anything for https except hostname and port number. |
| 231 // Hostname and port number are OK because they are visible when TCP |
| 232 // connection is established and the Suggest server may provide some |
| 233 // useful completed URL. |
| 234 if (input_.scheme() == L"https" && parts.path.is_nonempty()) |
| 235 return false; |
| 236 } |
| 237 |
| 238 return true; |
| 239 } |
| 240 |
210 void SearchProvider::StopHistory() { | 241 void SearchProvider::StopHistory() { |
211 history_request_consumer_.CancelAllRequests(); | 242 history_request_consumer_.CancelAllRequests(); |
212 history_request_pending_ = false; | 243 history_request_pending_ = false; |
213 history_results_.clear(); | 244 history_results_.clear(); |
214 have_history_results_ = false; | 245 have_history_results_ = false; |
215 } | 246 } |
216 | 247 |
217 void SearchProvider::StopSuggest() { | 248 void SearchProvider::StopSuggest() { |
218 suggest_results_pending_ = false; | 249 suggest_results_pending_ = false; |
219 MessageLoop::current()->timer_manager()->StopTimer(timer_.get()); | 250 MessageLoop::current()->timer_manager()->StopTimer(timer_.get()); |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 const size_t after_slashes = std::min(url->length(), | 645 const size_t after_slashes = std::min(url->length(), |
615 static_cast<size_t>(scheme.end() + 3)); | 646 static_cast<size_t>(scheme.end() + 3)); |
616 while ((prefix_len < after_slashes) && ((*url)[prefix_len] == L'/')) | 647 while ((prefix_len < after_slashes) && ((*url)[prefix_len] == L'/')) |
617 ++prefix_len; | 648 ++prefix_len; |
618 if (prefix_len == url->length()) | 649 if (prefix_len == url->length()) |
619 url->clear(); | 650 url->clear(); |
620 else | 651 else |
621 url->erase(url->begin(), url->begin() + prefix_len); | 652 url->erase(url->begin(), url->begin() + prefix_len); |
622 return prefix_len; | 653 return prefix_len; |
623 } | 654 } |
OLD | NEW |