cloud_print_url_fetcher.cc revision f2477e01787aa58f445919b809d89e252beef54f
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Use of this source code is governed by a BSD-style license that can be
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// found in the LICENSE file.
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner#include "chrome/service/cloud_print/cloud_print_url_fetcher.h"
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "base/metrics/histogram.h"
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "base/strings/stringprintf.h"
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "base/values.h"
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "chrome/common/cloud_print/cloud_print_constants.h"
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "chrome/common/cloud_print/cloud_print_helpers.h"
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "chrome/service/cloud_print/cloud_print_service_helpers.h"
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "chrome/service/cloud_print/cloud_print_token_store.h"
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "chrome/service/net/service_url_request_context.h"
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "chrome/service/service_process.h"
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "net/base/load_flags.h"
17e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek#include "net/http/http_status_code.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "net/url_request/url_fetcher.h"
19e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#include "net/url_request/url_request_status.h"
20464175bba1318bef7905122e9fda20cff926df78Chris Lattner#include "url/gurl.h"
21e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar
22464175bba1318bef7905122e9fda20cff926df78Chris Lattnernamespace cloud_print {
2368d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff
247192f8e9592729882a09d84d77838db26e39ebd4Ted Kremeneknamespace {
256c2b6eb8d836da19007f7540709e16d5e39a1cbaChris Lattner
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid ReportRequestTime(CloudPrintURLFetcher::RequestType type,
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                       base::TimeDelta time) {
28b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  if (type == CloudPrintURLFetcher::REQUEST_REGISTER) {
29b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.Register", time);
30b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) {
31b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.UpdatePrinter", time);
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else if (type == CloudPrintURLFetcher::REQUEST_DATA) {
33e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar    UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.DownloadData", time);
34e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar  } else {
35c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner    UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.Other", time);
36e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar  }
37e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar}
38e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar
39e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbarvoid ReportRetriesCount(CloudPrintURLFetcher::RequestType type,
40e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar                        int retries) {
41c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  if (type == CloudPrintURLFetcher::REQUEST_REGISTER) {
42e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar    UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.Register", retries);
43e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar  } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) {
44e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar    UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.UpdatePrinter",
45e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar                             retries);
46e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar  } else if (type == CloudPrintURLFetcher::REQUEST_DATA) {
47e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar    UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.DownloadData",
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                             retries);
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else {
502bd24ba6d10f8c811c8e2a57c8397e07082ba497Ted Kremenek    UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.Other", retries);
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
52ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb}
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid ReportDownloadSize(CloudPrintURLFetcher::RequestType type, size_t size) {
555618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  if (type == CloudPrintURLFetcher::REQUEST_REGISTER) {
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.Register", size);
577192f8e9592729882a09d84d77838db26e39ebd4Ted Kremenek  } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) {
58c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.UpdatePrinter",
59c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman                            size);
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  } else if (type == CloudPrintURLFetcher::REQUEST_DATA) {
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.DownloadData",
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                            size);
63a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  } else {
64a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.Other", size);
6588a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel  }
66a9a4a24592a2164114a8a36717650e6341eb67a4Ted Kremenek}
6788a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel
6844a3dded8080c5c9cfdad208ade8f8f7850d9a4fDevang Patelvoid ReportUploadSize(CloudPrintURLFetcher::RequestType type, size_t size) {
6944a3dded8080c5c9cfdad208ade8f8f7850d9a4fDevang Patel  if (type == CloudPrintURLFetcher::REQUEST_REGISTER) {
707d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.Register", size);
71b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson  } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) {
72b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.UpdatePrinter",
73b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson                            size);
74b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson  } else if (type == CloudPrintURLFetcher::REQUEST_DATA) {
757e219e47de26346885d667131977bd9ca2d7662aSteve Naroff    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.DownloadData",
766083ea3723ec3996ae3bdf8d1b352b0c3b3922c8Ted Kremenek                            size);
77a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  } else {
787e219e47de26346885d667131977bd9ca2d7662aSteve Naroff    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.Other", size);
792198891824c38d45b2279de5d5e3ef9394eb457cSteve Naroff  }
806083ea3723ec3996ae3bdf8d1b352b0c3b3922c8Ted Kremenek}
81a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek
82b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz JahanianCloudPrintURLFetcherFactory* g_factory = NULL;
83b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian
846083ea3723ec3996ae3bdf8d1b352b0c3b3922c8Ted Kremenek}  // namespace
85a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek
86390d50a725497e99247dc104a7d2c2a255d3af14Fariborz Jahanian// virtual
878baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders CarlssonCloudPrintURLFetcherFactory::~CloudPrintURLFetcherFactory() {}
886083ea3723ec3996ae3bdf8d1b352b0c3b3922c8Ted Kremenek
89a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek// static
908baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders CarlssonCloudPrintURLFetcher* CloudPrintURLFetcher::Create() {
91390d50a725497e99247dc104a7d2c2a255d3af14Fariborz Jahanian  CloudPrintURLFetcherFactory* factory = CloudPrintURLFetcher::factory();
92a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  return factory ? factory->CreateCloudPrintURLFetcher() :
932198891824c38d45b2279de5d5e3ef9394eb457cSteve Naroff      new CloudPrintURLFetcher;
947a9d49fd2bfac00e905b361ba76d26ab5b6c3b09Ted Kremenek}
95bd4c1ada2e8668f43a865dc2c662085cf61940c4Anders Carlsson
96bd4c1ada2e8668f43a865dc2c662085cf61940c4Anders Carlsson// static
97ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios KyrtzidisCloudPrintURLFetcherFactory* CloudPrintURLFetcher::factory() {
98ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis  return g_factory;
99e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek}
100b800dc2d5e27ec60f567567b623cdc61152b8fb8Chris Lattner
101e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek// static
102e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenekvoid CloudPrintURLFetcher::set_factory(CloudPrintURLFetcherFactory* factory) {
103e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek  g_factory = factory;
104e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek}
105e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek
106e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted KremenekCloudPrintURLFetcher::ResponseAction
1076c2b6eb8d836da19007f7540709e16d5e39a1cbaChris LattnerCloudPrintURLFetcher::Delegate::HandleRawResponse(
108e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek    const net::URLFetcher* source,
1097a9d49fd2bfac00e905b361ba76d26ab5b6c3b09Ted Kremenek    const GURL& url,
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const net::URLRequestStatus& status,
11171993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson    int response_code,
11229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff    const net::ResponseCookies& cookies,
113a9a4a24592a2164114a8a36717650e6341eb67a4Ted Kremenek    const std::string& data) {
1147a9d49fd2bfac00e905b361ba76d26ab5b6c3b09Ted Kremenek  return CONTINUE_PROCESSING;
115e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek}
116e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek
1176c2b6eb8d836da19007f7540709e16d5e39a1cbaChris LattnerCloudPrintURLFetcher::ResponseAction
1189c728dc4d8da89c73fcae74c9e72d7a83ffd7b6dTed KremenekCloudPrintURLFetcher::Delegate::HandleRawData(
1199c728dc4d8da89c73fcae74c9e72d7a83ffd7b6dTed Kremenek    const net::URLFetcher* source,
1209c728dc4d8da89c73fcae74c9e72d7a83ffd7b6dTed Kremenek    const GURL& url,
121ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis    const std::string& data) {
122ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis  return CONTINUE_PROCESSING;
123ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis}
124a9a4a24592a2164114a8a36717650e6341eb67a4Ted Kremenek
125a9a4a24592a2164114a8a36717650e6341eb67a4Ted KremenekCloudPrintURLFetcher::ResponseAction
126a9a4a24592a2164114a8a36717650e6341eb67a4Ted KremenekCloudPrintURLFetcher::Delegate::HandleJSONData(
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const net::URLFetcher* source,
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const GURL& url,
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    base::DictionaryValue* json_data,
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool succeeded) {
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return CONTINUE_PROCESSING;
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13364c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerCloudPrintURLFetcher::CloudPrintURLFetcher()
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    : delegate_(NULL),
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      num_retries_(0),
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      type_(REQUEST_MAX) {
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
13933e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
1408e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregorbool CloudPrintURLFetcher::IsSameRequest(const net::URLFetcher* source) {
1418e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  return (request_.get() == source);
142e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek}
143e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek
144e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbarvoid CloudPrintURLFetcher::StartGetRequest(
145fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek    RequestType type,
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const GURL& url,
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Delegate* delegate,
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    int max_retries,
14903ed44061df258e74a40383bda849e14b892a8c6Ted Kremenek    const std::string& additional_headers) {
15003ed44061df258e74a40383bda849e14b892a8c6Ted Kremenek  StartRequestHelper(type, url, net::URLFetcher::GET, delegate, max_retries,
151464175bba1318bef7905122e9fda20cff926df78Chris Lattner                     std::string(), std::string(), additional_headers);
152464175bba1318bef7905122e9fda20cff926df78Chris Lattner}
153464175bba1318bef7905122e9fda20cff926df78Chris Lattner
154d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattnervoid CloudPrintURLFetcher::StartPostRequest(
155f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    RequestType type,
156f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    const GURL& url,
157f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    Delegate* delegate,
158f46699ce225811d8d9dbab9d00189a0e54469457Chris Lattner    int max_retries,
159ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    const std::string& post_data_mime_type,
160ebb97e98c03f8d7034bd3748a10e35f39a95c289Christopher Lamb    const std::string& post_data,
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const std::string& additional_headers) {
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StartRequestHelper(type, url, net::URLFetcher::POST, delegate, max_retries,
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                     post_data_mime_type, post_data, additional_headers);
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CloudPrintURLFetcher::OnURLFetchComplete(
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const net::URLFetcher* source) {
1685618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  VLOG(1) << "CP_PROXY: OnURLFetchComplete, url: " << source->GetURL()
1695618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff          << ", response code: " << source->GetResponseCode();
1705618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  // Make sure we stay alive through the body of this function.
1715618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff  scoped_refptr<CloudPrintURLFetcher> keep_alive(this);
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  std::string data;
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  source->GetResponseAsString(&data);
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ReportRequestTime(type_, base::Time::Now() - start_time_);
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ReportDownloadSize(type_, data.size());
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ResponseAction action = delegate_->HandleRawResponse(
177bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff      source,
178bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff      source->GetURL(),
179c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff      source->GetStatus(),
180c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff      source->GetResponseCode(),
181c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff      source->GetCookies(),
182fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff      data);
183c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman
184c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  // If we get auth error, notify delegate and check if it wants to proceed.
185c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  if (action == CONTINUE_PROCESSING &&
186c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman      source->GetResponseCode() == net::HTTP_FORBIDDEN) {
187c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman    action = delegate_->OnRequestAuthError();
188c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman  }
189bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff
190bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff  if (action == CONTINUE_PROCESSING) {
191c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff    // We need to retry on all network errors.
192c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff    if (!source->GetStatus().is_success() || (source->GetResponseCode() != 200))
193c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff      action = RETRY_REQUEST;
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else
19573322924127c873c13101b705dd823f5539ffa5fSteve Naroff      action = delegate_->HandleRawData(source, source->GetURL(), data);
19673322924127c873c13101b705dd823f5539ffa5fSteve Naroff
19773322924127c873c13101b705dd823f5539ffa5fSteve Naroff    if (action == CONTINUE_PROCESSING) {
19873322924127c873c13101b705dd823f5539ffa5fSteve Naroff      // If the delegate is not interested in handling the raw response data,
199213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman      // we assume that a JSON response is expected. If we do not get a JSON
200213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman      // response, we will retry (to handle the case where we got redirected
201213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman      // to a non-cloudprint-server URL eg. for authentication).
202213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman      bool succeeded = false;
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      scoped_ptr<DictionaryValue> response_dict =
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          ParseResponseJSON(data, &succeeded);
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      if (response_dict) {
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        action = delegate_->HandleJSONData(source,
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                           source->GetURL(),
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                           response_dict.get(),
21086da77fdaf4c0237eafb9670f54eee20b08635bfEli Friedman                                           succeeded);
2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      } else {
2122ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor        action = RETRY_REQUEST;
2132ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor      }
2142ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor    }
2154b7c98378ae0c1a3635f0b7756848b4a9923f8bcTed Kremenek  }
2162ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor  // Retry the request if needed.
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (action == RETRY_REQUEST) {
2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Explicitly call ReceivedContentWasMalformed() to ensure the current
2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // request gets counted as a failure for calculation of the back-off
220a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    // period.  If it was already a failure by status code, this call will
2214b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian    // be ignored.
222a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    request_->ReceivedContentWasMalformed();
223a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek
2244b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian    // If we receive error code from the server "Media Type Not Supported",
225a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    // there is no reason to retry, request will never succeed.
226a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek    // In that case we should call OnRequestGiveUp() right away.
227c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian    if (source->GetResponseCode() == net::HTTP_UNSUPPORTED_MEDIA_TYPE)
228a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      num_retries_ = source->GetMaxRetriesOn5xx();
229c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian
23062f5f7ffad57e0c2af2b308af3735351505937cbChris Lattner    ++num_retries_;
231c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian    if ((-1 != source->GetMaxRetriesOn5xx()) &&
232c569249ca0ab755ac79d8cbbfcb2bcae19743624Fariborz Jahanian        (num_retries_ > source->GetMaxRetriesOn5xx())) {
2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // Retry limit reached. Give up.
234d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff      delegate_->OnRequestGiveUp();
2358d1a3b8ca1e5fcc4567b5a6f51d82be2e460de1cSteve Naroff      action = STOP_PROCESSING;
236d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff    } else {
237d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff      // Either no retry limit specified or retry limit has not yet been
2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // reached. Try again. Set up the request headers again because the token
2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // may have changed.
2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SetupRequestHeaders();
2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      request_->SetRequestContext(GetRequestContextGetter());
2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      start_time_ = base::Time::Now();
2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      request_->Start();
2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
245fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman  }
24655f4b02bc71e7347986c6a5249bef635aac1901aArgyrios Kyrtzidis  if (action != RETRY_REQUEST) {
247fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman    ReportRetriesCount(type_, num_retries_);
24855f4b02bc71e7347986c6a5249bef635aac1901aArgyrios Kyrtzidis  }
24964c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis}
25064c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis
25164c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidisvoid CloudPrintURLFetcher::StartRequestHelper(
25264c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis    RequestType type,
25364c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis    const GURL& url,
25464c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis    net::URLFetcher::RequestType request_type,
25564c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis    Delegate* delegate,
25664c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis    int max_retries,
2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const std::string& post_data_mime_type,
2588b9023ba35a86838789e2c9034a6128728c547aaChris Lattner    const std::string& post_data,
2598b9023ba35a86838789e2c9034a6128728c547aaChris Lattner    const std::string& additional_headers) {
2608b9023ba35a86838789e2c9034a6128728c547aaChris Lattner  DCHECK(delegate);
2618b9023ba35a86838789e2c9034a6128728c547aaChris Lattner  type_ = type;
262beaf299a2701c5559a4e5d76b0c40f805afb8e6aSteve Naroff  UMA_HISTOGRAM_ENUMERATION("CloudPrint.UrlFetcherRequestType", type,
263beaf299a2701c5559a4e5d76b0c40f805afb8e6aSteve Naroff                            REQUEST_MAX);
26471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson  // Persist the additional headers in case we need to retry the request.
26571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson  additional_headers_ = additional_headers;
266983df5b2280980e59b0b062bcc2882230465a61eSteve Naroff  request_.reset(net::URLFetcher::Create(0, url, request_type, this));
267a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  request_->SetRequestContext(GetRequestContextGetter());
268a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  // Since we implement our own retry logic, disable the retry in URLFetcher.
269a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  request_->SetAutomaticallyRetryOn5xx(false);
2702198891824c38d45b2279de5d5e3ef9394eb457cSteve Naroff  request_->SetMaxRetriesOn5xx(max_retries);
271b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian  delegate_ = delegate;
272bd4c1ada2e8668f43a865dc2c662085cf61940c4Anders Carlsson  SetupRequestHeaders();
273bd4c1ada2e8668f43a865dc2c662085cf61940c4Anders Carlsson  request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
274bd4c1ada2e8668f43a865dc2c662085cf61940c4Anders Carlsson                         net::LOAD_DO_NOT_SAVE_COOKIES);
275d96b35bc6becf8db00d140c11e3d0e53f27567a1Daniel Dunbar  if (request_type == net::URLFetcher::POST) {
276d96b35bc6becf8db00d140c11e3d0e53f27567a1Daniel Dunbar    request_->SetUploadData(post_data_mime_type, post_data);
277d96b35bc6becf8db00d140c11e3d0e53f27567a1Daniel Dunbar    ReportUploadSize(type_, post_data.size());
2787d6b46d9a9d75dea8ef9f6973dd50633c1f37963Fariborz Jahanian  }
279d96b35bc6becf8db00d140c11e3d0e53f27567a1Daniel Dunbar  start_time_ = base::Time::Now();
28033e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  request_->Start();
281ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian}
282a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek
283ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanianvoid CloudPrintURLFetcher::SetupRequestHeaders() {
284ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian  std::string headers = delegate_->GetAuthHeader();
285a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  if (!headers.empty())
28633e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian    headers += "\r\n";
287c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  headers += kChromeCloudPrintProxyHeader;
288c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  if (!additional_headers_.empty()) {
289c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar    headers += "\r\n";
290c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar    headers += additional_headers_;
291c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  }
292c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar  request_->SetExtraRequestHeaders(headers);
29377a49f6b1e5741f6bda71eb7837b43343925027bArgyrios Kyrtzidis}
294c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar
295c56f34a1c1779de15330bdb3eec39b3418802d47Daniel DunbarCloudPrintURLFetcher::~CloudPrintURLFetcher() {}
29633e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
297a526c5c67e5a0473c340903ee542ce570119665fTed Kremeneknet::URLRequestContextGetter* CloudPrintURLFetcher::GetRequestContextGetter() {
29833e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  ServiceURLRequestContextGetter* getter =
299a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      g_service_process->GetServiceURLRequestContextGetter();
30085f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson  // Now set up the user agent for cloudprint.
301d85376aa66bc16488539f6bb11f97d0170b1fe6bChris Lattner  std::string user_agent = getter->user_agent();
302d85376aa66bc16488539f6bb11f97d0170b1fe6bChris Lattner  base::StringAppendF(&user_agent, " %s", kCloudPrintUserAgent);
303a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  getter->set_user_agent(user_agent);
304d85376aa66bc16488539f6bb11f97d0170b1fe6bChris Lattner  return getter;
305b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian}
306a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek
307a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek}  // namespace cloud_print
308b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian