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.
5 #include "net/url_request/test_url_fetcher_factory.h"
10 #include "base/compiler_specific.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "net/base/host_port_pair.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/url_request/url_fetcher_delegate.h"
18 #include "net/url_request/url_fetcher_impl.h"
19 #include "net/url_request/url_fetcher_response_writer.h"
20 #include "net/url_request/url_request_status.h"
24 ScopedURLFetcherFactory::ScopedURLFetcherFactory(
25 URLFetcherFactory
* factory
) {
26 DCHECK(!URLFetcherImpl::factory());
27 URLFetcherImpl::set_factory(factory
);
30 ScopedURLFetcherFactory::~ScopedURLFetcherFactory() {
31 DCHECK(URLFetcherImpl::factory());
32 URLFetcherImpl::set_factory(NULL
);
35 TestURLFetcher::TestURLFetcher(int id
,
37 URLFetcherDelegate
* d
)
42 delegate_for_tests_(NULL
),
43 did_receive_last_chunk_(false),
45 fake_response_code_(-1),
46 fake_response_destination_(STRING
),
47 fake_was_fetched_via_proxy_(false),
48 fake_max_retries_(0) {
51 TestURLFetcher::~TestURLFetcher() {
52 if (delegate_for_tests_
)
53 delegate_for_tests_
->OnRequestEnd(id_
);
55 owner_
->RemoveFetcherFromMap(id_
);
58 void TestURLFetcher::SetUploadData(const std::string
& upload_content_type
,
59 const std::string
& upload_content
) {
60 upload_data_
= upload_content
;
63 void TestURLFetcher::SetUploadFilePath(
64 const std::string
& upload_content_type
,
65 const base::FilePath
& file_path
,
68 scoped_refptr
<base::TaskRunner
> file_task_runner
) {
69 upload_file_path_
= file_path
;
72 void TestURLFetcher::SetChunkedUpload(const std::string
& upload_content_type
) {
75 void TestURLFetcher::AppendChunkToUpload(const std::string
& data
,
77 DCHECK(!did_receive_last_chunk_
);
78 did_receive_last_chunk_
= is_last_chunk
;
79 chunks_
.push_back(data
);
80 if (delegate_for_tests_
)
81 delegate_for_tests_
->OnChunkUpload(id_
);
84 void TestURLFetcher::SetLoadFlags(int load_flags
) {
85 fake_load_flags_
= load_flags
;
88 int TestURLFetcher::GetLoadFlags() const {
89 return fake_load_flags_
;
92 void TestURLFetcher::SetReferrer(const std::string
& referrer
) {
95 void TestURLFetcher::SetReferrerPolicy(
96 URLRequest::ReferrerPolicy referrer_policy
) {
99 void TestURLFetcher::SetExtraRequestHeaders(
100 const std::string
& extra_request_headers
) {
101 fake_extra_request_headers_
.Clear();
102 fake_extra_request_headers_
.AddHeadersFromString(extra_request_headers
);
105 void TestURLFetcher::AddExtraRequestHeader(const std::string
& header_line
) {
106 fake_extra_request_headers_
.AddHeaderFromString(header_line
);
109 void TestURLFetcher::SetRequestContext(
110 URLRequestContextGetter
* request_context_getter
) {
113 void TestURLFetcher::SetFirstPartyForCookies(
114 const GURL
& first_party_for_cookies
) {
117 void TestURLFetcher::SetURLRequestUserData(
119 const CreateDataCallback
& create_data_callback
) {
122 void TestURLFetcher::SetStopOnRedirect(bool stop_on_redirect
) {
125 void TestURLFetcher::SetAutomaticallyRetryOn5xx(bool retry
) {
128 void TestURLFetcher::SetMaxRetriesOn5xx(int max_retries
) {
129 fake_max_retries_
= max_retries
;
132 int TestURLFetcher::GetMaxRetriesOn5xx() const {
133 return fake_max_retries_
;
136 base::TimeDelta
TestURLFetcher::GetBackoffDelay() const {
137 return fake_backoff_delay_
;
140 void TestURLFetcher::SetAutomaticallyRetryOnNetworkChanges(int max_retries
) {
143 void TestURLFetcher::SaveResponseToFileAtPath(
144 const base::FilePath
& file_path
,
145 scoped_refptr
<base::SequencedTaskRunner
> file_task_runner
) {
148 void TestURLFetcher::SaveResponseToTemporaryFile(
149 scoped_refptr
<base::SequencedTaskRunner
> file_task_runner
) {
152 void TestURLFetcher::SaveResponseWithWriter(
153 scoped_ptr
<URLFetcherResponseWriter
> response_writer
) {
154 if (fake_response_destination_
== STRING
) {
155 response_writer_
= response_writer
.Pass();
156 int response
= response_writer_
->Initialize(CompletionCallback());
157 // The TestURLFetcher doesn't handle asynchronous writes.
158 DCHECK_EQ(OK
, response
);
160 scoped_refptr
<IOBuffer
> buffer(new StringIOBuffer(fake_response_string_
));
161 response
= response_writer_
->Write(buffer
.get(),
162 fake_response_string_
.size(),
163 CompletionCallback());
164 DCHECK_EQ(static_cast<int>(fake_response_string_
.size()), response
);
165 response
= response_writer_
->Finish(CompletionCallback());
166 DCHECK_EQ(OK
, response
);
172 HttpResponseHeaders
* TestURLFetcher::GetResponseHeaders() const {
173 return fake_response_headers_
.get();
176 HostPortPair
TestURLFetcher::GetSocketAddress() const {
178 return HostPortPair();
181 bool TestURLFetcher::WasFetchedViaProxy() const {
182 return fake_was_fetched_via_proxy_
;
185 void TestURLFetcher::Start() {
186 // Overriden to do nothing. It is assumed the caller will notify the delegate.
187 if (delegate_for_tests_
)
188 delegate_for_tests_
->OnRequestStart(id_
);
191 const GURL
& TestURLFetcher::GetOriginalURL() const {
192 return original_url_
;
195 const GURL
& TestURLFetcher::GetURL() const {
199 const URLRequestStatus
& TestURLFetcher::GetStatus() const {
203 int TestURLFetcher::GetResponseCode() const {
204 return fake_response_code_
;
207 const ResponseCookies
& TestURLFetcher::GetCookies() const {
208 return fake_cookies_
;
211 void TestURLFetcher::ReceivedContentWasMalformed() {
214 bool TestURLFetcher::GetResponseAsString(
215 std::string
* out_response_string
) const {
216 if (fake_response_destination_
!= STRING
)
219 *out_response_string
= fake_response_string_
;
223 bool TestURLFetcher::GetResponseAsFilePath(
224 bool take_ownership
, base::FilePath
* out_response_path
) const {
225 if (fake_response_destination_
!= TEMP_FILE
)
228 *out_response_path
= fake_response_file_path_
;
232 void TestURLFetcher::GetExtraRequestHeaders(
233 HttpRequestHeaders
* headers
) const {
234 *headers
= fake_extra_request_headers_
;
237 void TestURLFetcher::set_status(const URLRequestStatus
& status
) {
238 fake_status_
= status
;
241 void TestURLFetcher::set_was_fetched_via_proxy(bool flag
) {
242 fake_was_fetched_via_proxy_
= flag
;
245 void TestURLFetcher::set_response_headers(
246 scoped_refptr
<HttpResponseHeaders
> headers
) {
247 fake_response_headers_
= headers
;
250 void TestURLFetcher::set_backoff_delay(base::TimeDelta backoff_delay
) {
251 fake_backoff_delay_
= backoff_delay
;
254 void TestURLFetcher::SetDelegateForTests(DelegateForTests
* delegate_for_tests
) {
255 delegate_for_tests_
= delegate_for_tests
;
258 void TestURLFetcher::SetResponseString(const std::string
& response
) {
259 fake_response_destination_
= STRING
;
260 fake_response_string_
= response
;
263 void TestURLFetcher::SetResponseFilePath(const base::FilePath
& path
) {
264 fake_response_destination_
= TEMP_FILE
;
265 fake_response_file_path_
= path
;
268 TestURLFetcherFactory::TestURLFetcherFactory()
269 : ScopedURLFetcherFactory(this),
270 delegate_for_tests_(NULL
),
271 remove_fetcher_on_delete_(false) {
274 TestURLFetcherFactory::~TestURLFetcherFactory() {}
276 URLFetcher
* TestURLFetcherFactory::CreateURLFetcher(
279 URLFetcher::RequestType request_type
,
280 URLFetcherDelegate
* d
) {
281 TestURLFetcher
* fetcher
= new TestURLFetcher(id
, url
, d
);
282 if (remove_fetcher_on_delete_
)
283 fetcher
->set_owner(this);
284 fetcher
->SetDelegateForTests(delegate_for_tests_
);
285 fetchers_
[id
] = fetcher
;
289 TestURLFetcher
* TestURLFetcherFactory::GetFetcherByID(int id
) const {
290 Fetchers::const_iterator i
= fetchers_
.find(id
);
291 return i
== fetchers_
.end() ? NULL
: i
->second
;
294 void TestURLFetcherFactory::RemoveFetcherFromMap(int id
) {
295 Fetchers::iterator i
= fetchers_
.find(id
);
296 DCHECK(i
!= fetchers_
.end());
300 void TestURLFetcherFactory::SetDelegateForTests(
301 TestURLFetcherDelegateForTests
* delegate_for_tests
) {
302 delegate_for_tests_
= delegate_for_tests
;
305 FakeURLFetcher::FakeURLFetcher(const GURL
& url
,
306 URLFetcherDelegate
* d
,
307 const std::string
& response_data
,
308 HttpStatusCode response_code
,
309 URLRequestStatus::Status status
)
310 : TestURLFetcher(0, url
, d
),
311 weak_factory_(this) {
314 case URLRequestStatus::SUCCESS
:
315 // |error| is initialized to OK.
317 case URLRequestStatus::IO_PENDING
:
318 error
= ERR_IO_PENDING
;
320 case URLRequestStatus::CANCELED
:
323 case URLRequestStatus::FAILED
:
327 set_status(URLRequestStatus(status
, error
));
328 set_response_code(response_code
);
329 SetResponseString(response_data
);
332 FakeURLFetcher::~FakeURLFetcher() {}
334 void FakeURLFetcher::Start() {
335 base::MessageLoop::current()->PostTask(
337 base::Bind(&FakeURLFetcher::RunDelegate
, weak_factory_
.GetWeakPtr()));
340 void FakeURLFetcher::RunDelegate() {
341 delegate()->OnURLFetchComplete(this);
344 const GURL
& FakeURLFetcher::GetURL() const {
345 return TestURLFetcher::GetOriginalURL();
348 FakeURLFetcherFactory::FakeURLFetcherFactory(
349 URLFetcherFactory
* default_factory
)
350 : ScopedURLFetcherFactory(this),
351 creator_(base::Bind(&DefaultFakeURLFetcherCreator
)),
352 default_factory_(default_factory
) {
355 FakeURLFetcherFactory::FakeURLFetcherFactory(
356 URLFetcherFactory
* default_factory
,
357 const FakeURLFetcherCreator
& creator
)
358 : ScopedURLFetcherFactory(this),
360 default_factory_(default_factory
) {
363 scoped_ptr
<FakeURLFetcher
> FakeURLFetcherFactory::DefaultFakeURLFetcherCreator(
365 URLFetcherDelegate
* delegate
,
366 const std::string
& response_data
,
367 HttpStatusCode response_code
,
368 URLRequestStatus::Status status
) {
369 return scoped_ptr
<FakeURLFetcher
>(
370 new FakeURLFetcher(url
, delegate
, response_data
, response_code
, status
));
373 FakeURLFetcherFactory::~FakeURLFetcherFactory() {}
375 URLFetcher
* FakeURLFetcherFactory::CreateURLFetcher(
378 URLFetcher::RequestType request_type
,
379 URLFetcherDelegate
* d
) {
380 FakeResponseMap::const_iterator it
= fake_responses_
.find(url
);
381 if (it
== fake_responses_
.end()) {
382 if (default_factory_
== NULL
) {
383 // If we don't have a baked response for that URL we return NULL.
384 DLOG(ERROR
) << "No baked response for URL: " << url
.spec();
387 return default_factory_
->CreateURLFetcher(id
, url
, request_type
, d
);
391 scoped_ptr
<FakeURLFetcher
> fake_fetcher
=
392 creator_
.Run(url
, d
, it
->second
.response_data
,
393 it
->second
.response_code
, it
->second
.status
);
394 // TODO: Make URLFetcherFactory::CreateURLFetcher return a scoped_ptr
395 return fake_fetcher
.release();
398 void FakeURLFetcherFactory::SetFakeResponse(
400 const std::string
& response_data
,
401 HttpStatusCode response_code
,
402 URLRequestStatus::Status status
) {
403 // Overwrite existing URL if it already exists.
404 FakeURLResponse response
;
405 response
.response_data
= response_data
;
406 response
.response_code
= response_code
;
407 response
.status
= status
;
408 fake_responses_
[url
] = response
;
411 void FakeURLFetcherFactory::ClearFakeResponses() {
412 fake_responses_
.clear();
415 URLFetcherImplFactory::URLFetcherImplFactory() {}
417 URLFetcherImplFactory::~URLFetcherImplFactory() {}
419 URLFetcher
* URLFetcherImplFactory::CreateURLFetcher(
422 URLFetcher::RequestType request_type
,
423 URLFetcherDelegate
* d
) {
424 return new URLFetcherImpl(url
, request_type
, d
);