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