Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/autocomplete/search_provider.h" | 5 #include "chrome/browser/autocomplete/search_provider.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 | 593 |
| 594 if (clear_cached_results) | 594 if (clear_cached_results) |
| 595 ClearAllResults(); | 595 ClearAllResults(); |
| 596 } | 596 } |
| 597 | 597 |
| 598 void SearchProvider::OnURLFetchComplete(const net::URLFetcher* source) { | 598 void SearchProvider::OnURLFetchComplete(const net::URLFetcher* source) { |
| 599 DCHECK(!done_); | 599 DCHECK(!done_); |
| 600 suggest_results_pending_--; | 600 suggest_results_pending_--; |
| 601 LogOmniboxSuggestRequest(REPLY_RECEIVED); | 601 LogOmniboxSuggestRequest(REPLY_RECEIVED); |
| 602 DCHECK_GE(suggest_results_pending_, 0); // Should never go negative. | 602 DCHECK_GE(suggest_results_pending_, 0); // Should never go negative. |
| 603 const net::HttpResponseHeaders* const response_headers = | |
| 604 source->GetResponseHeaders(); | |
| 605 std::string json_data; | |
| 606 source->GetResponseAsString(&json_data); | |
| 607 // JSON is supposed to be UTF-8, but some suggest service providers send JSON | |
| 608 // files in non-UTF-8 encodings. The actual encoding is usually specified in | |
| 609 // the Content-Type header field. | |
| 610 if (response_headers) { | |
| 611 std::string charset; | |
| 612 if (response_headers->GetCharset(&charset)) { | |
| 613 string16 data_16; | |
| 614 // TODO(jungshik): Switch to CodePageToUTF8 after it's added. | |
| 615 if (base::CodepageToUTF16(json_data, charset.c_str(), | |
| 616 base::OnStringConversionError::FAIL, | |
| 617 &data_16)) | |
| 618 json_data = UTF16ToUTF8(data_16); | |
| 619 } | |
| 620 } | |
| 621 | 603 |
| 622 const bool is_keyword = (source == keyword_fetcher_.get()); | 604 const bool is_keyword = (source == keyword_fetcher_.get()); |
| 623 // Ensure the request succeeded and that the provider used is still available. | 605 // Ensure the request succeeded and that the provider used is still available. |
| 624 // A verbatim match cannot be generated without this provider, causing errors. | 606 // A verbatim match cannot be generated without this provider, causing errors. |
| 625 const bool request_succeeded = | 607 const bool request_succeeded = |
| 626 source->GetStatus().is_success() && (source->GetResponseCode() == 200) && | 608 source->GetStatus().is_success() && (source->GetResponseCode() == 200) && |
| 627 (is_keyword ? | 609 (is_keyword ? |
| 628 providers_.GetKeywordProviderURL() : | 610 providers_.GetKeywordProviderURL() : |
| 629 providers_.GetDefaultProviderURL()); | 611 providers_.GetDefaultProviderURL()); |
| 630 | 612 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 641 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Success.GoogleResponseTime", | 623 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Success.GoogleResponseTime", |
| 642 elapsed_time); | 624 elapsed_time); |
| 643 } else { | 625 } else { |
| 644 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Failure.GoogleResponseTime", | 626 UMA_HISTOGRAM_TIMES("Omnibox.SuggestRequest.Failure.GoogleResponseTime", |
| 645 elapsed_time); | 627 elapsed_time); |
| 646 } | 628 } |
| 647 } | 629 } |
| 648 | 630 |
| 649 bool results_updated = false; | 631 bool results_updated = false; |
| 650 if (request_succeeded) { | 632 if (request_succeeded) { |
| 651 JSONStringValueSerializer deserializer(json_data); | 633 const net::HttpResponseHeaders* const response_headers = |
| 652 deserializer.set_allow_trailing_comma(true); | 634 source->GetResponseHeaders(); |
| 653 scoped_ptr<Value> data(deserializer.Deserialize(NULL, NULL)); | 635 std::string json_data; |
| 654 results_updated = data.get() && ParseSuggestResults(data.get(), is_keyword); | 636 source->GetResponseAsString(&json_data); |
| 637 // JSON is supposed to be UTF-8, but some suggest service providers send | |
| 638 // JSON files in non-UTF-8 encodings. The actual encoding is usually | |
| 639 // specified in the Content-Type header field. | |
| 640 if (response_headers) { | |
| 641 std::string charset; | |
| 642 if (response_headers->GetCharset(&charset)) { | |
| 643 string16 data_16; | |
| 644 // TODO(jungshik): Switch to CodePageToUTF8 after it's added. | |
| 645 if (base::CodepageToUTF16(json_data, charset.c_str(), | |
| 646 base::OnStringConversionError::FAIL, | |
| 647 &data_16)) | |
| 648 json_data = UTF16ToUTF8(data_16); | |
| 649 } | |
| 650 } | |
| 651 | |
| 652 int error_code = 0; | |
| 653 while (true) { | |
|
Peter Kasting
2013/10/29 18:45:49
This can infinite loop.
If we find the first '[',
Maria
2013/10/29 18:55:45
I don't think it's likely that XSSI guard would ch
Anuj
2013/10/29 18:58:05
Please see the test cases - Hypothetically XSSI gu
Anuj
2013/10/29 19:03:35
XSSI guard may not change. But looking for respons
| |
| 654 // The JSON response should be an array. | |
| 655 size_t response_start_index = json_data.find("["); | |
| 656 | |
| 657 if (response_start_index == std::string::npos) | |
| 658 break; | |
| 659 | |
| 660 // Remove any XSSI guards to allow for JSON parsing. | |
| 661 if (response_start_index > 0) | |
| 662 json_data.erase(0, response_start_index - 1); | |
| 663 | |
| 664 JSONStringValueSerializer deserializer(json_data); | |
| 665 deserializer.set_allow_trailing_comma(true); | |
| 666 scoped_ptr<Value> data(deserializer.Deserialize(&error_code, NULL)); | |
| 667 if (error_code == 0) { | |
| 668 results_updated = data.get() && | |
| 669 ParseSuggestResults(data.get(), is_keyword); | |
| 670 break; | |
| 671 } | |
| 672 } | |
| 655 } | 673 } |
| 656 | 674 |
| 657 UpdateMatches(); | 675 UpdateMatches(); |
| 658 if (done_ || results_updated) | 676 if (done_ || results_updated) |
| 659 listener_->OnProviderUpdate(results_updated); | 677 listener_->OnProviderUpdate(results_updated); |
| 660 } | 678 } |
| 661 | 679 |
| 662 void SearchProvider::Run() { | 680 void SearchProvider::Run() { |
| 663 // Start a new request with the current input. | 681 // Start a new request with the current input. |
| 664 suggest_results_pending_ = 0; | 682 suggest_results_pending_ = 0; |
| (...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1763 it->set_relevance(max_query_relevance); | 1781 it->set_relevance(max_query_relevance); |
| 1764 it->set_relevance_from_server(relevance_from_server); | 1782 it->set_relevance_from_server(relevance_from_server); |
| 1765 } | 1783 } |
| 1766 } | 1784 } |
| 1767 | 1785 |
| 1768 void SearchProvider::UpdateDone() { | 1786 void SearchProvider::UpdateDone() { |
| 1769 // We're done when the timer isn't running, there are no suggest queries | 1787 // We're done when the timer isn't running, there are no suggest queries |
| 1770 // pending, and we're not waiting on Instant. | 1788 // pending, and we're not waiting on Instant. |
| 1771 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0); | 1789 done_ = !timer_.IsRunning() && (suggest_results_pending_ == 0); |
| 1772 } | 1790 } |
| OLD | NEW |