autofill_download.cc revision cfb4826edae011aed657a813297687800ed85e17
1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/autofill_download.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <ostream> 94a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include <vector> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/rand_util.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h" 15201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/autofill/autofill_metrics.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/autofill_xml_parser.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/autofill/form_structure.h" 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "googleurl/src/gurl.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_response_headers.h" 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "third_party/libjingle/source/talk/xmllite/xmlparser.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define AUTO_FILL_QUERY_SERVER_REQUEST_URL \ 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "http://toolbarqueries.clients.google.com:80/tbproxy/af/query" 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define AUTO_FILL_UPLOAD_SERVER_REQUEST_URL \ 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "http://toolbarqueries.clients.google.com:80/tbproxy/af/upload" 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER "GFE/" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace { 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst size_t kMaxFormCacheSize = 16; 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstruct AutofillDownloadManager::FormRequestData { 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<std::string> form_signatures; 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutofillRequestType request_type; 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 40c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#ifdef ANDROID 41c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen// Taken from autofill_manager.cc 42c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsenconst double kAutoFillPositiveUploadRateDefaultValue = 0.01; 43c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsenconst double kAutoFillNegativeUploadRateDefaultValue = 0.01; 44c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#endif 45c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen 46dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutofillDownloadManager::AutofillDownloadManager(Profile* profile) 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : profile_(profile), 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_(NULL), 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen max_form_cache_size_(kMaxFormCacheSize), 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_query_request_(base::Time::Now()), 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_upload_request_(base::Time::Now()), 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positive_upload_rate_(0), 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch negative_upload_rate_(0), 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen fetcher_id_for_unittest_(0) { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |profile_| could be NULL in some unit-tests. 56c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#ifdef ANDROID 57c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen positive_upload_rate_ = kAutoFillPositiveUploadRateDefaultValue; 58c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen negative_upload_rate_ = kAutoFillNegativeUploadRateDefaultValue; 59c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#else 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (profile_) { 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* preferences = profile_->GetPrefs(); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positive_upload_rate_ = 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferences->GetDouble(prefs::kAutofillPositiveUploadRate); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch negative_upload_rate_ = 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferences->GetDouble(prefs::kAutofillNegativeUploadRate); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 67c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#endif 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 70dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutofillDownloadManager::~AutofillDownloadManager() { 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteContainerPairFirstPointers(url_fetchers_.begin(), 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.end()); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::SetObserver( 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutofillDownloadManager::Observer *observer) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (observer) { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!observer_); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_ = observer; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_ = NULL; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::StartQueryRequest( 8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const ScopedVector<FormStructure>& forms, 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const AutofillMetrics& metric_logger) { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (next_query_request_ > base::Time::Now()) { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We are in back-off mode: do not do the request. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string form_xml; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormRequestData request_data; 94513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures, 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &form_xml)) { 96513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_data.request_type = AutofillDownloadManager::REQUEST_QUERY; 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen metric_logger.Log(AutofillMetrics::QUERY_SENT); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string query_data; 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (CheckCacheForQueryRequest(request_data.form_signatures, &query_data)) { 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "AutofillDownloadManager: query request has been retrieved from" 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << "the cache"; 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (observer_) 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen observer_->OnLoadedAutofillHeuristics(query_data); 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return StartRequest(form_xml, request_data); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::StartUploadRequest( 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FormStructure& form, bool form_was_matched) { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (next_upload_request_ > base::Time::Now()) { 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We are in back-off mode: do not do the request. 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if we need to upload form. 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double upload_rate = form_was_matched ? GetPositiveUploadRate() : 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetNegativeUploadRate(); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (base::RandDouble() > upload_rate) { 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "AutofillDownloadManager: Upload request is ignored"; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we ever need notification that upload was skipped, add it here. 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string form_xml; 130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!form.EncodeUploadRequest(form_was_matched, &form_xml)) 131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormRequestData request_data; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_data.form_signatures.push_back(form.FormSignature()); 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_data.request_type = AutofillDownloadManager::REQUEST_UPLOAD; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return StartRequest(form_xml, request_data); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::CancelRequest( 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& form_signature, 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutofillDownloadManager::AutofillRequestType request_type) { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::map<URLFetcher *, FormRequestData>::iterator it = 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.begin(); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != url_fetchers_.end(); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++it) { 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (std::find(it->second.form_signatures.begin(), 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.form_signatures.end(), form_signature) != 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.form_signatures.end() && 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.request_type == request_type) { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete it->first; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.erase(it); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsendouble AutofillDownloadManager::GetPositiveUploadRate() const { 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return positive_upload_rate_; 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsendouble AutofillDownloadManager::GetNegativeUploadRate() const { 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return negative_upload_rate_; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::SetPositiveUploadRate(double rate) { 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rate == positive_upload_rate_) 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positive_upload_rate_ = rate; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(rate, 0.0); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_LE(rate, 1.0); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(profile_); 1746e1a1d3242a4de2a633c62ba45948dd2d0620990Kristian Monsen#ifndef ANDROID 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* preferences = profile_->GetPrefs(); 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferences->SetDouble(prefs::kAutofillPositiveUploadRate, rate); 177cfb4826edae011aed657a813297687800ed85e17Kristian Monsen#endif 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::SetNegativeUploadRate(double rate) { 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rate == negative_upload_rate_) 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch negative_upload_rate_ = rate; 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(rate, 0.0); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_LE(rate, 1.0); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(profile_); 1876e1a1d3242a4de2a633c62ba45948dd2d0620990Kristian Monsen#ifndef ANDROID 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* preferences = profile_->GetPrefs(); 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferences->SetDouble(prefs::kAutofillNegativeUploadRate, rate); 190cfb4826edae011aed657a813297687800ed85e17Kristian Monsen#endif 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::StartRequest( 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& form_xml, 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FormRequestData& request_data) { 196cfb4826edae011aed657a813297687800ed85e17Kristian Monsen net::URLRequestContextGetter* request_context = 19772348d7342b67133b80566824ec56ee7afff127fKristian Monsen#ifdef ANDROID 19872348d7342b67133b80566824ec56ee7afff127fKristian Monsen // On Android, use the webview request context getter which was passed 19972348d7342b67133b80566824ec56ee7afff127fKristian Monsen // through in the WebAutoFill::init() method in WebKit. 20072348d7342b67133b80566824ec56ee7afff127fKristian Monsen profile_->GetRequestContext(); 20172348d7342b67133b80566824ec56ee7afff127fKristian Monsen#else 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Profile::GetDefaultRequestContext(); 20372348d7342b67133b80566824ec56ee7afff127fKristian Monsen#endif 204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check if default request context is NULL: this very rarely happens, 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // I think, this could happen only if user opens chrome with some pages 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // loading the forms immediately; I cannot reproduce this even in that 207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // scenario, but bug 74492 shows it happened at least once. In that case bail 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // out and fall back on our own heuristics. 209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!request_context) 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string request_url; 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (request_data.request_type == AutofillDownloadManager::REQUEST_QUERY) 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_url = AUTO_FILL_QUERY_SERVER_REQUEST_URL; 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_url = AUTO_FILL_UPLOAD_SERVER_REQUEST_URL; 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Id is ignored for regular chrome, in unit test id's for fake fetcher 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // factory will be 0, 1, 2, ... 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLFetcher *fetcher = URLFetcher::Create(fetcher_id_for_unittest_++, 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL(request_url), 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLFetcher::POST, 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_[fetcher] = request_data; 2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fetcher->set_automatically_retry_on_5xx(false); 225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen fetcher->set_request_context(request_context); 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fetcher->set_upload_data("text/plain", form_xml); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fetcher->Start(); 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::CacheQueryRequest( 23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::vector<std::string>& forms_in_query, 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& query_data) { 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string signature = GetCombinedSignature(forms_in_query); 23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (QueryRequestCache::iterator it = cached_forms_.begin(); 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen it != cached_forms_.end(); ++it) { 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (it->first == signature) { 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We hit the cache, move to the first position and return. 23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::pair<std::string, std::string> data = *it; 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cached_forms_.erase(it); 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cached_forms_.push_front(data); 24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::pair<std::string, std::string> data; 24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen data.first = signature; 24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen data.second = query_data; 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cached_forms_.push_front(data); 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen while (cached_forms_.size() > max_form_cache_size_) 25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cached_forms_.pop_back(); 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::CheckCacheForQueryRequest( 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::vector<std::string>& forms_in_query, 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string* query_data) const { 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string signature = GetCombinedSignature(forms_in_query); 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (QueryRequestCache::const_iterator it = cached_forms_.begin(); 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen it != cached_forms_.end(); ++it) { 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (it->first == signature) { 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We hit the cache, fill the data and return. 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *query_data = it->second; 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string AutofillDownloadManager::GetCombinedSignature( 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::vector<std::string>& forms_in_query) const { 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t total_size = forms_in_query.size(); 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < forms_in_query.size(); ++i) 27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen total_size += forms_in_query[i].length(); 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string signature; 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen signature.reserve(total_size); 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < forms_in_query.size(); ++i) { 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i) 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen signature.append(","); 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen signature.append(forms_in_query[i]); 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return signature; 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 285dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::OnURLFetchComplete( 2863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const URLFetcher* source, 2873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const GURL& url, 2883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const net::URLRequestStatus& status, 2893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen int response_code, 2903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const ResponseCookies& cookies, 2913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const std::string& data) { 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::map<URLFetcher *, FormRequestData>::iterator it = 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.find(const_cast<URLFetcher*>(source)); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (it == url_fetchers_.end()) { 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Looks like crash on Mac is possibly caused with callback entering here 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with unknown fetcher when network is refreshed. 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string type_of_request( 300dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen it->second.request_type == AutofillDownloadManager::REQUEST_QUERY ? 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "query" : "upload"); 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kHttpResponseOk = 200; 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kHttpInternalServerError = 500; 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kHttpBadGateway = 502; 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kHttpServiceUnavailable = 503; 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(it->second.form_signatures.size()); 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (response_code != kHttpResponseOk) { 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool back_off = false; 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string server_header; 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (response_code) { 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case kHttpBadGateway: 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!source->response_headers()->EnumerateHeader(NULL, "server", 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &server_header) || 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StartsWithASCII(server_header.c_str(), 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER, 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false) != 0) 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Bad gateway was received from Autofill servers. Fall through to back 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // off. 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case kHttpInternalServerError: 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case kHttpServiceUnavailable: 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch back_off = true; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (back_off) { 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time back_off_time(base::Time::Now() + source->backoff_delay()); 329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) { 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_query_request_ = back_off_time; 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_upload_request_ = back_off_time; 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(WARNING) << "AutofillDownloadManager: " << type_of_request 3374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch << " request has failed with response " << response_code; 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (observer_) { 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_->OnHeuristicsRequestError(it->second.form_signatures[0], 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.request_type, 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response_code); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "AutofillDownloadManager: " << type_of_request 345731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " request has succeeded"; 346dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) { 34772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CacheQueryRequest(it->second.form_signatures, data); 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (observer_) 349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen observer_->OnLoadedAutofillHeuristics(data); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double new_positive_upload_rate = 0; 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double new_negative_upload_rate = 0; 353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AutofillUploadXmlParser parse_handler(&new_positive_upload_rate, 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &new_negative_upload_rate); 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmlParser parser(&parse_handler); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parser.Parse(data.data(), data.length(), true); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (parse_handler.succeeded()) { 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetPositiveUploadRate(new_positive_upload_rate); 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetNegativeUploadRate(new_negative_upload_rate); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (observer_) 363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen observer_->OnUploadedAutofillHeuristics(it->second.form_signatures[0]); 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete it->first; 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.erase(it); 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 369