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