autofill_download.cc revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 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>
84a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include <vector>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/rand_util.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h"
13201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/autofill/autofill_metrics.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/autofill_xml_parser.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_response_headers.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define DISABLED_REQUEST_URL "http://disabled"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
227d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#if defined(GOOGLE_CHROME_BUILD) || (defined(ANDROID) && defined(HAVE_AUTOFILL_DOWNLOAD_INTERNAL_H) && HAVE_AUTOFILL_DOWNLOAD_INTERNAL_H)
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/internal/autofill_download_internal.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define AUTO_FILL_QUERY_SERVER_REQUEST_URL DISABLED_REQUEST_URL
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define AUTO_FILL_UPLOAD_SERVER_REQUEST_URL DISABLED_REQUEST_URL
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER "SOMESERVER/"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstruct AutoFillDownloadManager::FormRequestData {
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::vector<std::string> form_signatures;
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  AutoFillRequestType request_type;
33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAutoFillDownloadManager::AutoFillDownloadManager(Profile* profile)
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : profile_(profile),
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer_(NULL),
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      next_query_request_(base::Time::Now()),
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      next_upload_request_(base::Time::Now()),
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      positive_upload_rate_(0),
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      negative_upload_rate_(0),
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      fetcher_id_for_unittest_(0),
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_testing_(false) {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |profile_| could be NULL in some unit-tests.
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_) {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PrefService* preferences = profile_->GetPrefs();
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    positive_upload_rate_ =
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        preferences->GetReal(prefs::kAutoFillPositiveUploadRate);
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    negative_upload_rate_ =
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        preferences->GetReal(prefs::kAutoFillNegativeUploadRate);
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAutoFillDownloadManager::~AutoFillDownloadManager() {
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteContainerPairFirstPointers(url_fetchers_.begin(),
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      url_fetchers_.end());
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutoFillDownloadManager::SetObserver(
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutoFillDownloadManager::Observer *observer) {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (observer) {
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!observer_);
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer_ = observer;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer_ = NULL;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutoFillDownloadManager::StartQueryRequest(
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const ScopedVector<FormStructure>& forms,
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const AutoFillMetrics& metric_logger) {
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (next_query_request_ > base::Time::Now()) {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We are in back-off mode: do not do the request.
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string form_xml;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FormRequestData request_data;
78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures,
79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                         &form_xml))
80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return false;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request_data.request_type = AutoFillDownloadManager::REQUEST_QUERY;
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  metric_logger.Log(AutoFillMetrics::QUERY_SENT);
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return StartRequest(form_xml, request_data);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutoFillDownloadManager::StartUploadRequest(
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FormStructure& form, bool form_was_matched) {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (next_upload_request_ > base::Time::Now()) {
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We are in back-off mode: do not do the request.
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check if we need to upload form.
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  double upload_rate = form_was_matched ? GetPositiveUploadRate() :
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          GetNegativeUploadRate();
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (base::RandDouble() > upload_rate) {
99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "AutoFillDownloadManager: Upload request is ignored";
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If we ever need notification that upload was skipped, add it here.
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string form_xml;
104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!form.EncodeUploadRequest(form_was_matched, &form_xml))
105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return false;
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FormRequestData request_data;
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request_data.form_signatures.push_back(form.FormSignature());
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request_data.request_type = AutoFillDownloadManager::REQUEST_UPLOAD;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return StartRequest(form_xml, request_data);
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutoFillDownloadManager::CancelRequest(
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& form_signature,
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutoFillDownloadManager::AutoFillRequestType request_type) {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::map<URLFetcher *, FormRequestData>::iterator it =
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       url_fetchers_.begin();
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != url_fetchers_.end();
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ++it) {
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (std::find(it->second.form_signatures.begin(),
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        it->second.form_signatures.end(), form_signature) !=
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        it->second.form_signatures.end() &&
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        it->second.request_type == request_type) {
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      delete it->first;
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url_fetchers_.erase(it);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochdouble AutoFillDownloadManager::GetPositiveUploadRate() const {
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return positive_upload_rate_;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochdouble AutoFillDownloadManager::GetNegativeUploadRate() const {
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return negative_upload_rate_;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutoFillDownloadManager::SetPositiveUploadRate(double rate) {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rate == positive_upload_rate_)
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  positive_upload_rate_ = rate;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_GE(rate, 0.0);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_LE(rate, 1.0);
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(profile_);
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PrefService* preferences = profile_->GetPrefs();
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  preferences->SetReal(prefs::kAutoFillPositiveUploadRate, rate);
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutoFillDownloadManager::SetNegativeUploadRate(double rate) {
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rate == negative_upload_rate_)
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  negative_upload_rate_ = rate;
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_GE(rate, 0.0);
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_LE(rate, 1.0);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(profile_);
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PrefService* preferences = profile_->GetPrefs();
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  preferences->SetReal(prefs::kAutoFillNegativeUploadRate, rate);
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AutoFillDownloadManager::StartRequest(
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& form_xml,
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FormRequestData& request_data) {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string request_url;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (request_data.request_type == AutoFillDownloadManager::REQUEST_QUERY)
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    request_url = AUTO_FILL_QUERY_SERVER_REQUEST_URL;
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    request_url = AUTO_FILL_UPLOAD_SERVER_REQUEST_URL;
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!request_url.compare(DISABLED_REQUEST_URL) && !is_testing_) {
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We have it disabled - return true as if it succeeded, but do nothing.
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1761391b24619d56bae6ce14bb54ed0fb16a945e853Kristian Monsen
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Id is ignored for regular chrome, in unit test id's for fake fetcher
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // factory will be 0, 1, 2, ...
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLFetcher *fetcher = URLFetcher::Create(fetcher_id_for_unittest_++,
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           GURL(request_url),
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           URLFetcher::POST,
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           this);
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_fetchers_[fetcher] = request_data;
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  fetcher->set_automatically_retry_on_5xx(false);
18540eae52c5e5dbf475a0cf368c9ccbb7f8a0653f4Ben Murdoch#ifdef ANDROID
18640eae52c5e5dbf475a0cf368c9ccbb7f8a0653f4Ben Murdoch  // On Android, use the webview request context getter which was passed
18740eae52c5e5dbf475a0cf368c9ccbb7f8a0653f4Ben Murdoch  // through in the WebAutoFill::init() method in WebKit.
18840eae52c5e5dbf475a0cf368c9ccbb7f8a0653f4Ben Murdoch  fetcher->set_request_context(profile_->GetRequestContext());
18940eae52c5e5dbf475a0cf368c9ccbb7f8a0653f4Ben Murdoch#else
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  fetcher->set_request_context(Profile::GetDefaultRequestContext());
19140eae52c5e5dbf475a0cf368c9ccbb7f8a0653f4Ben Murdoch#endif
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  fetcher->set_upload_data("text/plain", form_xml);
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  fetcher->Start();
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AutoFillDownloadManager::OnURLFetchComplete(const URLFetcher* source,
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 const GURL& url,
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 const URLRequestStatus& status,
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 int response_code,
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 const ResponseCookies& cookies,
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 const std::string& data) {
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<URLFetcher *, FormRequestData>::iterator it =
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url_fetchers_.find(const_cast<URLFetcher*>(source));
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (it == url_fetchers_.end()) {
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Looks like crash on Mac is possibly caused with callback entering here
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // with unknown fetcher when network is refreshed.
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string type_of_request(
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      it->second.request_type == AutoFillDownloadManager::REQUEST_QUERY ?
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          "query" : "upload");
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kHttpResponseOk = 200;
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kHttpInternalServerError = 500;
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kHttpBadGateway = 502;
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kHttpServiceUnavailable = 503;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(it->second.form_signatures.size());
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (response_code != kHttpResponseOk) {
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool back_off = false;
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string server_header;
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (response_code) {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case kHttpBadGateway:
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (!source->response_headers()->EnumerateHeader(NULL, "server",
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                         &server_header) ||
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            StartsWithASCII(server_header.c_str(),
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER,
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            false) != 0)
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          break;
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Bad getaway was received from AutoFill servers. Fall through to back
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // off.
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case kHttpInternalServerError:
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case kHttpServiceUnavailable:
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        back_off = true;
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (back_off) {
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base::Time back_off_time(base::Time::Now() + source->backoff_delay());
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (it->second.request_type == AutoFillDownloadManager::REQUEST_QUERY) {
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        next_query_request_ = back_off_time;
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        next_upload_request_ = back_off_time;
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    LOG(WARNING) << "AutoFillDownloadManager: " << type_of_request
2484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                 << " request has failed with response " << response_code;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (observer_) {
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer_->OnHeuristicsRequestError(it->second.form_signatures[0],
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          it->second.request_type,
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          response_code);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
255731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "AutoFillDownloadManager: " << type_of_request
256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            << " request has succeeded";
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (it->second.request_type == AutoFillDownloadManager::REQUEST_QUERY) {
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (observer_)
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        observer_->OnLoadedAutoFillHeuristics(data);
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      double new_positive_upload_rate = 0;
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      double new_negative_upload_rate = 0;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      AutoFillUploadXmlParser parse_handler(&new_positive_upload_rate,
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            &new_negative_upload_rate);
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      buzz::XmlParser parser(&parse_handler);
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parser.Parse(data.data(), data.length(), true);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (parse_handler.succeeded()) {
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        SetPositiveUploadRate(new_positive_upload_rate);
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        SetNegativeUploadRate(new_negative_upload_rate);
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (observer_)
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        observer_->OnUploadedAutoFillHeuristics(it->second.form_signatures[0]);
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete it->first;
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_fetchers_.erase(it);
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
279