Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / net / url_request / url_fetcher_impl_unittest.cc
blobb3d6336d590264119270936aa338898ac727ba1f
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"
7 #include <algorithm>
8 #include <string>
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"
38 #endif
40 namespace net {
42 using base::Time;
43 using base::TimeDelta;
45 // TODO(eroman): Add a regression test for http://crbug.com/40505.
47 namespace {
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
55 // tests.
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() {
64 base::FilePath path;
65 PathService::Get(base::DIR_SOURCE_ROOT, &path);
66 return path.Append(
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 {
73 public:
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() {
96 fetcher_->Start();
97 WaitForComplete();
100 // Wait until the request has completed or been canceled. Does not start the
101 // request.
102 void WaitForComplete() { run_loop_.Run(); }
104 // Cancels the fetch by deleting the fetcher.
105 void CancelFetch() {
106 EXPECT_TRUE(fetcher_);
107 fetcher_.reset();
108 run_loop_.Quit();
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;
117 run_loop_.Quit();
120 void OnURLFetchDownloadProgress(const URLFetcher* source,
121 int64 current,
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.
131 if (total >= 0)
132 EXPECT_LE(current, total);
135 void OnURLFetchUploadProgress(const URLFetcher* source,
136 int64 current,
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.
146 if (total >= 0)
147 EXPECT_LE(current, total);
150 bool did_complete() const { return did_complete_; }
152 private:
153 bool did_complete_;
155 scoped_ptr<URLFetcherImpl> fetcher_;
156 base::RunLoop run_loop_;
158 DISALLOW_COPY_AND_ASSIGN(WaitingURLFetcherDelegate);
161 class ThrottlingTestURLRequestContext : public TestURLRequestContext {
162 public:
163 ThrottlingTestURLRequestContext() : TestURLRequestContext(true) {
164 set_throttler_manager(&throttler_manager_);
165 Init();
166 DCHECK(throttler_manager() != nullptr);
169 private:
170 URLRequestThrottlerManager throttler_manager_;
173 class ThrottlingTestURLRequestContextGetter
174 : public TestURLRequestContextGetter {
175 public:
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_; }
186 protected:
187 ~ThrottlingTestURLRequestContextGetter() override {}
189 TestURLRequestContext* const context_;
192 } // namespace
194 class URLFetcherTest : public testing::Test,
195 public URLFetcherDelegate {
196 public:
197 URLFetcherTest()
198 : io_message_loop_proxy_(base::MessageLoopProxy::current()),
199 num_upload_streams_created_(0),
200 fetcher_(nullptr),
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) +
257 file_to_fetch),
258 URLFetcher::GET, request_context());
259 if (save_to_temporary_file) {
260 delegate->fetcher()->SaveResponseToTemporaryFile(
261 scoped_refptr<base::MessageLoopProxy>(
262 base::MessageLoopProxy::current()));
263 } else {
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;
274 EXPECT_TRUE(
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.
285 delegate.reset();
286 base::RunLoop().RunUntilIdle();
288 // File should only exist if |take_ownership| was true.
289 EXPECT_EQ(take_ownership, base::PathExists(out_path));
291 // Cleanup.
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_; }
302 // testing::Test:
303 void SetUp() override {
304 SetUpServer();
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
309 // requests.
310 resolver_.set_ondemand_mode(true);
311 resolver_.rules()->AddRule("example.com", "127.0.0.1");
312 hanging_url_ =
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_);
320 context_->Init();
322 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
323 crypto::EnsureNSSInit();
324 EnsureNSSHttpIOInit();
325 #endif
328 void TearDown() override {
329 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
330 ShutdownNSSHttpIO();
331 #endif
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_;
349 GURL hanging_url_;
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()));
366 fetcher_->Start();
369 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) {
370 EXPECT_TRUE(source->GetStatus().is_success());
371 EXPECT_EQ(expected_status_code_, source->GetResponseCode()); // HTTP OK
373 std::string data;
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.
391 namespace {
393 // Version of URLFetcherTest that tests request cancellation on shutdown.
394 class URLFetcherCancelTest : public URLFetcherTest {
395 public:
396 // 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 {
408 public:
409 explicit CancelTestURLRequestContext() {
412 private:
413 ~CancelTestURLRequestContext() override {
414 // The d'tor should execute in the IO thread. Post the quit task to the
415 // current thread.
416 base::MessageLoop::current()->PostTask(FROM_HERE,
417 base::MessageLoop::QuitClosure());
421 class CancelTestURLRequestContextGetter
422 : public TestURLRequestContextGetter {
423 public:
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(),
445 std::string(),
446 200,
448 2000,
449 2.0,
450 0.0,
451 4000));
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();
468 protected:
469 ~CancelTestURLRequestContextGetter() override {}
471 private:
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 {
480 public:
481 URLFetcherBadHTTPSTest() {}
483 // URLFetcherTest:
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);
498 fetcher_->Start();
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();
502 CancelRequest();
505 void URLFetcherCancelTest::OnURLFetchComplete(
506 const URLFetcher* source) {
507 // We should have cancelled the request before completion.
508 ADD_FAILURE();
509 CleanupAfterFetchComplete();
512 void URLFetcherCancelTest::CancelRequest() {
513 delete fetcher_;
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
516 // did not work.
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
521 // thread.
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());
530 std::string data;
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());
553 std::string data;
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,
563 request_context());
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,
579 request_context());
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,
606 request_context());
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,
647 request_context());
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());
682 std::string data;
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",
694 kUploadData);
695 delegate.StartFetcherAndWait();
697 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
698 EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
699 std::string data;
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",
711 kUploadData);
712 delegate.StartFetcherAndWait();
714 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
715 EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
716 std::string data;
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));
737 std::string data;
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));
760 std::string data;
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(
770 "text/plain",
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());
776 std::string data;
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(
789 "text/plain",
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());
795 std::string data;
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
803 // been uploaded.
804 class CheckUploadProgressDelegate : public WaitingURLFetcherDelegate {
805 public:
806 CheckUploadProgressDelegate()
807 : chunk_(1 << 16, 'a'), num_chunks_appended_(0), last_seen_progress_(0) {}
808 ~CheckUploadProgressDelegate() override {}
810 void OnURLFetchUploadProgress(const URLFetcher* source,
811 int64 current,
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;
819 MaybeAppendChunk();
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);
833 private:
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 {
870 public:
871 CheckDownloadProgressDelegate(int64 file_size)
872 : file_size_(file_size), last_seen_progress_(0) {}
873 ~CheckDownloadProgressDelegate() override {}
875 void OnURLFetchDownloadProgress(const URLFetcher* source,
876 int64 current,
877 int64 total) override {
878 // Run default checks.
879 WaitingURLFetcherDelegate::OnURLFetchDownloadProgress(source, current,
880 total);
882 EXPECT_LE(last_seen_progress_, current);
883 EXPECT_EQ(file_size_, total);
884 last_seen_progress_ = current;
887 private:
888 int64 file_size_;
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),
902 &file_contents));
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());
912 std::string data;
913 ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
914 EXPECT_EQ(file_contents, data);
917 class CancelOnUploadProgressDelegate : public WaitingURLFetcherDelegate {
918 public:
919 CancelOnUploadProgressDelegate() {}
920 ~CancelOnUploadProgressDelegate() override {}
922 void OnURLFetchUploadProgress(const URLFetcher* source,
923 int64 current,
924 int64 total) override {
925 CancelFetch();
928 private:
929 DISALLOW_COPY_AND_ASSIGN(CancelOnUploadProgressDelegate);
932 // Check that a fetch can be safely cancelled/deleted during an upload progress
933 // callback.
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,
942 // otherwise.
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 {
955 public:
956 CancelOnDownloadProgressDelegate() {}
957 ~CancelOnDownloadProgressDelegate() override {}
959 void OnURLFetchDownloadProgress(const URLFetcher* source,
960 int64 current,
961 int64 total) override {
962 CancelFetch();
965 private:
966 DISALLOW_COPY_AND_ASSIGN(CancelOnDownloadProgressDelegate);
969 // Check that a fetch can be safely cancelled/deleted during a download progress
970 // callback.
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());
997 std::string header;
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,
1080 entry.get());
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());
1090 std::string data;
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
1096 // second.
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());
1127 std::string data;
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
1144 // scope.
1145 base::Thread t("URLFetcher test thread");
1146 ASSERT_TRUE(t.Start());
1147 t.message_loop()->PostTask(
1148 FROM_HERE,
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(),
1163 std::string(),
1164 4000,
1166 2000,
1167 2.0,
1168 0.0,
1169 4000));
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(
1182 FROM_HERE,
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 {
1192 public:
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());
1208 std::string data;
1209 ASSERT_TRUE(fetcher()->GetResponseAsString(&data));
1210 EXPECT_EQ("request1", data);
1212 fetcher()->SetRequestContext(second_request_context_getter_.get());
1213 fetcher()->SetExtraRequestHeaders("test: request2");
1214 fetcher()->Start();
1215 return;
1217 WaitingURLFetcherDelegate::OnURLFetchComplete(source);
1220 private:
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());
1240 std::string data;
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
1256 // IOBuffer.
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(
1309 out_path,
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());
1345 std::string data;
1346 EXPECT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
1347 EXPECT_TRUE(data.empty());
1350 } // namespace
1352 } // namespace net