Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(980)

Side by Side Diff: chrome/browser/search/search.cc

Issue 17022004: Replace --google-base-suggest-url and --instant-url with --google-base-url. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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/search.h" 5 #include "chrome/browser/search/search.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.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/prefs/pref_service.h" 10 #include "base/prefs/pref_service.h"
11 #include "base/rand_util.h" 11 #include "base/rand_util.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
14 #include "chrome/browser/google/google_util.h"
14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/search/instant_service.h" 16 #include "chrome/browser/search/instant_service.h"
16 #include "chrome/browser/search/instant_service_factory.h" 17 #include "chrome/browser/search/instant_service_factory.h"
17 #include "chrome/browser/search_engines/template_url_prepopulate_data.h" 18 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
18 #include "chrome/browser/search_engines/template_url_service.h" 19 #include "chrome/browser/search_engines/template_url_service.h"
19 #include "chrome/browser/search_engines/template_url_service_factory.h" 20 #include "chrome/browser/search_engines/template_url_service_factory.h"
20 #include "chrome/browser/ui/browser.h" 21 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_instant_controller.h" 22 #include "chrome/browser/ui/browser_instant_controller.h"
22 #include "chrome/browser/ui/browser_iterator.h" 23 #include "chrome/browser/ui/browser_iterator.h"
23 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/chrome_switches.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 95 }
95 96
96 bool MatchesOrigin(const GURL& my_url, const GURL& other_url) { 97 bool MatchesOrigin(const GURL& my_url, const GURL& other_url) {
97 return my_url.host() == other_url.host() && 98 return my_url.host() == other_url.host() &&
98 my_url.port() == other_url.port() && 99 my_url.port() == other_url.port() &&
99 (my_url.scheme() == other_url.scheme() || 100 (my_url.scheme() == other_url.scheme() ||
100 (my_url.SchemeIs(chrome::kHttpsScheme) && 101 (my_url.SchemeIs(chrome::kHttpsScheme) &&
101 other_url.SchemeIs(chrome::kHttpScheme))); 102 other_url.SchemeIs(chrome::kHttpScheme)));
102 } 103 }
103 104
104 bool IsCommandLineInstantURL(const GURL& url) {
105 const CommandLine* cl = CommandLine::ForCurrentProcess();
106 const GURL instant_url(cl->GetSwitchValueASCII(switches::kInstantURL));
107 return instant_url.is_valid() && MatchesOrigin(url, instant_url);
108 }
109
110 bool MatchesAnySearchURL(const GURL& url, TemplateURL* template_url) { 105 bool MatchesAnySearchURL(const GURL& url, TemplateURL* template_url) {
111 GURL search_url = 106 GURL search_url =
112 TemplateURLRefToGURL(template_url->url_ref(), kDisableStartMargin); 107 TemplateURLRefToGURL(template_url->url_ref(), kDisableStartMargin);
113 if (search_url.is_valid() && MatchesOriginAndPath(url, search_url)) 108 if (search_url.is_valid() && MatchesOriginAndPath(url, search_url))
114 return true; 109 return true;
115 110
116 // "URLCount() - 1" because we already tested url_ref above. 111 // "URLCount() - 1" because we already tested url_ref above.
117 for (size_t i = 0; i < template_url->URLCount() - 1; ++i) { 112 for (size_t i = 0; i < template_url->URLCount() - 1; ++i) {
118 TemplateURLRef ref(template_url, i); 113 TemplateURLRef ref(template_url, i);
119 search_url = TemplateURLRefToGURL(ref, kDisableStartMargin); 114 search_url = TemplateURLRefToGURL(ref, kDisableStartMargin);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 return false; 155 return false;
161 156
162 const InstantService* instant_service = 157 const InstantService* instant_service =
163 InstantServiceFactory::GetForProfile(profile); 158 InstantServiceFactory::GetForProfile(profile);
164 if (!instant_service) 159 if (!instant_service)
165 return false; 160 return false;
166 161
167 return instant_service->IsInstantProcess(process_host->GetID()); 162 return instant_service->IsInstantProcess(process_host->GetID());
168 } 163 }
169 164
165 // Returns true if |url| passes some basic checks that must succeed for it to be
166 // usable as an instant URL:
167 // (1) It contains the search terms replacement key of |template_url|, which is
168 // expected to be the TemplateURL* for the default search provider.
169 // (2) Either it has a secure scheme, or else the user has manually specified a
170 // --google-base-url and it uses that base URL. (This allows testers to use
171 // --google-base-url to point at non-HTTPS servers, which eases testing.)
172 bool IsSuitableURLForInstant(const GURL& url, const TemplateURL* template_url) {
173 return template_url->HasSearchTermsReplacementKey(url) &&
174 (url.SchemeIsSecure() ||
175 google_util::StartsWithCommandLineGoogleBaseURL(url));
176 }
177
170 // Returns true if |url| can be used as an Instant URL for |profile|. 178 // Returns true if |url| can be used as an Instant URL for |profile|.
171 bool IsInstantURL(const GURL& url, Profile* profile) { 179 bool IsInstantURL(const GURL& url, Profile* profile) {
180 if (!url.is_valid())
181 return false;
182
172 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); 183 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
173 if (!template_url) 184 if (!template_url)
174 return false; 185 return false;
175 186
176 const TemplateURLRef& instant_url_ref = template_url->instant_url_ref();
177 const bool extended_api_enabled = IsInstantExtendedAPIEnabled(); 187 const bool extended_api_enabled = IsInstantExtendedAPIEnabled();
178 GURL effective_url = url; 188 if (extended_api_enabled && !IsSuitableURLForInstant(url, template_url))
179
180 if (IsCommandLineInstantURL(url))
181 effective_url = CoerceCommandLineURLToTemplateURL(url, instant_url_ref,
182 kDisableStartMargin);
183
184 if (!effective_url.is_valid())
185 return false; 189 return false;
186 190
187 if (extended_api_enabled && !effective_url.SchemeIsSecure()) 191 const TemplateURLRef& instant_url_ref = template_url->instant_url_ref();
188 return false;
189
190 if (extended_api_enabled &&
191 !template_url->HasSearchTermsReplacementKey(effective_url))
192 return false;
193
194 const GURL instant_url = 192 const GURL instant_url =
195 TemplateURLRefToGURL(instant_url_ref, kDisableStartMargin); 193 TemplateURLRefToGURL(instant_url_ref, kDisableStartMargin);
196 if (!instant_url.is_valid()) 194 return instant_url.is_valid() &&
197 return false; 195 (MatchesOriginAndPath(url, instant_url) ||
198 196 (extended_api_enabled && MatchesAnySearchURL(url, template_url)));
199 if (MatchesOriginAndPath(effective_url, instant_url))
200 return true;
201
202 if (extended_api_enabled && MatchesAnySearchURL(effective_url, template_url))
203 return true;
204
205 return false;
206 } 197 }
207 198
208 string16 GetSearchTermsImpl(const content::WebContents* contents, 199 string16 GetSearchTermsImpl(const content::WebContents* contents,
209 const content::NavigationEntry* entry) { 200 const content::NavigationEntry* entry) {
210 if (!IsQueryExtractionEnabled()) 201 if (!IsQueryExtractionEnabled())
211 return string16(); 202 return string16();
212 203
213 // For security reasons, don't extract search terms if the page is not being 204 // For security reasons, don't extract search terms if the page is not being
214 // rendered in the privileged Instant renderer process. This is to protect 205 // rendered in the privileged Instant renderer process. This is to protect
215 // against a malicious page somehow scripting the search results page and 206 // against a malicious page somehow scripting the search results page and
216 // faking search terms in the URL. Random pages can't get into the Instant 207 // faking search terms in the URL. Random pages can't get into the Instant
217 // renderer and scripting doesn't work cross-process, so if the page is in 208 // renderer and scripting doesn't work cross-process, so if the page is in
218 // the Instant process, we know it isn't being exploited. 209 // the Instant process, we know it isn't being exploited.
219 // Since iOS and Android doesn't use the instant framework, these checks are 210 // Since iOS and Android doesn't use the instant framework, these checks are
220 // disabled for the two platforms. 211 // disabled for the two platforms.
221 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 212 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
222 #if !defined(OS_IOS) && !defined(OS_ANDROID) 213 #if !defined(OS_IOS) && !defined(OS_ANDROID)
223 if (!IsRenderedInInstantProcess(contents, profile) && 214 if (!IsRenderedInInstantProcess(contents, profile) &&
224 (contents->GetController().GetLastCommittedEntry() == entry || 215 ((entry == contents->GetController().GetLastCommittedEntry()) ||
225 !ShouldAssignURLToInstantRenderer(entry->GetURL(), profile))) 216 !ShouldAssignURLToInstantRenderer(entry->GetURL(), profile)))
226 return string16(); 217 return string16();
227 #endif // !defined(OS_IOS) && !defined(OS_ANDROID) 218 #endif // !defined(OS_IOS) && !defined(OS_ANDROID)
228 // Check to see if search terms have already been extracted. 219 // Check to see if search terms have already been extracted.
229 string16 search_terms = GetSearchTermsFromNavigationEntry(entry); 220 string16 search_terms = GetSearchTermsFromNavigationEntry(entry);
230 if (!search_terms.empty()) 221 if (!search_terms.empty())
231 return search_terms; 222 return search_terms;
232 223
233 // Otherwise, extract from the URL. 224 // Otherwise, extract from the URL.
234 return GetSearchTermsFromURL(profile, entry->GetVirtualURL()); 225 return GetSearchTermsFromURL(profile, entry->GetVirtualURL());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 285
295 FieldTrialFlags flags; 286 FieldTrialFlags flags;
296 if (GetFieldTrialInfo( 287 if (GetFieldTrialInfo(
297 base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName), 288 base::FieldTrialList::FindFullName(kInstantExtendedFieldTrialName),
298 &flags, NULL)) { 289 &flags, NULL)) {
299 return GetBoolValueForFlagWithDefault(kLocalOnlyFlagName, false, flags); 290 return GetBoolValueForFlagWithDefault(kLocalOnlyFlagName, false, flags);
300 } 291 }
301 return false; 292 return false;
302 } 293 }
303 294
304 string16 GetSearchTermsFromURL(Profile* profile, const GURL& in_url) { 295 string16 GetSearchTermsFromURL(Profile* profile, const GURL& url) {
305 GURL url(in_url);
306 string16 search_terms; 296 string16 search_terms;
307
308 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); 297 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
309 if (!template_url) 298 if (template_url && IsSuitableURLForInstant(url, template_url))
310 return string16();
311
312 if (IsCommandLineInstantURL(url))
313 url = CoerceCommandLineURLToTemplateURL(url, template_url->url_ref(),
314 kDisableStartMargin);
315
316 if (url.SchemeIsSecure() && template_url->HasSearchTermsReplacementKey(url))
317 template_url->ExtractSearchTermsFromURL(url, &search_terms); 299 template_url->ExtractSearchTermsFromURL(url, &search_terms);
318
319 return search_terms; 300 return search_terms;
320 } 301 }
321 302
322 string16 GetSearchTermsFromNavigationEntry( 303 string16 GetSearchTermsFromNavigationEntry(
323 const content::NavigationEntry* entry) { 304 const content::NavigationEntry* entry) {
324 string16 search_terms; 305 string16 search_terms;
325 if (entry) 306 if (entry)
326 entry->GetExtraData(sessions::kSearchTermsKey, &search_terms); 307 entry->GetExtraData(sessions::kSearchTermsKey, &search_terms);
327 return search_terms; 308 return search_terms;
328 } 309 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 return l10n_util::GetStringUTF16(IDS_INSTANT_CHECKBOX_PREDICTION_DISABLED); 447 return l10n_util::GetStringUTF16(IDS_INSTANT_CHECKBOX_PREDICTION_DISABLED);
467 448
468 DCHECK(IsInstantCheckboxEnabled(profile)); 449 DCHECK(IsInstantCheckboxEnabled(profile));
469 return l10n_util::GetStringUTF16(IDS_INSTANT_CHECKBOX_ENABLED); 450 return l10n_util::GetStringUTF16(IDS_INSTANT_CHECKBOX_ENABLED);
470 } 451 }
471 452
472 GURL GetInstantURL(Profile* profile, int start_margin) { 453 GURL GetInstantURL(Profile* profile, int start_margin) {
473 if (!IsInstantCheckboxEnabled(profile)) 454 if (!IsInstantCheckboxEnabled(profile))
474 return GURL(); 455 return GURL();
475 456
457 // In non-extended mode, the checkbox must be checked.
476 const bool extended_api_enabled = IsInstantExtendedAPIEnabled(); 458 const bool extended_api_enabled = IsInstantExtendedAPIEnabled();
477
478 // In non-extended mode, the checkbox must be checked.
479 if (!extended_api_enabled && !IsInstantCheckboxChecked(profile)) 459 if (!extended_api_enabled && !IsInstantCheckboxChecked(profile))
480 return GURL(); 460 return GURL();
481 461
482 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); 462 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
483 CommandLine* cl = CommandLine::ForCurrentProcess(); 463 GURL instant_url =
484 if (cl->HasSwitch(switches::kInstantURL)) { 464 TemplateURLRefToGURL(template_url->instant_url_ref(), start_margin);
485 GURL instant_url(cl->GetSwitchValueASCII(switches::kInstantURL)); 465
486 if (extended_api_enabled) { 466 GURL::Replacements replacements;
487 // Extended mode won't work if the search terms replacement key is absent. 467
488 GURL coerced_url = CoerceCommandLineURLToTemplateURL( 468 // Extended mode requires HTTPS. Force it unless the base URL was overridden
489 instant_url, template_url->instant_url_ref(), start_margin); 469 // on the command line, in which case we allow HTTP (see comments on
490 if (!template_url->HasSearchTermsReplacementKey(coerced_url)) 470 // IsSuitableURLForInstant()).
491 return GURL(); 471 const std::string secure_scheme(chrome::kHttpsScheme);
492 } 472 if (extended_api_enabled && !instant_url.SchemeIsSecure() &&
493 return instant_url; 473 !google_util::StartsWithCommandLineGoogleBaseURL(instant_url))
474 replacements.SetSchemeStr(secure_scheme);
475
476 // If the user specified additional query params on the command line, add
477 // them.
478 std::string query_params(CommandLine::ForCurrentProcess()->
479 GetSwitchValueASCII(switches::kExtraSearchQueryParams));
480 if (!query_params.empty()) {
481 const std::string existing_query_params(instant_url.query());
482 if (!existing_query_params.empty())
483 query_params += "&" + existing_query_params;
484 replacements.SetQueryStr(query_params);
494 } 485 }
495 486
496 GURL instant_url = 487 return instant_url.ReplaceComponents(replacements);
497 TemplateURLRefToGURL(template_url->instant_url_ref(), start_margin);
498 if (extended_api_enabled && !instant_url.SchemeIsSecure()) {
499 // Extended mode requires HTTPS. Force it if necessary.
500 const std::string secure_scheme = chrome::kHttpsScheme;
501 GURL::Replacements replacements;
502 replacements.SetSchemeStr(secure_scheme);
503 instant_url = instant_url.ReplaceComponents(replacements);
504 }
505
506 return instant_url;
507 } 488 }
508 489
509 GURL GetLocalInstantURL(Profile* profile) { 490 GURL GetLocalInstantURL(Profile* profile) {
510 const TemplateURL* default_provider = 491 const TemplateURL* default_provider =
511 GetDefaultSearchProviderTemplateURL(profile); 492 GetDefaultSearchProviderTemplateURL(profile);
512 493
513 if (default_provider && 494 if (default_provider &&
514 (TemplateURLPrepopulateData::GetEngineType(default_provider->url()) == 495 (TemplateURLPrepopulateData::GetEngineType(default_provider->url()) ==
515 SEARCH_ENGINE_GOOGLE)) { 496 SEARCH_ENGINE_GOOGLE)) {
516 return GURL(chrome::kChromeSearchLocalGoogleNtpUrl); 497 return GURL(chrome::kChromeSearchLocalGoogleNtpUrl);
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 } 687 }
707 688
708 // Given a FieldTrialFlags object, returns the boolean value of the provided 689 // Given a FieldTrialFlags object, returns the boolean value of the provided
709 // flag. 690 // flag.
710 bool GetBoolValueForFlagWithDefault(const std::string& flag, 691 bool GetBoolValueForFlagWithDefault(const std::string& flag,
711 bool default_value, 692 bool default_value,
712 const FieldTrialFlags& flags) { 693 const FieldTrialFlags& flags) {
713 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); 694 return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags);
714 } 695 }
715 696
716 // Coerces the commandline Instant URL to look like a template URL, so that we
717 // can extract search terms from it.
718 GURL CoerceCommandLineURLToTemplateURL(const GURL& instant_url,
719 const TemplateURLRef& ref,
720 int start_margin) {
721 GURL search_url = TemplateURLRefToGURL(ref, start_margin);
722
723 // NOTE(samarth): GURL returns temporaries which we must save because
724 // GURL::Replacements expects the replacements to live until
725 // ReplaceComponents is called.
726 const std::string search_scheme = chrome::kHttpsScheme;
727 const std::string search_host = search_url.host();
728 const std::string search_port = search_url.port();
729
730 GURL::Replacements replacements;
731 replacements.SetSchemeStr(search_scheme);
732 replacements.SetHostStr(search_host);
733 replacements.SetPortStr(search_port);
734 return instant_url.ReplaceComponents(replacements);
735 }
736
737 bool DefaultSearchProviderSupportsInstant(Profile* profile) { 697 bool DefaultSearchProviderSupportsInstant(Profile* profile) {
738 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile); 698 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
739 if (!template_url) 699 if (!template_url)
740 return false; 700 return false;
741 701
742 GURL instant_url = TemplateURLRefToGURL(template_url->instant_url_ref(), 702 GURL instant_url = TemplateURLRefToGURL(template_url->instant_url_ref(),
743 kDisableStartMargin); 703 kDisableStartMargin);
744 // Extended mode instant requires a search terms replacement key. 704 // Extended mode instant requires a search terms replacement key.
745 return instant_url.is_valid() && 705 return instant_url.is_valid() &&
746 (!IsInstantExtendedAPIEnabled() || 706 (!IsInstantExtendedAPIEnabled() ||
(...skipping 13 matching lines...) Expand all
760 for (size_t i = 0; i < items_b.size(); ++i) { 720 for (size_t i = 0; i < items_b.size(); ++i) {
761 if (items_b[i].url != items_a[i].url || 721 if (items_b[i].url != items_a[i].url ||
762 items_b[i].title != items_a[i].title) { 722 items_b[i].title != items_a[i].title) {
763 return false; 723 return false;
764 } 724 }
765 } 725 }
766 return true; 726 return true;
767 } 727 }
768 728
769 } // namespace chrome 729 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698