• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_URL_FETCHER_H_
6 #define CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_URL_FETCHER_H_
7 
8 #include <string>
9 
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/time/time.h"
13 #include "net/url_request/url_fetcher.h"
14 #include "net/url_request/url_fetcher_delegate.h"
15 
16 class GURL;
17 
18 namespace base {
19 class DictionaryValue;
20 }
21 
22 namespace net {
23 class URLRequestContextGetter;
24 class URLRequestStatus;
25 }  // namespace net
26 
27 namespace cloud_print {
28 
29 // Factory for creating CloudPrintURLFetchers.
30 class CloudPrintURLFetcher;
31 class CloudPrintURLFetcherFactory {
32  public:
33   virtual CloudPrintURLFetcher* CreateCloudPrintURLFetcher() = 0;
34   virtual ~CloudPrintURLFetcherFactory();
35 };
36 
37 // A wrapper around URLFetcher for CloudPrint. URLFetcher applies retry logic
38 // only on HTTP response codes >= 500. In the cloud print case, we want to
39 // retry on all network errors. In addition, we want to treat non-JSON responses
40 // (for all CloudPrint APIs that expect JSON responses) as errors and they
41 // must also be retried.
42 class CloudPrintURLFetcher
43     : public base::RefCountedThreadSafe<CloudPrintURLFetcher>,
44       public net::URLFetcherDelegate {
45  public:
46   enum ResponseAction {
47     CONTINUE_PROCESSING,
48     STOP_PROCESSING,
49     RETRY_REQUEST,
50   };
51 
52   enum RequestType {
53     REQUEST_AUTH_CODE,
54     REQUEST_REGISTER,
55     REQUEST_UNREGISTER,
56     REQUEST_UPDATE_PRINTER,
57     REQUEST_UPDATE_JOB,
58     REQUEST_USER_MESSAGE,
59     REQUEST_TICKET,
60     REQUEST_DATA,
61     REQUEST_JOB_FETCH,
62     REQUEST_MAX,
63   };
64 
65   class Delegate {
66    public:
67     // Override this to handle the raw response as it is available. No response
68     // error checking is done before this method is called. If the delegate
69     // returns CONTINUE_PROCESSING, we will then check for network
70     // errors. Most implementations will not override this.
71     virtual ResponseAction HandleRawResponse(
72         const net::URLFetcher* source,
73         const GURL& url,
74         const net::URLRequestStatus& status,
75         int response_code,
76         const net::ResponseCookies& cookies,
77         const std::string& data);
78 
79     // This will be invoked only if HandleRawResponse returns
80     // CONTINUE_PROCESSING AND if there are no network errors and the HTTP
81     // response code is 200. The delegate implementation returns
82     // CONTINUE_PROCESSING if it does not want to handle the raw data itself.
83     // Handling the raw data is needed when the expected response is NOT JSON
84     // (like in the case of a print ticket response or a print job download
85     // response).
86     virtual ResponseAction HandleRawData(const net::URLFetcher* source,
87                                          const GURL& url,
88                                          const std::string& data);
89 
90     // This will be invoked only if HandleRawResponse and HandleRawData return
91     // CONTINUE_PROCESSING AND if the response contains a valid JSON dictionary.
92     // |succeeded| is the value of the "success" field in the response JSON.
93     virtual ResponseAction HandleJSONData(const net::URLFetcher* source,
94                                           const GURL& url,
95                                           base::DictionaryValue* json_data,
96                                           bool succeeded);
97 
98     // Invoked when the retry limit for this request has been reached (if there
99     // was a retry limit - a limit of -1 implies no limit).
OnRequestGiveUp()100     virtual void OnRequestGiveUp() { }
101 
102     // Invoked when the request returns a 403 error (applicable only when
103     // HandleRawResponse returns CONTINUE_PROCESSING).
104     // Returning RETRY_REQUEST will retry current request. (auth information
105     // may have been updated and new info is available through the
106     // Authenticator interface).
107     // Returning CONTINUE_PROCESSING will treat auth error as a network error.
108     virtual ResponseAction OnRequestAuthError() = 0;
109 
110     // Authentication information may change between retries.
111     // CloudPrintURLFetcher will request auth info before sending any request.
112     virtual std::string GetAuthHeader() = 0;
113 
114    protected:
~Delegate()115     virtual ~Delegate() {}
116   };
117 
118   static CloudPrintURLFetcher* Create();
119   static void set_factory(CloudPrintURLFetcherFactory* factory);
120 
121   bool IsSameRequest(const net::URLFetcher* source);
122 
123   void StartGetRequest(RequestType type,
124                        const GURL& url,
125                        Delegate* delegate,
126                        int max_retries,
127                        const std::string& additional_headers);
128   void StartPostRequest(RequestType type,
129                         const GURL& url,
130                         Delegate* delegate,
131                         int max_retries,
132                         const std::string& post_data_mime_type,
133                         const std::string& post_data,
134                         const std::string& additional_headers);
135 
136   // net::URLFetcherDelegate implementation.
137   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
138 
139  protected:
140   CloudPrintURLFetcher();
141   friend class base::RefCountedThreadSafe<CloudPrintURLFetcher>;
142   virtual ~CloudPrintURLFetcher();
143 
144   // Virtual for testing.
145   virtual net::URLRequestContextGetter* GetRequestContextGetter();
146 
147  private:
148   void StartRequestHelper(RequestType type,
149                           const GURL& url,
150                           net::URLFetcher::RequestType request_type,
151                           Delegate* delegate,
152                           int max_retries,
153                           const std::string& post_data_mime_type,
154                           const std::string& post_data,
155                           const std::string& additional_headers);
156   void SetupRequestHeaders();
157   static CloudPrintURLFetcherFactory* factory();
158 
159   scoped_ptr<net::URLFetcher> request_;
160   Delegate* delegate_;
161   int num_retries_;
162   net::URLFetcher::RequestType request_type_;
163   std::string additional_headers_;
164   std::string post_data_mime_type_;
165   std::string post_data_;
166 
167   RequestType type_;
168   base::Time start_time_;
169 };
170 
171 typedef CloudPrintURLFetcher::Delegate CloudPrintURLFetcherDelegate;
172 
173 }  // namespace cloud_print
174 
175 #endif  // CHROME_SERVICE_CLOUD_PRINT_CLOUD_PRINT_URL_FETCHER_H_
176