Home | History | Annotate | Download | only in cloud_print
      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).
    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:
    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