1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_download.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ostream> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_download_url.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_metrics.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_xml_parser.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/form_structure.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "components/autofill/core/common/autofill_pref_names.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/user_prefs.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_context.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/libjingle/source/talk/xmllite/xmlparser.h" 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserContext; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace autofill { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAutofillQueryServerNameStartInHeader[] = "GFE/"; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kMaxFormCacheSize = 16; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Generate field assignments xml that can be manually changed and then fed back 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// into the Autofill server as experiment data. 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void LogFieldAssignments( 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FormStructure& form, 423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const ServerFieldTypeSet& available_field_types) { 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string form_xml; 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!form.EncodeFieldAssignments(available_field_types, &form_xml)) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << "AutofillDownloadManager FieldAssignments for " 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << form.source_url() 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " :\n" 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << form_xml; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string AutofillDownloadManager::AutofillRequestTypeToString( 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AutofillRequestType type) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case AutofillDownloadManager::REQUEST_QUERY: 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "query"; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case AutofillDownloadManager::REQUEST_UPLOAD: 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "upload"; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::string(); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AutofillDownloadManager::FormRequestData { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> form_signatures; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutofillRequestType request_type; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutofillDownloadManager::AutofillDownloadManager(BrowserContext* context, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Observer* observer) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : browser_context_(context), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_(observer), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_form_cache_size_(kMaxFormCacheSize), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_query_request_(base::Time::Now()), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_upload_request_(base::Time::Now()), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) positive_upload_rate_(0), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) negative_upload_rate_(0), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_id_for_unittest_(0) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(observer_); 835e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) PrefService* preferences = user_prefs::UserPrefs::Get(browser_context_); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) positive_upload_rate_ = 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preferences->GetDouble(prefs::kAutofillPositiveUploadRate); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) negative_upload_rate_ = 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preferences->GetDouble(prefs::kAutofillNegativeUploadRate); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutofillDownloadManager::~AutofillDownloadManager() { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPairFirstPointers(url_fetchers_.begin(), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_fetchers_.end()); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutofillDownloadManager::StartQueryRequest( 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<FormStructure*>& forms, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AutofillMetrics& metric_logger) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_query_request_ > base::Time::Now()) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are in back-off mode: do not do the request. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string form_xml; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormRequestData request_data; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &form_xml)) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_data.request_type = AutofillDownloadManager::REQUEST_QUERY; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_SENT); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string query_data; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CheckCacheForQueryRequest(request_data.form_signatures, &query_data)) { 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "AutofillDownloadManager: query request has been retrieved " 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << "from the cache, form signatures: " 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << GetCombinedSignature(request_data.form_signatures); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnLoadedServerPredictions(query_data); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StartRequest(form_xml, request_data); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutofillDownloadManager::StartUploadRequest( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FormStructure& form, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool form_was_autofilled, 1273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const ServerFieldTypeSet& available_field_types) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string form_xml; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!form.EncodeUploadRequest(available_field_types, form_was_autofilled, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &form_xml)) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LogFieldAssignments(form, available_field_types); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_upload_request_ > base::Time::Now()) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are in back-off mode: do not do the request. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "AutofillDownloadManager: Upload request is throttled."; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flip a coin to see if we should upload this form. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double upload_rate = form_was_autofilled ? GetPositiveUploadRate() : 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetNegativeUploadRate(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (form.upload_required() == UPLOAD_NOT_REQUIRED || 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (form.upload_required() == USE_UPLOAD_RATES && 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RandDouble() > upload_rate)) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "AutofillDownloadManager: Upload request is ignored."; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we ever need notification that upload was skipped, add it here. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormRequestData request_data; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_data.form_signatures.push_back(form.FormSignature()); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_data.request_type = AutofillDownloadManager::REQUEST_UPLOAD; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StartRequest(form_xml, request_data); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double AutofillDownloadManager::GetPositiveUploadRate() const { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return positive_upload_rate_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double AutofillDownloadManager::GetNegativeUploadRate() const { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return negative_upload_rate_; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillDownloadManager::SetPositiveUploadRate(double rate) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rate == positive_upload_rate_) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) positive_upload_rate_ = rate; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(rate, 0.0); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(rate, 1.0); 1735e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) PrefService* preferences = user_prefs::UserPrefs::Get(browser_context_); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preferences->SetDouble(prefs::kAutofillPositiveUploadRate, rate); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillDownloadManager::SetNegativeUploadRate(double rate) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rate == negative_upload_rate_) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) negative_upload_rate_ = rate; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(rate, 0.0); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(rate, 1.0); 1835e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) PrefService* preferences = user_prefs::UserPrefs::Get(browser_context_); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preferences->SetDouble(prefs::kAutofillNegativeUploadRate, rate); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutofillDownloadManager::StartRequest( 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& form_xml, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FormRequestData& request_data) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* request_context = 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_context_->GetRequestContext(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_context); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL request_url; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_data.request_type == AutofillDownloadManager::REQUEST_QUERY) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_url = autofill::GetAutofillQueryUrl(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_url = autofill::GetAutofillUploadUrl(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Id is ignored for regular chrome, in unit test id's for fake fetcher 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // factory will be 0, 1, 2, ... 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLFetcher* fetcher = net::URLFetcher::Create( 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_id_for_unittest_++, request_url, net::URLFetcher::POST, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_fetchers_[fetcher] = request_data; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->SetAutomaticallyRetryOn5xx(false); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->SetRequestContext(request_context); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->SetUploadData("text/plain", form_xml); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::LOAD_DO_NOT_SEND_COOKIES); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher->Start(); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Sending AutofillDownloadManager " 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << AutofillRequestTypeToString(request_data.request_type) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " request: " << form_xml; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillDownloadManager::CacheQueryRequest( 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& forms_in_query, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& query_data) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string signature = GetCombinedSignature(forms_in_query); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (QueryRequestCache::iterator it = cached_forms_.begin(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != cached_forms_.end(); ++it) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->first == signature) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hit the cache, move to the first position and return. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<std::string, std::string> data = *it; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cached_forms_.erase(it); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cached_forms_.push_front(data); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<std::string, std::string> data; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.first = signature; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.second = query_data; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cached_forms_.push_front(data); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cached_forms_.size() > max_form_cache_size_) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cached_forms_.pop_back(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutofillDownloadManager::CheckCacheForQueryRequest( 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& forms_in_query, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* query_data) const { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string signature = GetCombinedSignature(forms_in_query); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (QueryRequestCache::const_iterator it = cached_forms_.begin(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != cached_forms_.end(); ++it) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->first == signature) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hit the cache, fill the data and return. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *query_data = it->second; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string AutofillDownloadManager::GetCombinedSignature( 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& forms_in_query) const { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t total_size = forms_in_query.size(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < forms_in_query.size(); ++i) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_size += forms_in_query[i].length(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string signature; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.reserve(total_size); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < forms_in_query.size(); ++i) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.append(","); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.append(forms_in_query[i]); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return signature; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutofillDownloadManager::OnURLFetchComplete( 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLFetcher* source) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<net::URLFetcher *, FormRequestData>::iterator it = 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_fetchers_.find(const_cast<net::URLFetcher*>(source)); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == url_fetchers_.end()) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Looks like crash on Mac is possibly caused with callback entering here 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with unknown fetcher when network is refreshed. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string type_of_request( 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AutofillRequestTypeToString(it->second.request_type)); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kHttpResponseOk = 200; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kHttpInternalServerError = 500; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kHttpBadGateway = 502; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kHttpServiceUnavailable = 503; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(it->second.form_signatures.size()); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (source->GetResponseCode() != kHttpResponseOk) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool back_off = false; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string server_header; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (source->GetResponseCode()) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kHttpBadGateway: 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!source->GetResponseHeaders()->EnumerateHeader(NULL, "server", 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &server_header) || 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartsWithASCII(server_header.c_str(), 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kAutofillQueryServerNameStartInHeader, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false) != 0) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bad gateway was received from Autofill servers. Fall through to back 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // off. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kHttpInternalServerError: 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kHttpServiceUnavailable: 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_off = true; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (back_off) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time back_off_time(base::Time::Now() + source->GetBackoffDelay()); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_query_request_ = back_off_time; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_upload_request_ = back_off_time; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "AutofillDownloadManager: " << type_of_request 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " request has failed with response " 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << source->GetResponseCode(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnServerRequestError(it->second.form_signatures[0], 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->second.request_type, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source->GetResponseCode()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_body; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source->GetResponseAsString(&response_body); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "AutofillDownloadManager: " << type_of_request 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " request has succeeded with response body: " 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << response_body; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheQueryRequest(it->second.form_signatures, response_body); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnLoadedServerPredictions(response_body); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double new_positive_upload_rate = 0; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double new_negative_upload_rate = 0; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutofillUploadXmlParser parse_handler(&new_positive_upload_rate, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &new_negative_upload_rate); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buzz::XmlParser parser(&parse_handler); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.Parse(response_body.data(), response_body.length(), true); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parse_handler.succeeded()) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPositiveUploadRate(new_positive_upload_rate); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetNegativeUploadRate(new_negative_upload_rate); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnUploadedPossibleFieldTypes(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete it->first; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_fetchers_.erase(it); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace autofill 353