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

Side by Side Diff: components/autocomplete/search_suggestion_parser.cc

Issue 423093013: Move DeserializeJsonData() and UTF-8 conversion code to SearchSuggestionParser (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clear image URLs Created 6 years, 4 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
« no previous file with comments | « components/autocomplete/search_suggestion_parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "components/autocomplete/search_suggestion_parser.h" 5 #include "components/autocomplete/search_suggestion_parser.h"
6 6
7 #include "base/i18n/icu_string_conversions.h"
7 #include "base/json/json_string_value_serializer.h" 8 #include "base/json/json_string_value_serializer.h"
8 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
9 #include "base/logging.h" 10 #include "base/logging.h"
10 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h" 13 #include "base/values.h"
13 #include "components/autocomplete/autocomplete_input.h" 14 #include "components/autocomplete/autocomplete_input.h"
14 #include "components/autocomplete/url_prefix.h" 15 #include "components/autocomplete/url_prefix.h"
15 #include "components/url_fixer/url_fixer.h" 16 #include "components/url_fixer/url_fixer.h"
16 #include "net/base/net_util.h" 17 #include "net/base/net_util.h"
18 #include "net/http/http_response_headers.h"
19 #include "net/url_request/url_fetcher.h"
17 20
18 namespace { 21 namespace {
19 22
20 AutocompleteMatchType::Type GetAutocompleteMatchType(const std::string& type) { 23 AutocompleteMatchType::Type GetAutocompleteMatchType(const std::string& type) {
21 if (type == "ENTITY") 24 if (type == "ENTITY")
22 return AutocompleteMatchType::SEARCH_SUGGEST_ENTITY; 25 return AutocompleteMatchType::SEARCH_SUGGEST_ENTITY;
23 if (type == "INFINITE") 26 if (type == "INFINITE")
24 return AutocompleteMatchType::SEARCH_SUGGEST_INFINITE; 27 return AutocompleteMatchType::SEARCH_SUGGEST_INFINITE;
25 if (type == "PERSONALIZED_QUERY") 28 if (type == "PERSONALIZED_QUERY")
26 return AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED; 29 return AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 int SearchSuggestionParser::NavigationResult::CalculateRelevance( 235 int SearchSuggestionParser::NavigationResult::CalculateRelevance(
233 const AutocompleteInput& input, 236 const AutocompleteInput& input,
234 bool keyword_provider_requested) const { 237 bool keyword_provider_requested) const {
235 return (from_keyword_provider_ || !keyword_provider_requested) ? 800 : 150; 238 return (from_keyword_provider_ || !keyword_provider_requested) ? 800 : 150;
236 } 239 }
237 240
238 // SearchSuggestionParser::Results --------------------------------------------- 241 // SearchSuggestionParser::Results ---------------------------------------------
239 242
240 SearchSuggestionParser::Results::Results() 243 SearchSuggestionParser::Results::Results()
241 : verbatim_relevance(-1), 244 : verbatim_relevance(-1),
242 field_trial_triggered(false) {} 245 field_trial_triggered(false),
246 relevances_from_server(false) {}
243 247
244 SearchSuggestionParser::Results::~Results() {} 248 SearchSuggestionParser::Results::~Results() {}
245 249
246 void SearchSuggestionParser::Results::Clear() { 250 void SearchSuggestionParser::Results::Clear() {
247 suggest_results.clear(); 251 suggest_results.clear();
248 navigation_results.clear(); 252 navigation_results.clear();
249 verbatim_relevance = -1; 253 verbatim_relevance = -1;
250 metadata.clear(); 254 metadata.clear();
251 } 255 }
252 256
(...skipping 14 matching lines...) Expand all
267 if (i->relevance_from_server()) 271 if (i->relevance_from_server())
268 return true; 272 return true;
269 } 273 }
270 274
271 return false; 275 return false;
272 } 276 }
273 277
274 // SearchSuggestionParser ------------------------------------------------------ 278 // SearchSuggestionParser ------------------------------------------------------
275 279
276 // static 280 // static
281 std::string SearchSuggestionParser::ExtractJsonData(
282 const net::URLFetcher* source) {
283 const net::HttpResponseHeaders* const response_headers =
284 source->GetResponseHeaders();
285 std::string json_data;
286 source->GetResponseAsString(&json_data);
287
288 // JSON is supposed to be UTF-8, but some suggest service providers send
289 // JSON files in non-UTF-8 encodings. The actual encoding is usually
290 // specified in the Content-Type header field.
291 if (response_headers) {
292 std::string charset;
293 if (response_headers->GetCharset(&charset)) {
294 base::string16 data_16;
295 // TODO(jungshik): Switch to CodePageToUTF8 after it's added.
296 if (base::CodepageToUTF16(json_data, charset.c_str(),
297 base::OnStringConversionError::FAIL,
298 &data_16))
299 json_data = base::UTF16ToUTF8(data_16);
300 }
301 }
302 return json_data;
303 }
304
305 // static
306 scoped_ptr<base::Value> SearchSuggestionParser::DeserializeJsonData(
307 std::string json_data) {
308 // The JSON response should be an array.
309 for (size_t response_start_index = json_data.find("["), i = 0;
310 response_start_index != std::string::npos && i < 5;
311 response_start_index = json_data.find("[", 1), i++) {
312 // Remove any XSSI guards to allow for JSON parsing.
313 if (response_start_index > 0)
314 json_data.erase(0, response_start_index);
315
316 JSONStringValueSerializer deserializer(json_data);
317 deserializer.set_allow_trailing_comma(true);
318 int error_code = 0;
319 scoped_ptr<base::Value> data(deserializer.Deserialize(&error_code, NULL));
320 if (error_code == 0)
321 return data.Pass();
322 }
323 return scoped_ptr<base::Value>();
324 }
325
326 // static
277 bool SearchSuggestionParser::ParseSuggestResults( 327 bool SearchSuggestionParser::ParseSuggestResults(
278 const base::Value& root_val, 328 const base::Value& root_val,
279 const AutocompleteInput& input, 329 const AutocompleteInput& input,
280 const AutocompleteSchemeClassifier& scheme_classifier, 330 const AutocompleteSchemeClassifier& scheme_classifier,
281 const ImagePrefetchCallback& image_prefetch_callback,
282 int default_result_relevance, 331 int default_result_relevance,
283 const std::string& languages, 332 const std::string& languages,
284 bool is_keyword_result, 333 bool is_keyword_result,
285 bool* relevances_from_server,
286 Results* results) { 334 Results* results) {
287 base::string16 query; 335 base::string16 query;
288 const base::ListValue* root_list = NULL; 336 const base::ListValue* root_list = NULL;
289 const base::ListValue* results_list = NULL; 337 const base::ListValue* results_list = NULL;
290 338
291 if (!root_val.GetAsList(&root_list) || !root_list->GetString(0, &query) || 339 if (!root_val.GetAsList(&root_list) || !root_list->GetString(0, &query) ||
292 query != input.text() || !root_list->GetList(1, &results_list)) 340 query != input.text() || !root_list->GetList(1, &results_list))
293 return false; 341 return false;
294 342
295 // 3rd element: Description list. 343 // 3rd element: Description list.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 381
334 // Store the metadata that came with the response in case we need to pass it 382 // Store the metadata that came with the response in case we need to pass it
335 // along with the prefetch query to Instant. 383 // along with the prefetch query to Instant.
336 JSONStringValueSerializer json_serializer(&results->metadata); 384 JSONStringValueSerializer json_serializer(&results->metadata);
337 json_serializer.Serialize(*extras); 385 json_serializer.Serialize(*extras);
338 } 386 }
339 387
340 // Clear the previous results now that new results are available. 388 // Clear the previous results now that new results are available.
341 results->suggest_results.clear(); 389 results->suggest_results.clear();
342 results->navigation_results.clear(); 390 results->navigation_results.clear();
391 results->answers_image_urls.clear();
343 392
344 base::string16 suggestion; 393 base::string16 suggestion;
345 std::string type; 394 std::string type;
346 int relevance = default_result_relevance; 395 int relevance = default_result_relevance;
347 // Prohibit navsuggest in FORCED_QUERY mode. Users wants queries, not URLs. 396 // Prohibit navsuggest in FORCED_QUERY mode. Users wants queries, not URLs.
348 const bool allow_navsuggest = 397 const bool allow_navsuggest =
349 input.type() != metrics::OmniboxInputType::FORCED_QUERY; 398 input.type() != metrics::OmniboxInputType::FORCED_QUERY;
350 const base::string16& trimmed_input = 399 const base::string16& trimmed_input =
351 base::CollapseWhitespace(input.text(), false); 400 base::CollapseWhitespace(input.text(), false);
352 for (size_t index = 0; results_list->GetString(index, &suggestion); ++index) { 401 for (size_t index = 0; results_list->GetString(index, &suggestion); ++index) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 // Error correction for bad data from server. 448 // Error correction for bad data from server.
400 if (match_contents.empty()) 449 if (match_contents.empty())
401 match_contents = suggestion; 450 match_contents = suggestion;
402 suggestion_detail->GetString("a", &annotation); 451 suggestion_detail->GetString("a", &annotation);
403 suggestion_detail->GetString("q", &suggest_query_params); 452 suggestion_detail->GetString("q", &suggest_query_params);
404 453
405 // Extract Answers, if provided. 454 // Extract Answers, if provided.
406 const base::DictionaryValue* answer_json = NULL; 455 const base::DictionaryValue* answer_json = NULL;
407 if (suggestion_detail->GetDictionary("ansa", &answer_json)) { 456 if (suggestion_detail->GetDictionary("ansa", &answer_json)) {
408 match_type = AutocompleteMatchType::SEARCH_SUGGEST_ANSWER; 457 match_type = AutocompleteMatchType::SEARCH_SUGGEST_ANSWER;
409 if (!image_prefetch_callback.is_null()) 458 GetAnswersImageURLs(answer_json, &results->answers_image_urls);
410 PrefetchAnswersImages(answer_json, image_prefetch_callback);
411 std::string contents; 459 std::string contents;
412 base::JSONWriter::Write(answer_json, &contents); 460 base::JSONWriter::Write(answer_json, &contents);
413 answer_contents = base::UTF8ToUTF16(contents); 461 answer_contents = base::UTF8ToUTF16(contents);
414 suggestion_detail->GetString("ansb", &answer_type); 462 suggestion_detail->GetString("ansb", &answer_type);
415 } 463 }
416 } 464 }
417 } 465 }
418 466
419 bool should_prefetch = static_cast<int>(index) == prefetch_index; 467 bool should_prefetch = static_cast<int>(index) == prefetch_index;
420 // TODO(kochi): Improve calculator suggestion presentation. 468 // TODO(kochi): Improve calculator suggestion presentation.
421 results->suggest_results.push_back(SuggestResult( 469 results->suggest_results.push_back(SuggestResult(
422 base::CollapseWhitespace(suggestion, false), match_type, 470 base::CollapseWhitespace(suggestion, false), match_type,
423 base::CollapseWhitespace(match_contents, false), 471 base::CollapseWhitespace(match_contents, false),
424 match_contents_prefix, annotation, answer_contents, answer_type, 472 match_contents_prefix, annotation, answer_contents, answer_type,
425 suggest_query_params, deletion_url, is_keyword_result, relevance, 473 suggest_query_params, deletion_url, is_keyword_result, relevance,
426 relevances != NULL, should_prefetch, trimmed_input)); 474 relevances != NULL, should_prefetch, trimmed_input));
427 } 475 }
428 } 476 }
429 *relevances_from_server = relevances != NULL; 477 results->relevances_from_server = relevances != NULL;
430 return true; 478 return true;
431 } 479 }
432 480
433 // static 481 // static
434 void SearchSuggestionParser::PrefetchAnswersImages( 482 void SearchSuggestionParser::GetAnswersImageURLs(
435 const base::DictionaryValue* answer_json, 483 const base::DictionaryValue* answer_json,
436 const ImagePrefetchCallback& image_prefetch_callback) { 484 std::vector<GURL>* urls) {
437 DCHECK(answer_json); 485 DCHECK(answer_json);
438 DCHECK(!image_prefetch_callback.is_null());
439 const base::ListValue* lines = NULL; 486 const base::ListValue* lines = NULL;
440 answer_json->GetList("l", &lines); 487 answer_json->GetList("l", &lines);
441 if (!lines || lines->GetSize() == 0) 488 if (!lines || lines->GetSize() == 0)
442 return; 489 return;
443 490
444 for (size_t line = 0; line < lines->GetSize(); ++line) { 491 for (size_t line = 0; line < lines->GetSize(); ++line) {
445 const base::DictionaryValue* imageLine = NULL; 492 const base::DictionaryValue* imageLine = NULL;
446 lines->GetDictionary(line, &imageLine); 493 lines->GetDictionary(line, &imageLine);
447 if (!imageLine) 494 if (!imageLine)
448 continue; 495 continue;
449 const base::DictionaryValue* imageData = NULL; 496 const base::DictionaryValue* imageData = NULL;
450 imageLine->GetDictionary("i", &imageData); 497 imageLine->GetDictionary("i", &imageData);
451 if (!imageData) 498 if (!imageData)
452 continue; 499 continue;
453 std::string imageUrl; 500 std::string imageUrl;
454 imageData->GetString("d", &imageUrl); 501 imageData->GetString("d", &imageUrl);
455 image_prefetch_callback.Run(GURL(imageUrl)); 502 urls->push_back(GURL(imageUrl));
456 } 503 }
457 } 504 }
OLDNEW
« no previous file with comments | « components/autocomplete/search_suggestion_parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698