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