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