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