1 // Copyright (c) 2011 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 // This file contains URLFetcher, a wrapper around net::URLRequest that handles 6 // low-level details like thread safety, ref counting, and incremental buffer 7 // reading. This is useful for callers who simply want to get the data from a 8 // URL and don't care about all the nitty-gritty details. 9 // 10 // NOTE(willchan): Only one "IO" thread is supported for URLFetcher. This is a 11 // temporary situation. We will work on allowing support for multiple "io" 12 // threads per process. 13 14 #ifndef CHROME_COMMON_NET_URL_FETCHER_H_ 15 #define CHROME_COMMON_NET_URL_FETCHER_H_ 16 #pragma once 17 18 #include <string> 19 #include <vector> 20 21 #include "base/memory/ref_counted.h" 22 #include "base/message_loop.h" 23 #include "base/time.h" 24 25 class GURL; 26 typedef std::vector<std::string> ResponseCookies; 27 28 namespace net { 29 class HttpResponseHeaders; 30 class URLRequestContextGetter; 31 class URLRequestStatus; 32 } // namespace net 33 34 // To use this class, create an instance with the desired URL and a pointer to 35 // the object to be notified when the URL has been loaded: 36 // URLFetcher* fetcher = new URLFetcher("http://www.google.com", 37 // URLFetcher::GET, this); 38 // 39 // Then, optionally set properties on this object, like the request context or 40 // extra headers: 41 // fetcher->SetExtraRequestHeaders("X-Foo: bar"); 42 // 43 // Finally, start the request: 44 // fetcher->Start(); 45 // 46 // The object you supply as a delegate must inherit from URLFetcher::Delegate; 47 // when the fetch is completed, OnURLFetchComplete() will be called with the 48 // resulting status and (if applicable) HTTP response code. From that point 49 // until the original URLFetcher instance is destroyed, you may examine the 50 // provided status and data for the URL. (You should copy these objects if you 51 // need them to live longer than the URLFetcher instance.) If the URLFetcher 52 // instance is destroyed before the callback happens, the fetch will be 53 // canceled and no callback will occur. 54 // 55 // You may create the URLFetcher instance on any thread; OnURLFetchComplete() 56 // will be called back on the same thread you use to create the instance. 57 // 58 // 59 // NOTE: By default URLFetcher requests are NOT intercepted, except when 60 // interception is explicitly enabled in tests. 61 62 class URLFetcher { 63 public: 64 enum RequestType { 65 GET, 66 POST, 67 HEAD, 68 }; 69 70 class Delegate { 71 public: 72 // This will be called when the URL has been fetched, successfully or not. 73 // |response_code| is the HTTP response code (200, 404, etc.) if 74 // applicable. |url|, |status| and |data| are all valid until the 75 // URLFetcher instance is destroyed. 76 virtual void OnURLFetchComplete(const URLFetcher* source, 77 const GURL& url, 78 const net::URLRequestStatus& status, 79 int response_code, 80 const ResponseCookies& cookies, 81 const std::string& data) = 0; 82 83 protected: ~Delegate()84 virtual ~Delegate() {} 85 }; 86 87 // URLFetcher::Create uses the currently registered Factory to create the 88 // URLFetcher. Factory is intended for testing. 89 class Factory { 90 public: 91 virtual URLFetcher* CreateURLFetcher(int id, 92 const GURL& url, 93 RequestType request_type, 94 Delegate* d) = 0; 95 96 protected: ~Factory()97 virtual ~Factory() {} 98 }; 99 100 // |url| is the URL to send the request to. 101 // |request_type| is the type of request to make. 102 // |d| the object that will receive the callback on fetch completion. 103 URLFetcher(const GURL& url, RequestType request_type, Delegate* d); 104 105 virtual ~URLFetcher(); 106 107 // Sets the factory used by the static method Create to create a URLFetcher. 108 // URLFetcher does not take ownership of |factory|. A value of NULL results 109 // in a URLFetcher being created directly. 110 #if defined(UNIT_TEST) set_factory(Factory * factory)111 static void set_factory(Factory* factory) { factory_ = factory; } 112 #endif 113 114 // Normally interception is disabled for URLFetcher, but you can use this 115 // to enable it for tests. Also see the set_factory method for another way 116 // of testing code that uses an URLFetcher. enable_interception_for_tests(bool enabled)117 static void enable_interception_for_tests(bool enabled) { 118 g_interception_enabled = enabled; 119 } 120 121 // Creates a URLFetcher, ownership returns to the caller. If there is no 122 // Factory (the default) this creates and returns a new URLFetcher. See the 123 // constructor for a description of the args. |id| may be used during testing 124 // to identify who is creating the URLFetcher. 125 static URLFetcher* Create(int id, const GURL& url, RequestType request_type, 126 Delegate* d); 127 128 // Sets data only needed by POSTs. All callers making POST requests should 129 // call this before the request is started. |upload_content_type| is the MIME 130 // type of the content, while |upload_content| is the data to be sent (the 131 // Content-Length header value will be set to the length of this data). 132 #ifdef ANDROID 133 // TODO: Upstream. 134 virtual 135 #endif 136 void set_upload_data(const std::string& upload_content_type, 137 const std::string& upload_content); 138 139 // Indicates that the POST data is sent via chunked transfer encoding. 140 // This may only be called before calling Start(). 141 // Use AppendChunkToUpload() to give the data chunks after calling Start(). 142 void set_chunked_upload(const std::string& upload_content_type); 143 144 // Adds the given bytes to a request's POST data transmitted using chunked 145 // transfer encoding. 146 // This method should be called ONLY after calling Start(). 147 virtual void AppendChunkToUpload(const std::string& data, bool is_last_chunk); 148 149 // Set one or more load flags as defined in net/base/load_flags.h. Must be 150 // called before the request is started. 151 void set_load_flags(int load_flags); 152 153 // Returns the current load flags. 154 int load_flags() const; 155 156 // The referrer URL for the request. Must be called before the request is 157 // started. 158 void set_referrer(const std::string& referrer); 159 160 // Set extra headers on the request. Must be called before the request 161 // is started. 162 void set_extra_request_headers(const std::string& extra_request_headers); 163 164 // Set the net::URLRequestContext on the request. Must be called before the 165 // request is started. 166 #ifdef ANDROID 167 // TODO: Upstream. 168 virtual 169 #endif 170 void set_request_context( 171 net::URLRequestContextGetter* request_context_getter); 172 173 #ifdef ANDROID 174 net::URLRequestContextGetter* request_context(); 175 #endif 176 177 // If |retry| is false, 5xx responses will be propagated to the observer, 178 // if it is true URLFetcher will automatically re-execute the request, 179 // after backoff_delay() elapses. URLFetcher has it set to true by default. 180 #ifdef ANDROID 181 // TODO: Upstream. 182 virtual 183 #endif 184 void set_automatically_retry_on_5xx(bool retry); 185 max_retries()186 int max_retries() const { return max_retries_; } 187 set_max_retries(int max_retries)188 void set_max_retries(int max_retries) { max_retries_ = max_retries; } 189 190 // Returns the back-off delay before the request will be retried, 191 // when a 5xx response was received. backoff_delay()192 base::TimeDelta backoff_delay() const { return backoff_delay_; } 193 194 // Sets the back-off delay, allowing to mock 5xx requests in unit-tests. 195 #if defined(UNIT_TEST) set_backoff_delay(base::TimeDelta backoff_delay)196 void set_backoff_delay(base::TimeDelta backoff_delay) { 197 backoff_delay_ = backoff_delay; 198 } 199 #endif // defined(UNIT_TEST) 200 201 // Retrieve the response headers from the request. Must only be called after 202 // the OnURLFetchComplete callback has run. 203 virtual net::HttpResponseHeaders* response_headers() const; 204 205 // Start the request. After this is called, you may not change any other 206 // settings. 207 virtual void Start(); 208 209 // Return the URL that this fetcher is processing. 210 const GURL& url() const; 211 212 // Reports that the received content was malformed. 213 void ReceivedContentWasMalformed(); 214 215 // Cancels all existing URLFetchers. Will notify the URLFetcher::Delegates. 216 // Note that any new URLFetchers created while this is running will not be 217 // cancelled. Typically, one would call this in the CleanUp() method of an IO 218 // thread, so that no new URLRequests would be able to start on the IO thread 219 // anyway. This doesn't prevent new URLFetchers from trying to post to the IO 220 // thread though, even though the task won't ever run. 221 static void CancelAll(); 222 223 protected: 224 // Returns the delegate. 225 Delegate* delegate() const; 226 227 // Used by tests. 228 const std::string& upload_data() const; 229 230 private: 231 friend class URLFetcherTest; 232 233 // Only used by URLFetcherTest, returns the number of URLFetcher::Core objects 234 // actively running. 235 static int GetNumFetcherCores(); 236 237 class Core; 238 239 scoped_refptr<Core> core_; 240 241 static Factory* factory_; 242 243 // If |automatically_retry_on_5xx_| is false, 5xx responses will be 244 // propagated to the observer, if it is true URLFetcher will automatically 245 // re-execute the request, after the back-off delay has expired. 246 // true by default. 247 bool automatically_retry_on_5xx_; 248 // Back-off time delay. 0 by default. 249 base::TimeDelta backoff_delay_; 250 // Maximum retries allowed. 251 int max_retries_; 252 253 static bool g_interception_enabled; 254 255 DISALLOW_COPY_AND_ASSIGN(URLFetcher); 256 }; 257 258 #endif // CHROME_COMMON_NET_URL_FETCHER_H_ 259