diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 20:25:53 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 20:25:53 +0000 |
commit | 56fa29593af8afdbd286100f8e7e36acc96de8a8 (patch) | |
tree | 1289161c33b1a9c9450453fcb3d9fbdcad8c5c33 /chrome/browser/search_engines | |
parent | 918104f95eff808cba4c4a4386866fc87efc27c6 (diff) | |
download | chromium_src-56fa29593af8afdbd286100f8e7e36acc96de8a8.zip chromium_src-56fa29593af8afdbd286100f8e7e36acc96de8a8.tar.gz chromium_src-56fa29593af8afdbd286100f8e7e36acc96de8a8.tar.bz2 |
Add --extra-search-query-params, which allows testers to pass additional query
params in the search and instant URLs of the default search provider.
BUG=254670
TEST=Run chrome with --extra-search-query-params="a=b&c=d" and note that omnibox search URLs now contain these flags (use about:omnibox to check this)
R=michaelbai@chromium.org, samarth@chromium.org, yfriedman@chromium.org
Review URL: https://codereview.chromium.org/18377002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209765 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/search_engines')
-rw-r--r-- | chrome/browser/search_engines/template_url.cc | 335 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url.h | 18 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_service.cc | 7 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_unittest.cc | 37 | ||||
-rw-r--r-- | chrome/browser/search_engines/util.cc | 1 |
5 files changed, 242 insertions, 156 deletions
diff --git a/chrome/browser/search_engines/template_url.cc b/chrome/browser/search_engines/template_url.cc index 535bb28..1ccf6dc 100644 --- a/chrome/browser/search_engines/template_url.cc +++ b/chrome/browser/search_engines/template_url.cc @@ -4,6 +4,7 @@ #include "chrome/browser/search_engines/template_url.h" +#include "base/command_line.h" #include "base/format_macros.h" #include "base/guid.h" #include "base/i18n/case_conversion.h" @@ -18,6 +19,7 @@ #include "chrome/browser/google/google_util.h" #include "chrome/browser/search_engines/search_terms_data.h" #include "chrome/browser/search_engines/template_url_service.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "extensions/common/constants.h" #include "google_apis/google_api_keys.h" @@ -155,7 +157,8 @@ TemplateURLRef::SearchTermsArgs::SearchTermsArgs(const string16& search_terms) : search_terms(search_terms), accepted_suggestion(NO_SUGGESTIONS_AVAILABLE), cursor_position(string16::npos), - omnibox_start_margin(-1) { + omnibox_start_margin(-1), + append_extra_query_params(false) { } TemplateURLRef::SearchTermsArgs::~SearchTermsArgs() { @@ -227,159 +230,21 @@ std::string TemplateURLRef::ReplaceSearchTermsUsingTermsData( if (!valid_) return std::string(); - if (replacements_.empty()) - return parsed_url_; - - // Determine if the search terms are in the query or before. We're escaping - // space as '+' in the former case and as '%20' in the latter case. - bool is_in_query = true; - for (Replacements::iterator i = replacements_.begin(); - i != replacements_.end(); ++i) { - if (i->type == SEARCH_TERMS) { - string16::size_type query_start = parsed_url_.find('?'); - is_in_query = query_start != string16::npos && - (static_cast<string16::size_type>(i->index) > query_start); - break; - } - } - - std::string input_encoding; - string16 encoded_terms; - string16 encoded_original_query; - owner_->EncodeSearchTerms(search_terms_args, is_in_query, &input_encoding, - &encoded_terms, &encoded_original_query); - - std::string url = parsed_url_; - - // replacements_ is ordered in ascending order, as such we need to iterate - // from the back. - for (Replacements::reverse_iterator i = replacements_.rbegin(); - i != replacements_.rend(); ++i) { - switch (i->type) { - case ENCODING: - url.insert(i->index, input_encoding); - break; - - case GOOGLE_ASSISTED_QUERY_STATS: - if (!search_terms_args.assisted_query_stats.empty()) { - // Get the base URL without substituting AQS to avoid infinite - // recursion. We need the URL to find out if it meets all - // AQS requirements (e.g. HTTPS protocol check). - // See TemplateURLRef::SearchTermsArgs for more details. - SearchTermsArgs search_terms_args_without_aqs(search_terms_args); - search_terms_args_without_aqs.assisted_query_stats.clear(); - GURL base_url(ReplaceSearchTermsUsingTermsData( - search_terms_args_without_aqs, search_terms_data)); - if (base_url.SchemeIs(chrome::kHttpsScheme)) { - url.insert(i->index, - "aqs=" + search_terms_args.assisted_query_stats + "&"); - } - } - break; - - case GOOGLE_BASE_URL: - url.insert(i->index, search_terms_data.GoogleBaseURLValue()); - break; - - case GOOGLE_BASE_SUGGEST_URL: - url.insert(i->index, search_terms_data.GoogleBaseSuggestURLValue()); - break; - - case GOOGLE_CURSOR_POSITION: - if (search_terms_args.cursor_position != string16::npos) - url.insert(i->index, - base::StringPrintf("cp=%" PRIuS "&", - search_terms_args.cursor_position)); - break; - - case GOOGLE_INSTANT_ENABLED: - url.insert(i->index, search_terms_data.InstantEnabledParam()); - break; - - case GOOGLE_INSTANT_EXTENDED_ENABLED: - url.insert(i->index, search_terms_data.InstantExtendedEnabledParam()); - break; - - case GOOGLE_NTP_IS_THEMED: - url.insert(i->index, search_terms_data.NTPIsThemedParam()); - break; - - case GOOGLE_OMNIBOX_START_MARGIN: - if (search_terms_args.omnibox_start_margin >= 0) { - url.insert(i->index, "es_sm=" + - base::IntToString(search_terms_args.omnibox_start_margin) + "&"); - } - break; - - case GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION: - if (search_terms_args.accepted_suggestion >= 0 || - !search_terms_args.assisted_query_stats.empty()) { - url.insert(i->index, "oq=" + UTF16ToUTF8(encoded_original_query) + - "&"); - } - break; - - case GOOGLE_RLZ: { - // On platforms that don't have RLZ, we still want this branch - // to happen so that we replace the RLZ template with the - // empty string. (If we don't handle this case, we hit a - // NOTREACHED below.) - string16 rlz_string = search_terms_data.GetRlzParameterValue(); - if (!rlz_string.empty()) { - url.insert(i->index, "rlz=" + UTF16ToUTF8(rlz_string) + "&"); - } - break; - } - - case GOOGLE_SEARCH_CLIENT: { - std::string client = search_terms_data.GetSearchClient(); - if (!client.empty()) - url.insert(i->index, "client=" + client + "&"); - break; - } - - case GOOGLE_SEARCH_FIELDTRIAL_GROUP: - // We are not currently running any fieldtrials that modulate the search - // url. If we do, then we'd have some conditional insert such as: - // url.insert(i->index, used_www ? "gcx=w&" : "gcx=c&"); - break; - - case GOOGLE_SUGGEST_CLIENT: - url.insert(i->index, search_terms_data.GetSuggestClient()); - break; - - case GOOGLE_UNESCAPED_SEARCH_TERMS: { - std::string unescaped_terms; - base::UTF16ToCodepage(search_terms_args.search_terms, - input_encoding.c_str(), - base::OnStringConversionError::SKIP, - &unescaped_terms); - url.insert(i->index, std::string(unescaped_terms.begin(), - unescaped_terms.end())); - break; - } - - case GOOGLE_ZERO_PREFIX_URL: - if (!search_terms_args.zero_prefix_url.empty()) { - const std::string& escaped_zero_prefix_url = - net::EscapeQueryParamValue(search_terms_args.zero_prefix_url, - true); - url.insert(i->index, "url=" + escaped_zero_prefix_url + "&"); - } - - break; - - case LANGUAGE: - url.insert(i->index, search_terms_data.GetApplicationLocale()); - break; - - case SEARCH_TERMS: - url.insert(i->index, UTF16ToUTF8(encoded_terms)); - break; - - default: - NOTREACHED(); - break; + std::string url(HandleReplacements(search_terms_args, search_terms_data)); + + // If the user specified additional query params on the command line, add + // them. + if (search_terms_args.append_extra_query_params) { + std::string query_params(CommandLine::ForCurrentProcess()-> + GetSwitchValueASCII(switches::kExtraSearchQueryParams)); + GURL gurl(url); + if (!query_params.empty() && gurl.is_valid()) { + GURL::Replacements replacements; + const std::string existing_query_params(gurl.query()); + if (!existing_query_params.empty()) + query_params += "&" + existing_query_params; + replacements.SetQueryStr(query_params); + return gurl.ReplaceComponents(replacements).possibly_invalid_spec(); } } @@ -733,6 +598,168 @@ void TemplateURLRef::ParseHostAndSearchTermKey( path_ = url.path(); } +std::string TemplateURLRef::HandleReplacements( + const SearchTermsArgs& search_terms_args, + const SearchTermsData& search_terms_data) const { + if (replacements_.empty()) + return parsed_url_; + + // Determine if the search terms are in the query or before. We're escaping + // space as '+' in the former case and as '%20' in the latter case. + bool is_in_query = true; + for (Replacements::iterator i = replacements_.begin(); + i != replacements_.end(); ++i) { + if (i->type == SEARCH_TERMS) { + string16::size_type query_start = parsed_url_.find('?'); + is_in_query = query_start != string16::npos && + (static_cast<string16::size_type>(i->index) > query_start); + break; + } + } + + std::string input_encoding; + string16 encoded_terms; + string16 encoded_original_query; + owner_->EncodeSearchTerms(search_terms_args, is_in_query, &input_encoding, + &encoded_terms, &encoded_original_query); + + std::string url = parsed_url_; + + // replacements_ is ordered in ascending order, as such we need to iterate + // from the back. + for (Replacements::reverse_iterator i = replacements_.rbegin(); + i != replacements_.rend(); ++i) { + switch (i->type) { + case ENCODING: + url.insert(i->index, input_encoding); + break; + + case GOOGLE_ASSISTED_QUERY_STATS: + if (!search_terms_args.assisted_query_stats.empty()) { + // Get the base URL without substituting AQS to avoid infinite + // recursion. We need the URL to find out if it meets all + // AQS requirements (e.g. HTTPS protocol check). + // See TemplateURLRef::SearchTermsArgs for more details. + SearchTermsArgs search_terms_args_without_aqs(search_terms_args); + search_terms_args_without_aqs.assisted_query_stats.clear(); + GURL base_url(ReplaceSearchTermsUsingTermsData( + search_terms_args_without_aqs, search_terms_data)); + if (base_url.SchemeIs(chrome::kHttpsScheme)) { + url.insert(i->index, + "aqs=" + search_terms_args.assisted_query_stats + "&"); + } + } + break; + + case GOOGLE_BASE_URL: + url.insert(i->index, search_terms_data.GoogleBaseURLValue()); + break; + + case GOOGLE_BASE_SUGGEST_URL: + url.insert(i->index, search_terms_data.GoogleBaseSuggestURLValue()); + break; + + case GOOGLE_CURSOR_POSITION: + if (search_terms_args.cursor_position != string16::npos) + url.insert(i->index, + base::StringPrintf("cp=%" PRIuS "&", + search_terms_args.cursor_position)); + break; + + case GOOGLE_INSTANT_ENABLED: + url.insert(i->index, search_terms_data.InstantEnabledParam()); + break; + + case GOOGLE_INSTANT_EXTENDED_ENABLED: + url.insert(i->index, search_terms_data.InstantExtendedEnabledParam()); + break; + + case GOOGLE_NTP_IS_THEMED: + url.insert(i->index, search_terms_data.NTPIsThemedParam()); + break; + + case GOOGLE_OMNIBOX_START_MARGIN: + if (search_terms_args.omnibox_start_margin >= 0) { + url.insert(i->index, "es_sm=" + + base::IntToString(search_terms_args.omnibox_start_margin) + "&"); + } + break; + + case GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION: + if (search_terms_args.accepted_suggestion >= 0 || + !search_terms_args.assisted_query_stats.empty()) { + url.insert(i->index, "oq=" + UTF16ToUTF8(encoded_original_query) + + "&"); + } + break; + + case GOOGLE_RLZ: { + // On platforms that don't have RLZ, we still want this branch + // to happen so that we replace the RLZ template with the + // empty string. (If we don't handle this case, we hit a + // NOTREACHED below.) + string16 rlz_string = search_terms_data.GetRlzParameterValue(); + if (!rlz_string.empty()) { + url.insert(i->index, "rlz=" + UTF16ToUTF8(rlz_string) + "&"); + } + break; + } + + case GOOGLE_SEARCH_CLIENT: { + std::string client = search_terms_data.GetSearchClient(); + if (!client.empty()) + url.insert(i->index, "client=" + client + "&"); + break; + } + + case GOOGLE_SEARCH_FIELDTRIAL_GROUP: + // We are not currently running any fieldtrials that modulate the search + // url. If we do, then we'd have some conditional insert such as: + // url.insert(i->index, used_www ? "gcx=w&" : "gcx=c&"); + break; + + case GOOGLE_SUGGEST_CLIENT: + url.insert(i->index, search_terms_data.GetSuggestClient()); + break; + + case GOOGLE_UNESCAPED_SEARCH_TERMS: { + std::string unescaped_terms; + base::UTF16ToCodepage(search_terms_args.search_terms, + input_encoding.c_str(), + base::OnStringConversionError::SKIP, + &unescaped_terms); + url.insert(i->index, std::string(unescaped_terms.begin(), + unescaped_terms.end())); + break; + } + + case GOOGLE_ZERO_PREFIX_URL: + if (!search_terms_args.zero_prefix_url.empty()) { + const std::string& escaped_zero_prefix_url = + net::EscapeQueryParamValue(search_terms_args.zero_prefix_url, + true); + url.insert(i->index, "url=" + escaped_zero_prefix_url + "&"); + } + + break; + + case LANGUAGE: + url.insert(i->index, search_terms_data.GetApplicationLocale()); + break; + + case SEARCH_TERMS: + url.insert(i->index, UTF16ToUTF8(encoded_terms)); + break; + + default: + NOTREACHED(); + break; + } + } + + return url; +} + // TemplateURLData ------------------------------------------------------------ diff --git a/chrome/browser/search_engines/template_url.h b/chrome/browser/search_engines/template_url.h index f81876a..3eb9f4d 100644 --- a/chrome/browser/search_engines/template_url.h +++ b/chrome/browser/search_engines/template_url.h @@ -58,7 +58,7 @@ class TemplateURLRef { ~SearchTermsArgs(); // The search terms (query). - const string16 search_terms; + string16 search_terms; // The original (input) query. string16 original_query; @@ -85,6 +85,15 @@ class TemplateURLRef { // The URL of the current webpage to be used for experimental zero-prefix // suggestions. std::string zero_prefix_url; + + // If set, ReplaceSearchTerms() will automatically append any extra query + // params specified via the --extra-search-query-params command-line + // argument. Generally, this should be set when dealing with the search or + // instant TemplateURLRefs of the default search engine and the caller cares + // about the query portion of the URL. Since neither TemplateURLRef nor + // indeed TemplateURL know whether a TemplateURL is the default search + // engine, callers instead must set this manually. + bool append_extra_query_params; }; TemplateURLRef(TemplateURL* owner, Type type); @@ -246,6 +255,13 @@ class TemplateURLRef { void ParseHostAndSearchTermKey( const SearchTermsData& search_terms_data) const; + // Replaces all replacements in |parsed_url_| with their actual values and + // returns the result. This is the main functionality of + // ReplaceSearchTermsUsingTermsData(). + std::string HandleReplacements( + const SearchTermsArgs& search_terms_args, + const SearchTermsData& search_terms_data) const; + // The TemplateURL that contains us. This should outlive us. TemplateURL* const owner_; diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc index 813f488..bde41b0 100644 --- a/chrome/browser/search_engines/template_url_service.cc +++ b/chrome/browser/search_engines/template_url_service.cc @@ -1391,7 +1391,12 @@ void TemplateURLService::Init(const Initializer* initializers, data.short_name = UTF8ToUTF16(initializers[i].content); data.SetKeyword(UTF8ToUTF16(initializers[i].keyword)); data.SetURL(osd_url); - AddNoNotify(new TemplateURL(profile_, data), true); + TemplateURL* template_url = new TemplateURL(profile_, data); + AddNoNotify(template_url, true); + + // Set the first provided identifier to be the default. + if (i == 0) + SetDefaultSearchProviderNoNotify(template_url); } } diff --git a/chrome/browser/search_engines/template_url_unittest.cc b/chrome/browser/search_engines/template_url_unittest.cc index cffbb59..2f8b6c4 100644 --- a/chrome/browser/search_engines/template_url_unittest.cc +++ b/chrome/browser/search_engines/template_url_unittest.cc @@ -3,12 +3,14 @@ // found in the LICENSE file. #include "base/base_paths.h" +#include "base/command_line.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/rlz/rlz.h" #include "chrome/browser/search_engines/search_terms_data.h" #include "chrome/browser/search_engines/template_url.h" +#include "chrome/common/chrome_switches.h" #include "testing/gtest/include/gtest/gtest.h" #if defined(ENABLE_RLZ) @@ -1032,3 +1034,38 @@ TEST_F(TemplateURLTest, ReplaceSearchTermsInURL) { GURL("http://google.com/alt/?q=#q=123"), search_terms, &result)); EXPECT_EQ(GURL("http://google.com/alt/?q=#q=Bob Morane"), result); } + +// Test the |append_extra_query_params| field of SearchTermsArgs. +TEST_F(TemplateURLTest, ExtraQueryParams) { + UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/"); + TemplateURLData data; + // Pick a URL with replacements before, during, and after the query, to ensure + // we don't goof up any of them. + data.SetURL("{google:baseURL}search?q={searchTerms}" + "#{google:originalQueryForSuggestion}x"); + TemplateURL url(NULL, data); + + // Baseline: no command-line args, no |append_extra_query_params| flag. + TemplateURLRef::SearchTermsArgs search_terms(ASCIIToUTF16("abc")); + search_terms.original_query = ASCIIToUTF16("def"); + search_terms.accepted_suggestion = 0; + EXPECT_EQ("http://www.google.com/search?q=abc#oq=def&x", + url.url_ref().ReplaceSearchTerms(search_terms)); + + // Set the flag. Since there are no command-line args, this should have no + // effect. + search_terms.append_extra_query_params = true; + EXPECT_EQ("http://www.google.com/search?q=abc#oq=def&x", + url.url_ref().ReplaceSearchTerms(search_terms)); + + // Now append the command-line arg. This should be inserted into the query. + CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kExtraSearchQueryParams, "a=b"); + EXPECT_EQ("http://www.google.com/search?a=b&q=abc#oq=def&x", + url.url_ref().ReplaceSearchTerms(search_terms)); + + // Turn off the flag. Now the command-line arg should be ignored again. + search_terms.append_extra_query_params = false; + EXPECT_EQ("http://www.google.com/search?q=abc#oq=def&x", + url.url_ref().ReplaceSearchTerms(search_terms)); +} diff --git a/chrome/browser/search_engines/util.cc b/chrome/browser/search_engines/util.cc index fbef1cc..6aa478e 100644 --- a/chrome/browser/search_engines/util.cc +++ b/chrome/browser/search_engines/util.cc @@ -50,6 +50,7 @@ GURL GetDefaultSearchURLForSearchTerms(Profile* profile, const TemplateURLRef& search_url = default_provider->url_ref(); DCHECK(search_url.SupportsReplacement()); TemplateURLRef::SearchTermsArgs search_terms_args(terms); + search_terms_args.append_extra_query_params = true; return GURL(search_url.ReplaceSearchTerms(search_terms_args)); } |