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/url_fetcher_impl.h"
10 #include "base/bind.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/macros.h"
14 #include "base/message_loop/message_loop_proxy.h"
15 #include "base/path_service.h"
16 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/synchronization/waitable_event.h"
19 #include "base/threading/thread.h"
20 #include "build/build_config.h"
21 #include "crypto/nss_util.h"
22 #include "net/base/elements_upload_data_stream.h"
23 #include "net/base/network_change_notifier.h"
24 #include "net/base/upload_bytes_element_reader.h"
25 #include "net/base/upload_element_reader.h"
26 #include "net/base/upload_file_element_reader.h"
27 #include "net/dns/mock_host_resolver.h"
28 #include "net/http/http_response_headers.h"
29 #include "net/test/spawned_test_server/spawned_test_server.h"
30 #include "net/url_request/url_fetcher_delegate.h"
31 #include "net/url_request/url_request_context_getter.h"
32 #include "net/url_request/url_request_test_util.h"
33 #include "net/url_request/url_request_throttler_manager.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
37 #include "net/cert_net/nss_ocsp.h"
43 using base::TimeDelta
;
45 // TODO(eroman): Add a regression test for http://crbug.com/40505.
49 // TODO(akalin): Move all the test data to somewhere under net/.
50 const base::FilePath::CharType kDocRoot
[] =
51 FILE_PATH_LITERAL("net/data/url_fetcher_impl_unittest");
52 const char kTestServerFilePrefix
[] = "files/";
54 // Test server path and response body for the default URL used by many of the
56 const char kDefaultResponsePath
[] = "defaultresponse";
57 const char kDefaultResponseBody
[] =
58 "Default response given for path: /defaultresponse";
60 // Request body for streams created by CreateUploadStream.
61 const char kCreateUploadStreamBody
[] = "rosebud";
63 base::FilePath
GetUploadFileTestPath() {
65 PathService::Get(base::DIR_SOURCE_ROOT
, &path
);
67 FILE_PATH_LITERAL("net/data/url_request_unittest/BullRunSpeech.txt"));
70 // Simple URLRequestDelegate that waits for the specified fetcher to complete.
71 // Can only be used once.
72 class WaitingURLFetcherDelegate
: public URLFetcherDelegate
{
74 WaitingURLFetcherDelegate() : did_complete_(false) {}
76 // Creates a URLFetcher that runs network tasks on the current message loop.
77 void CreateFetcherWithContext(const GURL
& url
,
78 URLFetcher::RequestType request_type
,
79 URLRequestContext
* context
) {
80 CreateFetcherWithContextGetter(
81 url
, request_type
, new TrivialURLRequestContextGetter(
82 context
, base::MessageLoopProxy::current()));
85 void CreateFetcherWithContextGetter(const GURL
& url
,
86 URLFetcher::RequestType request_type
,
87 URLRequestContextGetter
* context_getter
) {
88 fetcher_
.reset(new URLFetcherImpl(url
, request_type
, this));
89 fetcher_
->SetRequestContext(context_getter
);
92 URLFetcher
* fetcher() const { return fetcher_
.get(); }
94 // Wait until the request has completed or been canceled.
95 void StartFetcherAndWait() {
100 // Wait until the request has completed or been canceled. Does not start the
102 void WaitForComplete() { run_loop_
.Run(); }
104 // Cancels the fetch by deleting the fetcher.
106 EXPECT_TRUE(fetcher_
);
111 // URLFetcherDelegate:
112 void OnURLFetchComplete(const URLFetcher
* source
) override
{
113 EXPECT_FALSE(did_complete_
);
114 EXPECT_TRUE(fetcher_
);
115 EXPECT_EQ(fetcher_
.get(), source
);
116 did_complete_
= true;
120 void OnURLFetchDownloadProgress(const URLFetcher
* source
,
122 int64 total
) override
{
123 // Note that the current progress may be greater than the previous progress,
124 // in the case of retrying the request.
125 EXPECT_FALSE(did_complete_
);
126 EXPECT_TRUE(fetcher_
);
127 EXPECT_EQ(source
, fetcher_
.get());
129 EXPECT_LE(0, current
);
130 // If file size is not known, |total| is -1.
132 EXPECT_LE(current
, total
);
135 void OnURLFetchUploadProgress(const URLFetcher
* source
,
137 int64 total
) override
{
138 // Note that the current progress may be greater than the previous progress,
139 // in the case of retrying the request.
140 EXPECT_FALSE(did_complete_
);
141 EXPECT_TRUE(fetcher_
);
142 EXPECT_EQ(source
, fetcher_
.get());
144 EXPECT_LE(0, current
);
145 // If file size is not known, |total| is -1.
147 EXPECT_LE(current
, total
);
150 bool did_complete() const { return did_complete_
; }
155 scoped_ptr
<URLFetcherImpl
> fetcher_
;
156 base::RunLoop run_loop_
;
158 DISALLOW_COPY_AND_ASSIGN(WaitingURLFetcherDelegate
);
161 class ThrottlingTestURLRequestContext
: public TestURLRequestContext
{
163 ThrottlingTestURLRequestContext() : TestURLRequestContext(true) {
164 set_throttler_manager(&throttler_manager_
);
166 DCHECK(throttler_manager() != nullptr);
170 URLRequestThrottlerManager throttler_manager_
;
173 class ThrottlingTestURLRequestContextGetter
174 : public TestURLRequestContextGetter
{
176 ThrottlingTestURLRequestContextGetter(
177 base::MessageLoopProxy
* io_message_loop_proxy
,
178 TestURLRequestContext
* request_context
)
179 : TestURLRequestContextGetter(io_message_loop_proxy
),
180 context_(request_context
) {
183 // TestURLRequestContextGetter:
184 TestURLRequestContext
* GetURLRequestContext() override
{ return context_
; }
187 ~ThrottlingTestURLRequestContextGetter() override
{}
189 TestURLRequestContext
* const context_
;
194 class URLFetcherTest
: public testing::Test
,
195 public URLFetcherDelegate
{
198 : io_message_loop_proxy_(base::MessageLoopProxy::current()),
199 num_upload_streams_created_(0),
201 expected_status_code_(200) {}
203 static int GetNumFetcherCores() {
204 return URLFetcherImpl::GetNumFetcherCores();
207 // Creates a URLFetcher, using the program's main thread to do IO.
208 virtual void CreateFetcher(const GURL
& url
);
210 // URLFetcherDelegate:
211 // Subclasses that override this should either call this function or
212 // CleanupAfterFetchComplete() at the end of their processing, depending on
213 // whether they want to check for a non-empty HTTP 200 response or not.
214 void OnURLFetchComplete(const URLFetcher
* source
) override
;
216 // Deletes |fetcher| and terminates the message loop.
217 void CleanupAfterFetchComplete();
219 scoped_refptr
<base::MessageLoopProxy
> io_message_loop_proxy() {
220 return io_message_loop_proxy_
;
223 TestURLRequestContext
* request_context() {
224 return context_
.get();
227 // Callback passed to URLFetcher to create upload stream by some tests.
228 scoped_ptr
<UploadDataStream
> CreateUploadStream() {
229 ++num_upload_streams_created_
;
230 std::vector
<char> buffer(
231 kCreateUploadStreamBody
,
232 kCreateUploadStreamBody
+ strlen(kCreateUploadStreamBody
));
233 return ElementsUploadDataStream::CreateWithReader(
234 scoped_ptr
<UploadElementReader
>(
235 new UploadOwnedBytesElementReader(&buffer
)),
239 // Number of streams created by CreateUploadStream.
240 size_t num_upload_streams_created() const {
241 return num_upload_streams_created_
;
244 // Downloads |file_to_fetch| and checks the contents when done. If
245 // |save_to_temporary_file| is true, saves it to a temporary file, and
246 // |requested_out_path| is ignored. Otherwise, saves it to
247 // |requested_out_path|. Takes ownership of the file if |take_ownership| is
248 // true. Deletes file when done.
249 void SaveFileTest(const char* file_to_fetch
,
250 bool save_to_temporary_file
,
251 const base::FilePath
& requested_out_path
,
252 bool take_ownership
) {
253 scoped_ptr
<WaitingURLFetcherDelegate
> delegate(
254 new WaitingURLFetcherDelegate());
255 delegate
->CreateFetcherWithContext(
256 test_server_
->GetURL(std::string(kTestServerFilePrefix
) +
258 URLFetcher::GET
, request_context());
259 if (save_to_temporary_file
) {
260 delegate
->fetcher()->SaveResponseToTemporaryFile(
261 scoped_refptr
<base::MessageLoopProxy
>(
262 base::MessageLoopProxy::current()));
264 delegate
->fetcher()->SaveResponseToFileAtPath(
265 requested_out_path
, scoped_refptr
<base::MessageLoopProxy
>(
266 base::MessageLoopProxy::current()));
268 delegate
->StartFetcherAndWait();
270 EXPECT_TRUE(delegate
->fetcher()->GetStatus().is_success());
271 EXPECT_EQ(200, delegate
->fetcher()->GetResponseCode());
273 base::FilePath out_path
;
275 delegate
->fetcher()->GetResponseAsFilePath(take_ownership
, &out_path
));
276 if (!save_to_temporary_file
) {
277 EXPECT_EQ(requested_out_path
, out_path
);
280 EXPECT_TRUE(base::ContentsEqual(
281 test_server_
->GetDocumentRoot().AppendASCII(file_to_fetch
), out_path
));
283 // Delete the delegate and run the message loop to give the fetcher's
284 // destructor a chance to delete the file.
286 base::RunLoop().RunUntilIdle();
288 // File should only exist if |take_ownership| was true.
289 EXPECT_EQ(take_ownership
, base::PathExists(out_path
));
292 if (base::PathExists(out_path
))
293 base::DeleteFile(out_path
, false);
296 // Returns a URL that hangs on DNS resolution. Only hangs when using the
297 // request context returned by request_context().
298 const GURL
& hanging_url() const { return hanging_url_
; }
300 MockHostResolver
* resolver() { return &resolver_
; }
303 void SetUp() override
{
305 ASSERT_TRUE(test_server_
->Start());
307 // Set up host resolver so requests for |hanging_url_| block on an async DNS
308 // resolver. Calling resolver()->ResolveAllPending() will resume the hung
310 resolver_
.set_ondemand_mode(true);
311 resolver_
.rules()->AddRule("example.com", "127.0.0.1");
313 GURL(base::StringPrintf("http://example.com:%d/defaultresponse",
314 test_server_
->host_port_pair().port()));
315 ASSERT_TRUE(hanging_url_
.is_valid());
317 context_
.reset(new TestURLRequestContext(true));
318 context_
->set_host_resolver(&resolver_
);
319 context_
->set_throttler_manager(&throttler_manager_
);
322 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
323 crypto::EnsureNSSInit();
324 EnsureNSSHttpIOInit();
328 void TearDown() override
{
329 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
334 // Initializes |test_server_| without starting it. Allows subclasses to use
335 // their own server configuration.
336 virtual void SetUpServer() {
337 test_server_
.reset(new SpawnedTestServer(SpawnedTestServer::TYPE_HTTP
,
338 SpawnedTestServer::kLocalhost
,
339 base::FilePath(kDocRoot
)));
342 // URLFetcher is designed to run on the main UI thread, but in our tests
343 // we assume that the current thread is the IO thread where the URLFetcher
344 // dispatches its requests to. When we wish to simulate being used from
345 // a UI thread, we dispatch a worker thread to do so.
346 scoped_refptr
<base::MessageLoopProxy
> io_message_loop_proxy_
;
348 scoped_ptr
<SpawnedTestServer
> test_server_
;
351 size_t num_upload_streams_created_
;
353 URLFetcherImpl
* fetcher_
;
355 MockHostResolver resolver_
;
356 URLRequestThrottlerManager throttler_manager_
;
357 scoped_ptr
<TestURLRequestContext
> context_
;
359 int expected_status_code_
;
362 void URLFetcherTest::CreateFetcher(const GURL
& url
) {
363 fetcher_
= new URLFetcherImpl(url
, URLFetcher::GET
, this);
364 fetcher_
->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
365 io_message_loop_proxy().get(), request_context()));
369 void URLFetcherTest::OnURLFetchComplete(const URLFetcher
* source
) {
370 EXPECT_TRUE(source
->GetStatus().is_success());
371 EXPECT_EQ(expected_status_code_
, source
->GetResponseCode()); // HTTP OK
374 EXPECT_TRUE(source
->GetResponseAsString(&data
));
375 EXPECT_FALSE(data
.empty());
377 CleanupAfterFetchComplete();
380 void URLFetcherTest::CleanupAfterFetchComplete() {
381 delete fetcher_
; // Have to delete this here and not in the destructor,
382 // because the destructor won't necessarily run on the
383 // same thread that CreateFetcher() did.
385 io_message_loop_proxy()->PostTask(FROM_HERE
,
386 base::MessageLoop::QuitClosure());
387 // If the current message loop is not the IO loop, it will be shut down when
388 // the main loop returns and this thread subsequently goes out of scope.
393 // Version of URLFetcherTest that tests request cancellation on shutdown.
394 class URLFetcherCancelTest
: public URLFetcherTest
{
397 void CreateFetcher(const GURL
& url
) override
;
399 // URLFetcherDelegate:
400 void OnURLFetchComplete(const URLFetcher
* source
) override
;
402 void CancelRequest();
405 // Version of TestURLRequestContext that posts a Quit task to the IO
406 // thread once it is deleted.
407 class CancelTestURLRequestContext
: public ThrottlingTestURLRequestContext
{
409 explicit CancelTestURLRequestContext() {
413 ~CancelTestURLRequestContext() override
{
414 // The d'tor should execute in the IO thread. Post the quit task to the
416 base::MessageLoop::current()->PostTask(FROM_HERE
,
417 base::MessageLoop::QuitClosure());
421 class CancelTestURLRequestContextGetter
422 : public TestURLRequestContextGetter
{
424 CancelTestURLRequestContextGetter(
425 base::MessageLoopProxy
* io_message_loop_proxy
,
426 const GURL
& throttle_for_url
)
427 : TestURLRequestContextGetter(io_message_loop_proxy
),
428 io_message_loop_proxy_(io_message_loop_proxy
),
429 context_created_(false, false),
430 throttle_for_url_(throttle_for_url
) {
433 // TestURLRequestContextGetter:
434 TestURLRequestContext
* GetURLRequestContext() override
{
435 if (!context_
.get()) {
436 context_
.reset(new CancelTestURLRequestContext());
437 DCHECK(context_
->throttler_manager());
439 // Registers an entry for test url. The backoff time is calculated by:
440 // new_backoff = 2.0 * old_backoff + 0
441 // The initial backoff is 2 seconds and maximum backoff is 4 seconds.
442 // Maximum retries allowed is set to 2.
443 scoped_refptr
<URLRequestThrottlerEntry
> entry(
444 new URLRequestThrottlerEntry(context_
->throttler_manager(),
452 context_
->throttler_manager()
453 ->OverrideEntryForTests(throttle_for_url_
, entry
.get());
455 context_created_
.Signal();
457 return context_
.get();
460 virtual scoped_refptr
<base::MessageLoopProxy
> GetIOMessageLoopProxy() const {
461 return io_message_loop_proxy_
;
464 void WaitForContextCreation() {
465 context_created_
.Wait();
469 ~CancelTestURLRequestContextGetter() override
{}
472 scoped_ptr
<TestURLRequestContext
> context_
;
473 scoped_refptr
<base::MessageLoopProxy
> io_message_loop_proxy_
;
474 base::WaitableEvent context_created_
;
475 GURL throttle_for_url_
;
478 // Version of URLFetcherTest that tests bad HTTPS requests.
479 class URLFetcherBadHTTPSTest
: public URLFetcherTest
{
481 URLFetcherBadHTTPSTest() {}
484 void SetUpServer() override
{
485 SpawnedTestServer::SSLOptions
ssl_options(
486 SpawnedTestServer::SSLOptions::CERT_EXPIRED
);
487 test_server_
.reset(new SpawnedTestServer(
488 SpawnedTestServer::TYPE_HTTPS
, ssl_options
, base::FilePath(kDocRoot
)));
492 void URLFetcherCancelTest::CreateFetcher(const GURL
& url
) {
493 fetcher_
= new URLFetcherImpl(url
, URLFetcher::GET
, this);
494 CancelTestURLRequestContextGetter
* context_getter
=
495 new CancelTestURLRequestContextGetter(io_message_loop_proxy().get(), url
);
496 fetcher_
->SetRequestContext(context_getter
);
497 fetcher_
->SetMaxRetriesOn5xx(2);
499 // We need to wait for the creation of the URLRequestContext, since we
500 // rely on it being destroyed as a signal to end the test.
501 context_getter
->WaitForContextCreation();
505 void URLFetcherCancelTest::OnURLFetchComplete(
506 const URLFetcher
* source
) {
507 // We should have cancelled the request before completion.
509 CleanupAfterFetchComplete();
512 void URLFetcherCancelTest::CancelRequest() {
514 // The URLFetcher's test context will post a Quit task once it is
515 // deleted. So if this test simply hangs, it means cancellation
519 // Create the fetcher on the main thread. Since network IO will happen on the
520 // main thread, this will test URLFetcher's ability to do everything on one
522 TEST_F(URLFetcherTest
, SameThreadTest
) {
523 WaitingURLFetcherDelegate delegate
;
524 delegate
.CreateFetcherWithContext(test_server_
->GetURL(kDefaultResponsePath
),
525 URLFetcher::GET
, request_context());
526 delegate
.StartFetcherAndWait();
528 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
529 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
531 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
532 EXPECT_EQ(kDefaultResponseBody
, data
);
535 // Create a separate thread that will create the URLFetcher. A separate thread
536 // acts as the network thread.
537 TEST_F(URLFetcherTest
, DifferentThreadsTest
) {
538 base::Thread
network_thread("network thread");
539 base::Thread::Options network_thread_options
;
540 network_thread_options
.message_loop_type
= base::MessageLoop::TYPE_IO
;
541 ASSERT_TRUE(network_thread
.StartWithOptions(network_thread_options
));
543 scoped_refptr
<TestURLRequestContextGetter
> context_getter(
544 new TestURLRequestContextGetter(network_thread
.task_runner()));
545 WaitingURLFetcherDelegate delegate
;
546 delegate
.CreateFetcherWithContextGetter(
547 test_server_
->GetURL(kDefaultResponsePath
), URLFetcher::GET
,
548 new TestURLRequestContextGetter(network_thread
.task_runner()));
549 delegate
.StartFetcherAndWait();
551 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
552 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
554 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
555 EXPECT_EQ(kDefaultResponseBody
, data
);
558 // Tests to make sure CancelAll() will successfully cancel existing URLFetchers.
559 TEST_F(URLFetcherTest
, CancelAll
) {
560 EXPECT_EQ(0, GetNumFetcherCores());
561 WaitingURLFetcherDelegate delegate
;
562 delegate
.CreateFetcherWithContext(hanging_url(), URLFetcher::GET
,
564 delegate
.fetcher()->Start();
565 // Wait for the request to reach the mock resolver and hang, to ensure the
566 // request has actually started.
567 base::RunLoop().RunUntilIdle();
568 EXPECT_TRUE(resolver_
.has_pending_requests());
570 EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores());
571 URLFetcherImpl::CancelAll();
572 EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores());
575 TEST_F(URLFetcherTest
, DontRetryOnNetworkChangedByDefault
) {
576 EXPECT_EQ(0, GetNumFetcherCores());
577 WaitingURLFetcherDelegate delegate
;
578 delegate
.CreateFetcherWithContext(hanging_url(), URLFetcher::GET
,
580 EXPECT_FALSE(resolver_
.has_pending_requests());
582 // This posts a task to start the fetcher.
583 delegate
.fetcher()->Start();
584 base::RunLoop().RunUntilIdle();
586 // The fetcher is now running, but is pending the host resolve.
587 EXPECT_EQ(1, GetNumFetcherCores());
588 EXPECT_TRUE(resolver_
.has_pending_requests());
589 ASSERT_FALSE(delegate
.did_complete());
591 // A network change notification aborts the connect job.
592 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
593 delegate
.WaitForComplete();
594 EXPECT_FALSE(resolver_
.has_pending_requests());
596 // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error.
597 EXPECT_EQ(hanging_url(), delegate
.fetcher()->GetOriginalURL());
598 ASSERT_FALSE(delegate
.fetcher()->GetStatus().is_success());
599 EXPECT_EQ(ERR_NETWORK_CHANGED
, delegate
.fetcher()->GetStatus().error());
602 TEST_F(URLFetcherTest
, RetryOnNetworkChangedAndFail
) {
603 EXPECT_EQ(0, GetNumFetcherCores());
604 WaitingURLFetcherDelegate delegate
;
605 delegate
.CreateFetcherWithContext(hanging_url(), URLFetcher::GET
,
607 delegate
.fetcher()->SetAutomaticallyRetryOnNetworkChanges(3);
608 EXPECT_FALSE(resolver_
.has_pending_requests());
610 // This posts a task to start the fetcher.
611 delegate
.fetcher()->Start();
612 base::RunLoop().RunUntilIdle();
614 // The fetcher is now running, but is pending the host resolve.
615 EXPECT_EQ(1, GetNumFetcherCores());
616 EXPECT_TRUE(resolver_
.has_pending_requests());
617 ASSERT_FALSE(delegate
.did_complete());
619 // Make it fail 3 times.
620 for (int i
= 0; i
< 3; ++i
) {
621 // A network change notification aborts the connect job.
622 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
623 base::RunLoop().RunUntilIdle();
625 // But the fetcher retries automatically.
626 EXPECT_EQ(1, GetNumFetcherCores());
627 EXPECT_TRUE(resolver_
.has_pending_requests());
628 ASSERT_FALSE(delegate
.did_complete());
631 // A 4th failure doesn't trigger another retry, and propagates the error
632 // to the owner of the fetcher.
633 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
634 delegate
.WaitForComplete();
635 EXPECT_FALSE(resolver_
.has_pending_requests());
637 // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error.
638 EXPECT_EQ(hanging_url(), delegate
.fetcher()->GetOriginalURL());
639 ASSERT_FALSE(delegate
.fetcher()->GetStatus().is_success());
640 EXPECT_EQ(ERR_NETWORK_CHANGED
, delegate
.fetcher()->GetStatus().error());
643 TEST_F(URLFetcherTest
, RetryOnNetworkChangedAndSucceed
) {
644 EXPECT_EQ(0, GetNumFetcherCores());
645 WaitingURLFetcherDelegate delegate
;
646 delegate
.CreateFetcherWithContext(hanging_url(), URLFetcher::GET
,
648 delegate
.fetcher()->SetAutomaticallyRetryOnNetworkChanges(3);
649 EXPECT_FALSE(resolver_
.has_pending_requests());
651 // This posts a task to start the fetcher.
652 delegate
.fetcher()->Start();
653 base::RunLoop().RunUntilIdle();
655 // The fetcher is now running, but is pending the host resolve.
656 EXPECT_EQ(1, GetNumFetcherCores());
657 EXPECT_TRUE(resolver_
.has_pending_requests());
658 ASSERT_FALSE(delegate
.did_complete());
660 // Make it fail 3 times.
661 for (int i
= 0; i
< 3; ++i
) {
662 // A network change notification aborts the connect job.
663 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
664 base::RunLoop().RunUntilIdle();
666 // But the fetcher retries automatically.
667 EXPECT_EQ(1, GetNumFetcherCores());
668 EXPECT_TRUE(resolver_
.has_pending_requests());
669 ASSERT_FALSE(delegate
.did_complete());
672 // Now let it succeed by resolving the pending request.
673 resolver_
.ResolveAllPending();
674 delegate
.WaitForComplete();
675 EXPECT_FALSE(resolver_
.has_pending_requests());
677 // This time the request succeeded.
678 EXPECT_EQ(hanging_url(), delegate
.fetcher()->GetOriginalURL());
679 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
680 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
683 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
684 EXPECT_EQ(kDefaultResponseBody
, data
);
687 TEST_F(URLFetcherTest
, PostString
) {
688 const char kUploadData
[] = "bobsyeruncle";
690 WaitingURLFetcherDelegate delegate
;
691 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echo"),
692 URLFetcher::POST
, request_context());
693 delegate
.fetcher()->SetUploadData("application/x-www-form-urlencoded",
695 delegate
.StartFetcherAndWait();
697 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
698 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
700 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
701 EXPECT_EQ(kUploadData
, data
);
704 TEST_F(URLFetcherTest
, PostEmptyString
) {
705 const char kUploadData
[] = "";
707 WaitingURLFetcherDelegate delegate
;
708 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echo"),
709 URLFetcher::POST
, request_context());
710 delegate
.fetcher()->SetUploadData("application/x-www-form-urlencoded",
712 delegate
.StartFetcherAndWait();
714 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
715 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
717 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
718 EXPECT_EQ(kUploadData
, data
);
721 TEST_F(URLFetcherTest
, PostEntireFile
) {
722 base::FilePath upload_path
= GetUploadFileTestPath();
724 WaitingURLFetcherDelegate delegate
;
725 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echo"),
726 URLFetcher::POST
, request_context());
727 delegate
.fetcher()->SetUploadFilePath("application/x-www-form-urlencoded",
728 upload_path
, 0, kuint64max
,
729 base::MessageLoopProxy::current());
730 delegate
.StartFetcherAndWait();
732 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
733 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
735 std::string expected
;
736 ASSERT_TRUE(base::ReadFileToString(upload_path
, &expected
));
738 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
739 EXPECT_EQ(expected
, data
);
742 TEST_F(URLFetcherTest
, PostFileRange
) {
743 const size_t kRangeStart
= 30;
744 const size_t kRangeLength
= 100;
745 base::FilePath upload_path
= GetUploadFileTestPath();
747 WaitingURLFetcherDelegate delegate
;
748 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echo"),
749 URLFetcher::POST
, request_context());
750 delegate
.fetcher()->SetUploadFilePath("application/x-www-form-urlencoded",
751 upload_path
, kRangeStart
, kRangeLength
,
752 base::MessageLoopProxy::current());
753 delegate
.StartFetcherAndWait();
755 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
756 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
758 std::string expected
;
759 ASSERT_TRUE(base::ReadFileToString(upload_path
, &expected
));
761 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
762 EXPECT_EQ(expected
.substr(kRangeStart
, kRangeLength
), data
);
765 TEST_F(URLFetcherTest
, PostWithUploadStreamFactory
) {
766 WaitingURLFetcherDelegate delegate
;
767 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echo"),
768 URLFetcher::POST
, request_context());
769 delegate
.fetcher()->SetUploadStreamFactory(
771 base::Bind(&URLFetcherTest::CreateUploadStream
, base::Unretained(this)));
772 delegate
.StartFetcherAndWait();
774 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
775 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
777 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
778 EXPECT_EQ(kCreateUploadStreamBody
, data
);
779 EXPECT_EQ(1u, num_upload_streams_created());
782 TEST_F(URLFetcherTest
, PostWithUploadStreamFactoryAndRetries
) {
783 WaitingURLFetcherDelegate delegate
;
784 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echo?status=500"),
785 URLFetcher::POST
, request_context());
786 delegate
.fetcher()->SetAutomaticallyRetryOn5xx(true);
787 delegate
.fetcher()->SetMaxRetriesOn5xx(1);
788 delegate
.fetcher()->SetUploadStreamFactory(
790 base::Bind(&URLFetcherTest::CreateUploadStream
, base::Unretained(this)));
791 delegate
.StartFetcherAndWait();
793 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
794 EXPECT_EQ(500, delegate
.fetcher()->GetResponseCode());
796 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
797 EXPECT_EQ(kCreateUploadStreamBody
, data
);
798 EXPECT_EQ(2u, num_upload_streams_created());
801 // Checks that upload progress increases over time, never exceeds what's already
802 // been sent, and adds a chunk whenever all previously appended chunks have
804 class CheckUploadProgressDelegate
: public WaitingURLFetcherDelegate
{
806 CheckUploadProgressDelegate()
807 : chunk_(1 << 16, 'a'), num_chunks_appended_(0), last_seen_progress_(0) {}
808 ~CheckUploadProgressDelegate() override
{}
810 void OnURLFetchUploadProgress(const URLFetcher
* source
,
812 int64 total
) override
{
813 // Run default checks.
814 WaitingURLFetcherDelegate::OnURLFetchUploadProgress(source
, current
, total
);
816 EXPECT_LE(last_seen_progress_
, current
);
817 EXPECT_LE(current
, bytes_appended());
818 last_seen_progress_
= current
;
822 // Append the next chunk if all previously appended chunks have been sent.
823 void MaybeAppendChunk() {
824 const int kNumChunks
= 5;
825 if (last_seen_progress_
== bytes_appended() &&
826 num_chunks_appended_
< kNumChunks
) {
827 ++num_chunks_appended_
;
828 fetcher()->AppendChunkToUpload(chunk_
,
829 num_chunks_appended_
== kNumChunks
);
834 int64
bytes_appended() const { return num_chunks_appended_
* chunk_
.size(); }
836 const std::string chunk_
;
838 int64 num_chunks_appended_
;
839 int64 last_seen_progress_
;
841 DISALLOW_COPY_AND_ASSIGN(CheckUploadProgressDelegate
);
844 TEST_F(URLFetcherTest
, UploadProgress
) {
845 CheckUploadProgressDelegate delegate
;
846 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echo"),
847 URLFetcher::POST
, request_context());
848 // Use a chunked upload so that the upload can be paused after uploading data.
849 // Since upload progress uses a timer, the delegate may not receive any
850 // notification otherwise.
851 delegate
.fetcher()->SetChunkedUpload("application/x-www-form-urlencoded");
853 delegate
.fetcher()->Start();
854 // Append the first chunk. Others will be appended automatically in response
855 // to OnURLFetchUploadProgress events.
856 delegate
.MaybeAppendChunk();
857 delegate
.WaitForComplete();
859 // Make sure there are no pending events that cause problems when run.
860 base::RunLoop().RunUntilIdle();
862 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
863 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
864 EXPECT_TRUE(delegate
.did_complete());
867 // Checks that download progress never decreases, never exceeds file size, and
868 // that file size is correctly reported.
869 class CheckDownloadProgressDelegate
: public WaitingURLFetcherDelegate
{
871 CheckDownloadProgressDelegate(int64 file_size
)
872 : file_size_(file_size
), last_seen_progress_(0) {}
873 ~CheckDownloadProgressDelegate() override
{}
875 void OnURLFetchDownloadProgress(const URLFetcher
* source
,
877 int64 total
) override
{
878 // Run default checks.
879 WaitingURLFetcherDelegate::OnURLFetchDownloadProgress(source
, current
,
882 EXPECT_LE(last_seen_progress_
, current
);
883 EXPECT_EQ(file_size_
, total
);
884 last_seen_progress_
= current
;
889 int64 last_seen_progress_
;
891 DISALLOW_COPY_AND_ASSIGN(CheckDownloadProgressDelegate
);
894 TEST_F(URLFetcherTest
, DownloadProgress
) {
895 // Get a file large enough to require more than one read into
896 // URLFetcher::Core's IOBuffer.
897 const char kFileToFetch
[] = "animate1.gif";
899 std::string file_contents
;
900 ASSERT_TRUE(base::ReadFileToString(
901 test_server_
->GetDocumentRoot().AppendASCII(kFileToFetch
),
904 CheckDownloadProgressDelegate
delegate(file_contents
.size());
905 delegate
.CreateFetcherWithContext(
906 test_server_
->GetURL(std::string(kTestServerFilePrefix
) + kFileToFetch
),
907 URLFetcher::GET
, request_context());
908 delegate
.StartFetcherAndWait();
910 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
911 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
913 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
914 EXPECT_EQ(file_contents
, data
);
917 class CancelOnUploadProgressDelegate
: public WaitingURLFetcherDelegate
{
919 CancelOnUploadProgressDelegate() {}
920 ~CancelOnUploadProgressDelegate() override
{}
922 void OnURLFetchUploadProgress(const URLFetcher
* source
,
924 int64 total
) override
{
929 DISALLOW_COPY_AND_ASSIGN(CancelOnUploadProgressDelegate
);
932 // Check that a fetch can be safely cancelled/deleted during an upload progress
934 TEST_F(URLFetcherTest
, CancelInUploadProgressCallback
) {
935 CancelOnUploadProgressDelegate delegate
;
936 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echo"),
937 URLFetcher::POST
, request_context());
938 delegate
.fetcher()->SetChunkedUpload("application/x-www-form-urlencoded");
939 delegate
.fetcher()->Start();
940 // Use a chunked upload so that the upload can be paused after uploading data.
941 // Since uploads progress uses a timer, may not receive any notification,
943 std::string
upload_data(1 << 16, 'a');
944 delegate
.fetcher()->AppendChunkToUpload(upload_data
, false);
945 delegate
.WaitForComplete();
947 // Make sure there are no pending events that cause problems when run.
948 base::RunLoop().RunUntilIdle();
950 EXPECT_FALSE(delegate
.did_complete());
951 EXPECT_FALSE(delegate
.fetcher());
954 class CancelOnDownloadProgressDelegate
: public WaitingURLFetcherDelegate
{
956 CancelOnDownloadProgressDelegate() {}
957 ~CancelOnDownloadProgressDelegate() override
{}
959 void OnURLFetchDownloadProgress(const URLFetcher
* source
,
961 int64 total
) override
{
966 DISALLOW_COPY_AND_ASSIGN(CancelOnDownloadProgressDelegate
);
969 // Check that a fetch can be safely cancelled/deleted during a download progress
971 TEST_F(URLFetcherTest
, CancelInDownloadProgressCallback
) {
972 // Get a file large enough to require more than one read into
973 // URLFetcher::Core's IOBuffer.
974 static const char kFileToFetch
[] = "animate1.gif";
975 CancelOnDownloadProgressDelegate delegate
;
976 delegate
.CreateFetcherWithContext(
977 test_server_
->GetURL(std::string(kTestServerFilePrefix
) + kFileToFetch
),
978 URLFetcher::GET
, request_context());
979 delegate
.StartFetcherAndWait();
981 // Make sure there are no pending events that cause problems when run.
982 base::RunLoop().RunUntilIdle();
984 EXPECT_FALSE(delegate
.did_complete());
985 EXPECT_FALSE(delegate
.fetcher());
988 TEST_F(URLFetcherTest
, Headers
) {
989 WaitingURLFetcherDelegate delegate
;
990 delegate
.CreateFetcherWithContext(
991 test_server_
->GetURL("set-header?cache-control: private"),
992 URLFetcher::GET
, request_context());
993 delegate
.StartFetcherAndWait();
995 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
996 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
998 ASSERT_TRUE(delegate
.fetcher()->GetResponseHeaders()->GetNormalizedHeader(
999 "cache-control", &header
));
1000 EXPECT_EQ("private", header
);
1003 TEST_F(URLFetcherTest
, SocketAddress
) {
1004 WaitingURLFetcherDelegate delegate
;
1005 delegate
.CreateFetcherWithContext(test_server_
->GetURL(kDefaultResponsePath
),
1006 URLFetcher::GET
, request_context());
1007 delegate
.StartFetcherAndWait();
1009 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
1010 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
1011 EXPECT_EQ(test_server_
->host_port_pair().port(),
1012 delegate
.fetcher()->GetSocketAddress().port());
1013 EXPECT_EQ(test_server_
->host_port_pair().host(),
1014 delegate
.fetcher()->GetSocketAddress().host());
1017 TEST_F(URLFetcherTest
, StopOnRedirect
) {
1018 const char kRedirectTarget
[] = "http://redirect.target.com";
1020 WaitingURLFetcherDelegate delegate
;
1021 delegate
.CreateFetcherWithContext(
1022 test_server_
->GetURL(std::string("server-redirect?") + kRedirectTarget
),
1023 URLFetcher::GET
, request_context());
1024 delegate
.fetcher()->SetStopOnRedirect(true);
1025 delegate
.StartFetcherAndWait();
1027 EXPECT_EQ(GURL(kRedirectTarget
), delegate
.fetcher()->GetURL());
1028 EXPECT_EQ(URLRequestStatus::CANCELED
,
1029 delegate
.fetcher()->GetStatus().status());
1030 EXPECT_EQ(ERR_ABORTED
, delegate
.fetcher()->GetStatus().error());
1031 EXPECT_EQ(301, delegate
.fetcher()->GetResponseCode());
1034 TEST_F(URLFetcherTest
, ThrottleOnRepeatedFetches
) {
1035 base::Time start_time
= Time::Now();
1036 GURL
url(test_server_
->GetURL(kDefaultResponsePath
));
1038 // Registers an entry for test url. It only allows 3 requests to be sent
1039 // in 200 milliseconds.
1040 scoped_refptr
<URLRequestThrottlerEntry
> entry(new URLRequestThrottlerEntry(
1041 request_context()->throttler_manager(), std::string() /* url_id */,
1042 200 /* sliding_window_period_ms */, 3 /* max_send_threshold */,
1043 1 /* initial_backoff_ms */, 2.0 /* multiply_factor */,
1044 0.0 /* jitter_factor */, 256 /* maximum_backoff_ms */));
1046 request_context()->throttler_manager()
1047 ->OverrideEntryForTests(url
, entry
.get());
1049 for (int i
= 0; i
< 20; ++i
) {
1050 WaitingURLFetcherDelegate delegate
;
1051 delegate
.CreateFetcherWithContext(url
, URLFetcher::GET
, request_context());
1052 delegate
.StartFetcherAndWait();
1054 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
1055 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
1058 // 20 requests were sent. Due to throttling, they should have collectively
1059 // taken over 1 second.
1060 EXPECT_GE(Time::Now() - start_time
, base::TimeDelta::FromSeconds(1));
1063 TEST_F(URLFetcherTest
, ThrottleOn5xxRetries
) {
1064 base::Time start_time
= Time::Now();
1065 GURL
url(test_server_
->GetURL("files/server-unavailable.html"));
1067 // Registers an entry for test url. The backoff time is calculated by:
1068 // new_backoff = 2.0 * old_backoff + 0
1069 // and maximum backoff time is 256 milliseconds.
1070 // Maximum retries allowed is set to 11.
1071 scoped_refptr
<URLRequestThrottlerEntry
> entry(new URLRequestThrottlerEntry(
1072 request_context()->throttler_manager(), std::string() /* url_id */,
1073 200 /* sliding_window_period_ms */, 3 /* max_send_threshold */,
1074 1 /* initial_backoff_ms */, 2.0 /* multiply_factor */,
1075 0.0 /* jitter_factor */, 256 /* maximum_backoff_ms */));
1076 request_context()->throttler_manager()
1077 ->OverrideEntryForTests(url
, entry
.get());
1079 request_context()->throttler_manager()->OverrideEntryForTests(url
,
1082 WaitingURLFetcherDelegate delegate
;
1083 delegate
.CreateFetcherWithContext(url
, URLFetcher::GET
, request_context());
1084 delegate
.fetcher()->SetAutomaticallyRetryOn5xx(true);
1085 delegate
.fetcher()->SetMaxRetriesOn5xx(11);
1086 delegate
.StartFetcherAndWait();
1088 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
1089 EXPECT_EQ(503, delegate
.fetcher()->GetResponseCode());
1091 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
1092 EXPECT_FALSE(data
.empty());
1094 // The request should have been retried 11 times (12 times including the first
1095 // attempt). Due to throttling, they should have collectively taken over 1
1097 EXPECT_GE(Time::Now() - start_time
, base::TimeDelta::FromSeconds(1));
1100 // Tests overload protection, when responses passed through.
1101 TEST_F(URLFetcherTest
, ProtectTestPassedThrough
) {
1102 base::Time start_time
= Time::Now();
1103 GURL
url(test_server_
->GetURL("files/server-unavailable.html"));
1105 // Registers an entry for test url. The backoff time is calculated by:
1106 // new_backoff = 2.0 * old_backoff + 0
1107 // and maximum backoff time is 150000 milliseconds.
1108 // Maximum retries allowed is set to 11.
1109 scoped_refptr
<URLRequestThrottlerEntry
> entry(new URLRequestThrottlerEntry(
1110 request_context()->throttler_manager(), std::string() /* url_id */,
1111 200 /* sliding_window_period_ms */, 3 /* max_send_threshold */,
1112 10000 /* initial_backoff_ms */, 2.0 /* multiply_factor */,
1113 0.0 /* jitter_factor */, 150000 /* maximum_backoff_ms */));
1114 // Total time if *not* for not doing automatic backoff would be 150s.
1115 // In reality it should be "as soon as server responds".
1116 request_context()->throttler_manager()
1117 ->OverrideEntryForTests(url
, entry
.get());
1119 WaitingURLFetcherDelegate delegate
;
1120 delegate
.CreateFetcherWithContext(url
, URLFetcher::GET
, request_context());
1121 delegate
.fetcher()->SetAutomaticallyRetryOn5xx(false);
1122 delegate
.fetcher()->SetMaxRetriesOn5xx(11);
1123 delegate
.StartFetcherAndWait();
1125 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
1126 EXPECT_EQ(503, delegate
.fetcher()->GetResponseCode());
1128 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
1129 EXPECT_FALSE(data
.empty());
1130 EXPECT_GT(delegate
.fetcher()->GetBackoffDelay().InMicroseconds(), 0);
1132 // The request should not have been retried at all. If it had attempted all
1133 // 11 retries, that should have taken 2.5 minutes.
1134 EXPECT_TRUE(Time::Now() - start_time
< TimeDelta::FromMinutes(1));
1137 TEST_F(URLFetcherCancelTest
, ReleasesContext
) {
1138 GURL
url(test_server_
->GetURL("files/server-unavailable.html"));
1140 // Create a separate thread that will create the URLFetcher. The current
1141 // (main) thread will do the IO, and when the fetch is complete it will
1142 // terminate the main thread's message loop; then the other thread's
1143 // message loop will be shut down automatically as the thread goes out of
1145 base::Thread
t("URLFetcher test thread");
1146 ASSERT_TRUE(t
.Start());
1147 t
.message_loop()->PostTask(
1149 base::Bind(&URLFetcherCancelTest::CreateFetcher
,
1150 base::Unretained(this), url
));
1152 base::MessageLoop::current()->Run();
1155 TEST_F(URLFetcherCancelTest
, CancelWhileDelayedStartTaskPending
) {
1156 GURL
url(test_server_
->GetURL("files/server-unavailable.html"));
1158 // Register an entry for test url.
1159 // Using a sliding window of 4 seconds, and max of 1 request, under a fast
1160 // run we expect to have a 4 second delay when posting the Start task.
1161 scoped_refptr
<URLRequestThrottlerEntry
> entry(
1162 new URLRequestThrottlerEntry(request_context()->throttler_manager(),
1170 request_context()->throttler_manager()
1171 ->OverrideEntryForTests(url
, entry
.get());
1172 // Fake that a request has just started.
1173 entry
->ReserveSendingTimeForNextRequest(base::TimeTicks());
1175 // The next request we try to send will be delayed by ~4 seconds.
1176 // The slower the test runs, the less the delay will be (since it takes the
1177 // time difference from now).
1179 base::Thread
t("URLFetcher test thread");
1180 ASSERT_TRUE(t
.Start());
1181 t
.message_loop()->PostTask(
1183 base::Bind(&URLFetcherTest::CreateFetcher
, base::Unretained(this), url
));
1185 base::MessageLoop::current()->Run();
1188 // A URLFetcherDelegate that expects to receive a response body of "request1"
1189 // and then reuses the fetcher for the same URL, setting the "test" request
1190 // header to "request2".
1191 class ReuseFetcherDelegate
: public WaitingURLFetcherDelegate
{
1193 // |second_request_context_getter| is the context getter used for the second
1194 // request. Can't reuse the old one because fetchers release it on completion.
1195 ReuseFetcherDelegate(
1196 scoped_refptr
<URLRequestContextGetter
> second_request_context_getter
)
1197 : first_request_complete_(false),
1198 second_request_context_getter_(second_request_context_getter
) {}
1200 ~ReuseFetcherDelegate() override
{}
1202 void OnURLFetchComplete(const URLFetcher
* source
) override
{
1203 EXPECT_EQ(fetcher(), source
);
1204 if (!first_request_complete_
) {
1205 first_request_complete_
= true;
1206 EXPECT_TRUE(fetcher()->GetStatus().is_success());
1207 EXPECT_EQ(200, fetcher()->GetResponseCode());
1209 ASSERT_TRUE(fetcher()->GetResponseAsString(&data
));
1210 EXPECT_EQ("request1", data
);
1212 fetcher()->SetRequestContext(second_request_context_getter_
.get());
1213 fetcher()->SetExtraRequestHeaders("test: request2");
1217 WaitingURLFetcherDelegate::OnURLFetchComplete(source
);
1221 bool first_request_complete_
;
1222 scoped_refptr
<URLRequestContextGetter
> second_request_context_getter_
;
1224 DISALLOW_COPY_AND_ASSIGN(ReuseFetcherDelegate
);
1227 TEST_F(URLFetcherTest
, ReuseFetcherForSameURL
) {
1228 // TODO(mmenke): It's really weird that this is supported, particularly
1229 // some fields can be modified between requests, but some (Like upload body)
1230 // cannot be. Can we get rid of support for this?
1231 ReuseFetcherDelegate
delegate(new TrivialURLRequestContextGetter(
1232 request_context(), base::MessageLoopProxy::current()));
1233 delegate
.CreateFetcherWithContext(test_server_
->GetURL("echoheader?test"),
1234 URLFetcher::GET
, request_context());
1235 delegate
.fetcher()->SetExtraRequestHeaders("test: request1");
1236 delegate
.StartFetcherAndWait();
1238 EXPECT_TRUE(delegate
.fetcher()->GetStatus().is_success());
1239 EXPECT_EQ(200, delegate
.fetcher()->GetResponseCode());
1241 ASSERT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
1242 EXPECT_EQ("request2", data
);
1245 // Get a small file.
1246 TEST_F(URLFetcherTest
, FileTestSmallGet
) {
1247 const char kFileToFetch
[] = "simple.html";
1249 base::ScopedTempDir temp_dir
;
1250 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
1251 base::FilePath out_path
= temp_dir
.path().AppendASCII(kFileToFetch
);
1252 SaveFileTest(kFileToFetch
, false, out_path
, false);
1255 // Get a file large enough to require more than one read into URLFetcher::Core's
1257 TEST_F(URLFetcherTest
, FileTestLargeGet
) {
1258 const char kFileToFetch
[] = "animate1.gif";
1260 base::ScopedTempDir temp_dir
;
1261 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
1262 base::FilePath out_path
= temp_dir
.path().AppendASCII(kFileToFetch
);
1263 SaveFileTest(kFileToFetch
, false, out_path
, false);
1266 // If the caller takes the ownership of the output file, the file should persist
1267 // even after URLFetcher is gone.
1268 TEST_F(URLFetcherTest
, FileTestTakeOwnership
) {
1269 const char kFileToFetch
[] = "simple.html";
1271 base::ScopedTempDir temp_dir
;
1272 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
1273 base::FilePath out_path
= temp_dir
.path().AppendASCII(kFileToFetch
);
1274 SaveFileTest(kFileToFetch
, false, out_path
, true);
1277 // Test that an existing file can be overwritten be a fetcher.
1278 TEST_F(URLFetcherTest
, FileTestOverwriteExisting
) {
1279 base::ScopedTempDir temp_dir
;
1280 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
1282 // Create a file before trying to fetch.
1283 const char kFileToFetch
[] = "simple.html";
1284 std::string
data(10000, '?'); // Meant to be larger than simple.html.
1285 base::FilePath out_path
= temp_dir
.path().AppendASCII(kFileToFetch
);
1286 ASSERT_EQ(static_cast<int>(data
.size()),
1287 base::WriteFile(out_path
, data
.data(), data
.size()));
1288 ASSERT_TRUE(base::PathExists(out_path
));
1290 SaveFileTest(kFileToFetch
, false, out_path
, true);
1293 // Test trying to overwrite a directory with a file when using a fetcher fails.
1294 TEST_F(URLFetcherTest
, FileTestTryToOverwriteDirectory
) {
1295 base::ScopedTempDir temp_dir
;
1296 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
1298 // Create a directory before trying to fetch.
1299 static const char kFileToFetch
[] = "simple.html";
1300 base::FilePath out_path
= temp_dir
.path().AppendASCII(kFileToFetch
);
1301 ASSERT_TRUE(base::CreateDirectory(out_path
));
1302 ASSERT_TRUE(base::PathExists(out_path
));
1304 WaitingURLFetcherDelegate delegate
;
1305 delegate
.CreateFetcherWithContext(
1306 test_server_
->GetURL(std::string(kTestServerFilePrefix
) + kFileToFetch
),
1307 URLFetcher::GET
, request_context());
1308 delegate
.fetcher()->SaveResponseToFileAtPath(
1310 scoped_refptr
<base::MessageLoopProxy
>(base::MessageLoopProxy::current()));
1311 delegate
.StartFetcherAndWait();
1313 EXPECT_FALSE(delegate
.fetcher()->GetStatus().is_success());
1314 EXPECT_EQ(ERR_ACCESS_DENIED
, delegate
.fetcher()->GetStatus().error());
1317 // Get a small file and save it to a temp file.
1318 TEST_F(URLFetcherTest
, TempFileTestSmallGet
) {
1319 SaveFileTest("simple.html", true, base::FilePath(), false);
1322 // Get a file large enough to require more than one read into URLFetcher::Core's
1323 // IOBuffer and save it to a temp file.
1324 TEST_F(URLFetcherTest
, TempFileTestLargeGet
) {
1325 SaveFileTest("animate1.gif", true, base::FilePath(), false);
1328 // If the caller takes the ownership of the temp file, check that the file
1329 // persists even after URLFetcher is gone.
1330 TEST_F(URLFetcherTest
, TempFileTestTakeOwnership
) {
1331 SaveFileTest("simple.html", true, base::FilePath(), true);
1334 TEST_F(URLFetcherBadHTTPSTest
, BadHTTPS
) {
1335 WaitingURLFetcherDelegate delegate
;
1336 delegate
.CreateFetcherWithContext(test_server_
->GetURL(kDefaultResponsePath
),
1337 URLFetcher::GET
, request_context());
1338 delegate
.StartFetcherAndWait();
1340 EXPECT_EQ(URLRequestStatus::CANCELED
,
1341 delegate
.fetcher()->GetStatus().status());
1342 EXPECT_EQ(ERR_ABORTED
, delegate
.fetcher()->GetStatus().error());
1343 EXPECT_EQ(-1, delegate
.fetcher()->GetResponseCode());
1344 EXPECT_TRUE(delegate
.fetcher()->GetCookies().empty());
1346 EXPECT_TRUE(delegate
.fetcher()->GetResponseAsString(&data
));
1347 EXPECT_TRUE(data
.empty());