webservice_search_provider.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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. 4 5#include "chrome/browser/ui/app_list/search/common/webservice_search_provider.h" 6 7#include <string> 8 9#include "base/callback.h" 10#include "base/strings/string_util.h" 11#include "chrome/browser/search/search.h" 12#include "chrome/common/url_constants.h" 13#include "url/gurl.h" 14 15namespace app_list { 16 17namespace { 18 19const int kWebserviceQueryThrottleIntrevalInMs = 100; 20const size_t kMinimumQueryLength = 3u; 21 22} // namespace 23 24WebserviceSearchProvider::WebserviceSearchProvider(Profile* profile) 25 : profile_(profile), use_throttling_(true) {} 26 27WebserviceSearchProvider::~WebserviceSearchProvider() {} 28 29void WebserviceSearchProvider::StartThrottledQuery( 30 const base::Closure& start_query) { 31 base::TimeDelta interval = 32 base::TimeDelta::FromMilliseconds(kWebserviceQueryThrottleIntrevalInMs); 33 if (!use_throttling_ || base::Time::Now() - last_keytyped_ > interval) { 34 query_throttler_.Stop(); 35 start_query.Run(); 36 } else { 37 query_throttler_.Start(FROM_HERE, interval, start_query); 38 } 39 last_keytyped_ = base::Time::Now(); 40} 41 42bool WebserviceSearchProvider::IsValidQuery(const string16& query) { 43 // If |query| contains sensitive data, bail out and do not create the place 44 // holder "search-web-store" result. 45 if (IsSensitiveInput(query) || 46 (query.size() < kMinimumQueryLength) || 47 !chrome::IsSuggestPrefEnabled(profile_)) { 48 return false; 49 } 50 51 return true; 52} 53 54// Returns whether or not the user's input string, |query|, might contain any 55// sensitive information, based purely on its value and not where it came from. 56bool WebserviceSearchProvider::IsSensitiveInput(const string16& query) { 57 const GURL query_as_url(query); 58 if (!query_as_url.is_valid()) 59 return false; 60 61 // The input can be interpreted as a URL. Check to see if it is potentially 62 // sensitive. (Code shamelessly copied from search_provider.cc's 63 // IsQuerySuitableForSuggest function.) 64 65 // First we check the scheme: if this looks like a URL with a scheme that is 66 // file, we shouldn't send it. Sending such things is a waste of time and a 67 // disclosure of potentially private, local data. If the scheme is OK, we 68 // still need to check other cases below. 69 if (LowerCaseEqualsASCII(query_as_url.scheme(), chrome::kFileScheme)) 70 return true; 71 72 // Don't send URLs with usernames, queries or refs. Some of these are 73 // private, and the Suggest server is unlikely to have any useful results 74 // for any of them. Also don't send URLs with ports, as we may initially 75 // think that a username + password is a host + port (and we don't want to 76 // send usernames/passwords), and even if the port really is a port, the 77 // server is once again unlikely to have and useful results. 78 if (!query_as_url.username().empty() || 79 !query_as_url.port().empty() || 80 !query_as_url.query().empty() || 81 !query_as_url.ref().empty()) { 82 return true; 83 } 84 85 // Don't send anything for https except the hostname. Hostnames are OK 86 // because they are visible when the TCP connection is established, but the 87 // specific path may reveal private information. 88 if (LowerCaseEqualsASCII(query_as_url.scheme(), content::kHttpsScheme) && 89 !query_as_url.path().empty() && query_as_url.path() != "/") { 90 return true; 91 } 92 93 return false; 94} 95 96} // namespace app_list 97