summaryrefslogtreecommitdiffstats
path: root/chrome/service/cloud_print/cloud_print_url_fetcher.h
blob: 397716024b3a4b66533de553270dc1d2c5dae5df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_URL_FETCHER_H_
#define CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_URL_FETCHER_H_

#include <string>

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"

class GURL;

namespace base {
class DictionaryValue;
}

namespace net {
class URLRequestContextGetter;
class URLRequestStatus;
}  // namespace net

namespace cloud_print {

// Factory for creating CloudPrintURLFetchers.
class CloudPrintURLFetcher;
class CloudPrintURLFetcherFactory {
 public:
  virtual CloudPrintURLFetcher* CreateCloudPrintURLFetcher() = 0;
  virtual ~CloudPrintURLFetcherFactory();
};

// A wrapper around URLFetcher for CloudPrint. URLFetcher applies retry logic
// only on HTTP response codes >= 500. In the cloud print case, we want to
// retry on all network errors. In addition, we want to treat non-JSON responses
// (for all CloudPrint APIs that expect JSON responses) as errors and they
// must also be retried.
class CloudPrintURLFetcher
    : public base::RefCountedThreadSafe<CloudPrintURLFetcher>,
      public net::URLFetcherDelegate {
 public:
  enum ResponseAction {
    CONTINUE_PROCESSING,
    STOP_PROCESSING,
    RETRY_REQUEST,
  };

  class Delegate {
   public:
    // Override this to handle the raw response as it is available. No response
    // error checking is done before this method is called. If the delegate
    // returns CONTINUE_PROCESSING, we will then check for network
    // errors. Most implementations will not override this.
    virtual ResponseAction HandleRawResponse(
        const net::URLFetcher* source,
        const GURL& url,
        const net::URLRequestStatus& status,
        int response_code,
        const net::ResponseCookies& cookies,
        const std::string& data);

    // This will be invoked only if HandleRawResponse returns
    // CONTINUE_PROCESSING AND if there are no network errors and the HTTP
    // response code is 200. The delegate implementation returns
    // CONTINUE_PROCESSING if it does not want to handle the raw data itself.
    // Handling the raw data is needed when the expected response is NOT JSON
    // (like in the case of a print ticket response or a print job download
    // response).
    virtual ResponseAction HandleRawData(const net::URLFetcher* source,
                                         const GURL& url,
                                         const std::string& data);

    // This will be invoked only if HandleRawResponse and HandleRawData return
    // CONTINUE_PROCESSING AND if the response contains a valid JSON dictionary.
    // |succeeded| is the value of the "success" field in the response JSON.
    virtual ResponseAction HandleJSONData(const net::URLFetcher* source,
                                          const GURL& url,
                                          base::DictionaryValue* json_data,
                                          bool succeeded);

    // Invoked when the retry limit for this request has been reached (if there
    // was a retry limit - a limit of -1 implies no limit).
    virtual void OnRequestGiveUp() { }

    // Invoked when the request returns a 403 error (applicable only when
    // HandleRawResponse returns CONTINUE_PROCESSING).
    // Returning RETRY_REQUEST will retry current request. (auth information
    // may have been updated and new info is available through the
    // Authenticator interface).
    // Returning CONTINUE_PROCESSING will treat auth error as a network error.
    virtual ResponseAction OnRequestAuthError() = 0;

    // Authentication information may change between retries.
    // CloudPrintURLFetcher will request auth info before sending any request.
    virtual std::string GetAuthHeader() = 0;

   protected:
    virtual ~Delegate() {}
  };

  static CloudPrintURLFetcher* Create();
  static void set_factory(CloudPrintURLFetcherFactory* factory);

  bool IsSameRequest(const net::URLFetcher* source);

  void StartGetRequest(const GURL& url,
                       Delegate* delegate,
                       int max_retries,
                       const std::string& additional_headers);
  void StartPostRequest(const GURL& url,
                        Delegate* delegate,
                        int max_retries,
                        const std::string& post_data_mime_type,
                        const std::string& post_data,
                        const std::string& additional_headers);

  // net::URLFetcherDelegate implementation.
  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;

 protected:
  CloudPrintURLFetcher();
  friend class base::RefCountedThreadSafe<CloudPrintURLFetcher>;
  virtual ~CloudPrintURLFetcher();

  // Virtual for testing.
  virtual net::URLRequestContextGetter* GetRequestContextGetter();

 private:
  void StartRequestHelper(const GURL& url,
                          net::URLFetcher::RequestType request_type,
                          Delegate* delegate,
                          int max_retries,
                          const std::string& post_data_mime_type,
                          const std::string& post_data,
                          const std::string& additional_headers);
  void SetupRequestHeaders();
  static CloudPrintURLFetcherFactory* factory();

  scoped_ptr<net::URLFetcher> request_;
  Delegate* delegate_;
  int num_retries_;
  net::URLFetcher::RequestType request_type_;
  std::string additional_headers_;
  std::string post_data_mime_type_;
  std::string post_data_;
};

typedef CloudPrintURLFetcher::Delegate CloudPrintURLFetcherDelegate;

}  // namespace cloud_print

#endif  // CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_URL_FETCHER_H_