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 11bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch#ifdef ANDROID 12bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch#include "android/jni/autofill_request_url.h" 13bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch#endif 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/rand_util.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h" 18201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/autofill/autofill_metrics.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/autofill_xml_parser.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/autofill/form_structure.h" 213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "googleurl/src/gurl.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_response_headers.h" 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "third_party/libjingle/source/talk/xmllite/xmlparser.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define AUTO_FILL_QUERY_SERVER_REQUEST_URL \ 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "http://toolbarqueries.clients.google.com:80/tbproxy/af/query" 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define AUTO_FILL_UPLOAD_SERVER_REQUEST_URL \ 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "http://toolbarqueries.clients.google.com:80/tbproxy/af/upload" 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER "GFE/" 334f3a742b60841cf402cd4192bd864afb7306356bBen Murdoch#ifdef ANDROID 344f3a742b60841cf402cd4192bd864afb7306356bBen Murdoch#define ANDROID_AUTOFILL_CLIENT_PARAM "?client=AndroidBrowser" 354f3a742b60841cf402cd4192bd864afb7306356bBen Murdoch#endif 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace { 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst size_t kMaxFormCacheSize = 16; 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstruct AutofillDownloadManager::FormRequestData { 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<std::string> form_signatures; 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutofillRequestType request_type; 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 46c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#ifdef ANDROID 47c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen// Taken from autofill_manager.cc 48c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsenconst double kAutoFillPositiveUploadRateDefaultValue = 0.01; 49c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsenconst double kAutoFillNegativeUploadRateDefaultValue = 0.01; 50c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#endif 51c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen 52dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutofillDownloadManager::AutofillDownloadManager(Profile* profile) 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : profile_(profile), 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_(NULL), 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen max_form_cache_size_(kMaxFormCacheSize), 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_query_request_(base::Time::Now()), 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_upload_request_(base::Time::Now()), 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positive_upload_rate_(0), 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch negative_upload_rate_(0), 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen fetcher_id_for_unittest_(0) { 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |profile_| could be NULL in some unit-tests. 62c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#ifdef ANDROID 63c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen positive_upload_rate_ = kAutoFillPositiveUploadRateDefaultValue; 64c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen negative_upload_rate_ = kAutoFillNegativeUploadRateDefaultValue; 65c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#else 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (profile_) { 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* preferences = profile_->GetPrefs(); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positive_upload_rate_ = 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferences->GetDouble(prefs::kAutofillPositiveUploadRate); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch negative_upload_rate_ = 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferences->GetDouble(prefs::kAutofillNegativeUploadRate); 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 73c4becdd46e31d261b930e4b5a539cbc1d45c23a6Kristian Monsen#endif 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAutofillDownloadManager::~AutofillDownloadManager() { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch STLDeleteContainerPairFirstPointers(url_fetchers_.begin(), 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.end()); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::SetObserver( 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutofillDownloadManager::Observer *observer) { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (observer) { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!observer_); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_ = observer; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_ = NULL; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::StartQueryRequest( 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const ScopedVector<FormStructure>& forms, 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const AutofillMetrics& metric_logger) { 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (next_query_request_ > base::Time::Now()) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We are in back-off mode: do not do the request. 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string form_xml; 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormRequestData request_data; 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures, 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &form_xml)) { 102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_data.request_type = AutofillDownloadManager::REQUEST_QUERY; 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen metric_logger.Log(AutofillMetrics::QUERY_SENT); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string query_data; 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (CheckCacheForQueryRequest(request_data.form_signatures, &query_data)) { 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "AutofillDownloadManager: query request has been retrieved from" 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << "the cache"; 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (observer_) 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen observer_->OnLoadedAutofillHeuristics(query_data); 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return StartRequest(form_xml, request_data); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::StartUploadRequest( 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FormStructure& form, bool form_was_matched) { 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (next_upload_request_ > base::Time::Now()) { 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We are in back-off mode: do not do the request. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if we need to upload form. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double upload_rate = form_was_matched ? GetPositiveUploadRate() : 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetNegativeUploadRate(); 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (base::RandDouble() > upload_rate) { 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "AutofillDownloadManager: Upload request is ignored"; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we ever need notification that upload was skipped, add it here. 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string form_xml; 136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!form.EncodeUploadRequest(form_was_matched, &form_xml)) 137513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FormRequestData request_data; 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_data.form_signatures.push_back(form.FormSignature()); 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen request_data.request_type = AutofillDownloadManager::REQUEST_UPLOAD; 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return StartRequest(form_xml, request_data); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::CancelRequest( 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& form_signature, 148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AutofillDownloadManager::AutofillRequestType request_type) { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::map<URLFetcher *, FormRequestData>::iterator it = 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.begin(); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != url_fetchers_.end(); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++it) { 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (std::find(it->second.form_signatures.begin(), 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.form_signatures.end(), form_signature) != 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.form_signatures.end() && 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.request_type == request_type) { 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete it->first; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.erase(it); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsendouble AutofillDownloadManager::GetPositiveUploadRate() const { 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return positive_upload_rate_; 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsendouble AutofillDownloadManager::GetNegativeUploadRate() const { 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return negative_upload_rate_; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::SetPositiveUploadRate(double rate) { 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rate == positive_upload_rate_) 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positive_upload_rate_ = rate; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(rate, 0.0); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_LE(rate, 1.0); 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(profile_); 1806e1a1d3242a4de2a633c62ba45948dd2d0620990Kristian Monsen#ifndef ANDROID 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* preferences = profile_->GetPrefs(); 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferences->SetDouble(prefs::kAutofillPositiveUploadRate, rate); 183cfb4826edae011aed657a813297687800ed85e17Kristian Monsen#endif 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::SetNegativeUploadRate(double rate) { 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rate == negative_upload_rate_) 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch negative_upload_rate_ = rate; 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(rate, 0.0); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_LE(rate, 1.0); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(profile_); 1936e1a1d3242a4de2a633c62ba45948dd2d0620990Kristian Monsen#ifndef ANDROID 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* preferences = profile_->GetPrefs(); 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferences->SetDouble(prefs::kAutofillNegativeUploadRate, rate); 196cfb4826edae011aed657a813297687800ed85e17Kristian Monsen#endif 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::StartRequest( 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& form_xml, 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FormRequestData& request_data) { 202cfb4826edae011aed657a813297687800ed85e17Kristian Monsen net::URLRequestContextGetter* request_context = 20372348d7342b67133b80566824ec56ee7afff127fKristian Monsen#ifdef ANDROID 20472348d7342b67133b80566824ec56ee7afff127fKristian Monsen // On Android, use the webview request context getter which was passed 20572348d7342b67133b80566824ec56ee7afff127fKristian Monsen // through in the WebAutoFill::init() method in WebKit. 20672348d7342b67133b80566824ec56ee7afff127fKristian Monsen profile_->GetRequestContext(); 20772348d7342b67133b80566824ec56ee7afff127fKristian Monsen#else 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Profile::GetDefaultRequestContext(); 20972348d7342b67133b80566824ec56ee7afff127fKristian Monsen#endif 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check if default request context is NULL: this very rarely happens, 211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // I think, this could happen only if user opens chrome with some pages 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // loading the forms immediately; I cannot reproduce this even in that 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // scenario, but bug 74492 shows it happened at least once. In that case bail 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // out and fall back on our own heuristics. 215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!request_context) 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string request_url; 218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (request_data.request_type == AutofillDownloadManager::REQUEST_QUERY) 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_url = AUTO_FILL_QUERY_SERVER_REQUEST_URL; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch request_url = AUTO_FILL_UPLOAD_SERVER_REQUEST_URL; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 223bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch#ifdef ANDROID 224bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch if (request_data.request_type == AutofillDownloadManager::REQUEST_QUERY) { 225bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch // Ask the platform what URL to use for Autofill. If the 226bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch // platform doesn't know, bail and rely on the heuristics 227bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch // we've gathered. 228bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch request_url = android::AutofillRequestUrl::GetQueryUrl(); 229bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch if (request_url.empty()) 230bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch return false; 2314f3a742b60841cf402cd4192bd864afb7306356bBen Murdoch request_url += ANDROID_AUTOFILL_CLIENT_PARAM; 2324f3a742b60841cf402cd4192bd864afb7306356bBen Murdoch 233bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch } 234bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch#endif 235bb958596648e7394f6cd9dcbd264ef9931655764Ben Murdoch 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Id is ignored for regular chrome, in unit test id's for fake fetcher 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // factory will be 0, 1, 2, ... 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLFetcher *fetcher = URLFetcher::Create(fetcher_id_for_unittest_++, 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL(request_url), 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLFetcher::POST, 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this); 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_[fetcher] = request_data; 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fetcher->set_automatically_retry_on_5xx(false); 244dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen fetcher->set_request_context(request_context); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fetcher->set_upload_data("text/plain", form_xml); 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fetcher->Start(); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::CacheQueryRequest( 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::vector<std::string>& forms_in_query, 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& query_data) { 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string signature = GetCombinedSignature(forms_in_query); 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (QueryRequestCache::iterator it = cached_forms_.begin(); 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen it != cached_forms_.end(); ++it) { 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (it->first == signature) { 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We hit the cache, move to the first position and return. 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::pair<std::string, std::string> data = *it; 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cached_forms_.erase(it); 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cached_forms_.push_front(data); 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::pair<std::string, std::string> data; 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen data.first = signature; 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen data.second = query_data; 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cached_forms_.push_front(data); 26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen while (cached_forms_.size() > max_form_cache_size_) 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen cached_forms_.pop_back(); 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AutofillDownloadManager::CheckCacheForQueryRequest( 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::vector<std::string>& forms_in_query, 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string* query_data) const { 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string signature = GetCombinedSignature(forms_in_query); 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (QueryRequestCache::const_iterator it = cached_forms_.begin(); 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen it != cached_forms_.end(); ++it) { 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (it->first == signature) { 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We hit the cache, fill the data and return. 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *query_data = it->second; 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string AutofillDownloadManager::GetCombinedSignature( 28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::vector<std::string>& forms_in_query) const { 28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size_t total_size = forms_in_query.size(); 29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < forms_in_query.size(); ++i) 29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen total_size += forms_in_query[i].length(); 29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string signature; 29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen signature.reserve(total_size); 29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < forms_in_query.size(); ++i) { 29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i) 29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen signature.append(","); 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen signature.append(forms_in_query[i]); 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return signature; 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AutofillDownloadManager::OnURLFetchComplete( 3053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const URLFetcher* source, 3063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const GURL& url, 3073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const net::URLRequestStatus& status, 3083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen int response_code, 3093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const ResponseCookies& cookies, 3103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const std::string& data) { 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::map<URLFetcher *, FormRequestData>::iterator it = 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.find(const_cast<URLFetcher*>(source)); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (it == url_fetchers_.end()) { 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Looks like crash on Mac is possibly caused with callback entering here 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with unknown fetcher when network is refreshed. 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string type_of_request( 319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen it->second.request_type == AutofillDownloadManager::REQUEST_QUERY ? 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "query" : "upload"); 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kHttpResponseOk = 200; 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kHttpInternalServerError = 500; 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kHttpBadGateway = 502; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kHttpServiceUnavailable = 503; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(it->second.form_signatures.size()); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (response_code != kHttpResponseOk) { 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool back_off = false; 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string server_header; 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (response_code) { 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case kHttpBadGateway: 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!source->response_headers()->EnumerateHeader(NULL, "server", 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &server_header) || 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StartsWithASCII(server_header.c_str(), 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER, 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false) != 0) 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Bad gateway was received from Autofill servers. Fall through to back 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // off. 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case kHttpInternalServerError: 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case kHttpServiceUnavailable: 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch back_off = true; 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (back_off) { 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time back_off_time(base::Time::Now() + source->backoff_delay()); 348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) { 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_query_request_ = back_off_time; 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_upload_request_ = back_off_time; 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(WARNING) << "AutofillDownloadManager: " << type_of_request 3564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch << " request has failed with response " << response_code; 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (observer_) { 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_->OnHeuristicsRequestError(it->second.form_signatures[0], 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.request_type, 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response_code); 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "AutofillDownloadManager: " << type_of_request 364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << " request has succeeded"; 365dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) { 36672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CacheQueryRequest(it->second.form_signatures, data); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (observer_) 368dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen observer_->OnLoadedAutofillHeuristics(data); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double new_positive_upload_rate = 0; 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch double new_negative_upload_rate = 0; 372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AutofillUploadXmlParser parse_handler(&new_positive_upload_rate, 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &new_negative_upload_rate); 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buzz::XmlParser parser(&parse_handler); 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parser.Parse(data.data(), data.length(), true); 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (parse_handler.succeeded()) { 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetPositiveUploadRate(new_positive_upload_rate); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetNegativeUploadRate(new_negative_upload_rate); 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (observer_) 382dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen observer_->OnUploadedAutofillHeuristics(it->second.form_signatures[0]); 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete it->first; 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_fetchers_.erase(it); 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 388