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. 4 5 #include "net/url_request/url_fetcher_impl.h" 6 7 #include <algorithm> 8 #include <string> 9 10 #include "base/bind.h" 11 #include "base/file_util.h" 12 #include "base/files/scoped_temp_dir.h" 13 #include "base/message_loop/message_loop_proxy.h" 14 #include "base/strings/stringprintf.h" 15 #include "base/synchronization/waitable_event.h" 16 #include "base/threading/thread.h" 17 #include "build/build_config.h" 18 #include "crypto/nss_util.h" 19 #include "net/base/network_change_notifier.h" 20 #include "net/dns/mock_host_resolver.h" 21 #include "net/http/http_response_headers.h" 22 #include "net/test/spawned_test_server/spawned_test_server.h" 23 #include "net/url_request/url_fetcher_delegate.h" 24 #include "net/url_request/url_request_context_getter.h" 25 #include "net/url_request/url_request_test_util.h" 26 #include "net/url_request/url_request_throttler_manager.h" 27 #include "testing/gtest/include/gtest/gtest.h" 28 29 #if defined(USE_NSS) || defined(OS_IOS) 30 #include "net/ocsp/nss_ocsp.h" 31 #endif 32 33 namespace net { 34 35 using base::Time; 36 using base::TimeDelta; 37 38 // TODO(eroman): Add a regression test for http://crbug.com/40505. 39 40 namespace { 41 42 // TODO(akalin): Move all the test data to somewhere under net/. 43 const base::FilePath::CharType kDocRoot[] = 44 FILE_PATH_LITERAL("chrome/test/data"); 45 const char kTestServerFilePrefix[] = "files/"; 46 47 class ThrottlingTestURLRequestContext : public TestURLRequestContext { 48 public: 49 ThrottlingTestURLRequestContext() : TestURLRequestContext(true) { 50 set_throttler_manager(&throttler_manager_); 51 Init(); 52 DCHECK(throttler_manager() != NULL); 53 } 54 55 private: 56 URLRequestThrottlerManager throttler_manager_; 57 }; 58 59 class ThrottlingTestURLRequestContextGetter 60 : public TestURLRequestContextGetter { 61 public: 62 ThrottlingTestURLRequestContextGetter( 63 base::MessageLoopProxy* io_message_loop_proxy, 64 TestURLRequestContext* request_context) 65 : TestURLRequestContextGetter(io_message_loop_proxy), 66 context_(request_context) { 67 } 68 69 // TestURLRequestContextGetter: 70 virtual TestURLRequestContext* GetURLRequestContext() OVERRIDE { 71 return context_; 72 } 73 74 protected: 75 virtual ~ThrottlingTestURLRequestContextGetter() {} 76 77 TestURLRequestContext* const context_; 78 }; 79 80 } // namespace 81 82 class URLFetcherTest : public testing::Test, 83 public URLFetcherDelegate { 84 public: 85 URLFetcherTest() : fetcher_(NULL) {} 86 87 static int GetNumFetcherCores() { 88 return URLFetcherImpl::GetNumFetcherCores(); 89 } 90 91 // Creates a URLFetcher, using the program's main thread to do IO. 92 virtual void CreateFetcher(const GURL& url); 93 94 // URLFetcherDelegate: 95 // Subclasses that override this should either call this function or 96 // CleanupAfterFetchComplete() at the end of their processing, depending on 97 // whether they want to check for a non-empty HTTP 200 response or not. 98 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 99 100 // Deletes |fetcher| and terminates the message loop. 101 void CleanupAfterFetchComplete(); 102 103 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() { 104 return io_message_loop_proxy_; 105 } 106 107 TestURLRequestContext* request_context() { 108 return context_.get(); 109 } 110 111 protected: 112 // testing::Test: 113 virtual void SetUp() OVERRIDE { 114 testing::Test::SetUp(); 115 116 context_.reset(new ThrottlingTestURLRequestContext()); 117 io_message_loop_proxy_ = base::MessageLoopProxy::current(); 118 119 #if defined(USE_NSS) || defined(OS_IOS) 120 crypto::EnsureNSSInit(); 121 EnsureNSSHttpIOInit(); 122 #endif 123 } 124 125 virtual void TearDown() OVERRIDE { 126 #if defined(USE_NSS) || defined(OS_IOS) 127 ShutdownNSSHttpIO(); 128 #endif 129 } 130 131 // URLFetcher is designed to run on the main UI thread, but in our tests 132 // we assume that the current thread is the IO thread where the URLFetcher 133 // dispatches its requests to. When we wish to simulate being used from 134 // a UI thread, we dispatch a worker thread to do so. 135 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; 136 137 URLFetcherImpl* fetcher_; 138 scoped_ptr<TestURLRequestContext> context_; 139 }; 140 141 // A test fixture that uses a MockHostResolver, so that name resolutions can 142 // be manipulated by the tests to keep connections in the resolving state. 143 class URLFetcherMockDnsTest : public URLFetcherTest { 144 public: 145 // testing::Test: 146 virtual void SetUp() OVERRIDE; 147 148 // URLFetcherTest: 149 virtual void CreateFetcher(const GURL& url) OVERRIDE; 150 151 // URLFetcherDelegate: 152 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 153 154 protected: 155 GURL test_url_; 156 scoped_ptr<SpawnedTestServer> test_server_; 157 MockHostResolver resolver_; 158 scoped_ptr<URLFetcher> completed_fetcher_; 159 }; 160 161 void URLFetcherTest::CreateFetcher(const GURL& url) { 162 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 163 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 164 io_message_loop_proxy().get(), request_context())); 165 fetcher_->Start(); 166 } 167 168 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) { 169 EXPECT_TRUE(source->GetStatus().is_success()); 170 EXPECT_EQ(200, source->GetResponseCode()); // HTTP OK 171 172 std::string data; 173 EXPECT_TRUE(source->GetResponseAsString(&data)); 174 EXPECT_FALSE(data.empty()); 175 176 CleanupAfterFetchComplete(); 177 } 178 179 void URLFetcherTest::CleanupAfterFetchComplete() { 180 delete fetcher_; // Have to delete this here and not in the destructor, 181 // because the destructor won't necessarily run on the 182 // same thread that CreateFetcher() did. 183 184 io_message_loop_proxy()->PostTask(FROM_HERE, 185 base::MessageLoop::QuitClosure()); 186 // If the current message loop is not the IO loop, it will be shut down when 187 // the main loop returns and this thread subsequently goes out of scope. 188 } 189 190 void URLFetcherMockDnsTest::SetUp() { 191 URLFetcherTest::SetUp(); 192 193 resolver_.set_ondemand_mode(true); 194 resolver_.rules()->AddRule("example.com", "127.0.0.1"); 195 196 context_.reset(new TestURLRequestContext(true)); 197 context_->set_host_resolver(&resolver_); 198 context_->Init(); 199 200 test_server_.reset(new SpawnedTestServer(SpawnedTestServer::TYPE_HTTP, 201 SpawnedTestServer::kLocalhost, 202 base::FilePath(kDocRoot))); 203 ASSERT_TRUE(test_server_->Start()); 204 205 // test_server_.GetURL() returns a URL with 127.0.0.1 (kLocalhost), that is 206 // immediately resolved by the MockHostResolver. Use a hostname instead to 207 // trigger an async resolve. 208 test_url_ = GURL( 209 base::StringPrintf("http://example.com:%d/defaultresponse", 210 test_server_->host_port_pair().port())); 211 ASSERT_TRUE(test_url_.is_valid()); 212 } 213 214 void URLFetcherMockDnsTest::CreateFetcher(const GURL& url) { 215 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 216 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 217 io_message_loop_proxy().get(), request_context())); 218 } 219 220 void URLFetcherMockDnsTest::OnURLFetchComplete(const URLFetcher* source) { 221 io_message_loop_proxy()->PostTask(FROM_HERE, 222 base::MessageLoop::QuitClosure()); 223 ASSERT_EQ(fetcher_, source); 224 EXPECT_EQ(test_url_, source->GetOriginalURL()); 225 completed_fetcher_.reset(fetcher_); 226 } 227 228 namespace { 229 230 // Version of URLFetcherTest that does a POST instead 231 class URLFetcherPostTest : public URLFetcherTest { 232 public: 233 // URLFetcherTest: 234 virtual void CreateFetcher(const GURL& url) OVERRIDE; 235 236 // URLFetcherDelegate: 237 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 238 }; 239 240 // Version of URLFetcherTest that does a POST of a file using 241 // SetUploadDataStream 242 class URLFetcherPostFileTest : public URLFetcherTest { 243 public: 244 URLFetcherPostFileTest(); 245 246 void SetUploadRange(uint64 range_offset, uint64 range_length) { 247 range_offset_ = range_offset; 248 range_length_ = range_length; 249 } 250 251 // URLFetcherTest: 252 virtual void CreateFetcher(const GURL& url) OVERRIDE; 253 254 // URLFetcherDelegate: 255 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 256 257 private: 258 base::FilePath path_; 259 uint64 range_offset_; 260 uint64 range_length_; 261 }; 262 263 // Version of URLFetcherTest that does a POST instead with empty upload body 264 class URLFetcherEmptyPostTest : public URLFetcherTest { 265 public: 266 // URLFetcherTest: 267 virtual void CreateFetcher(const GURL& url) OVERRIDE; 268 269 // URLFetcherDelegate: 270 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 271 }; 272 273 // Version of URLFetcherTest that tests download progress reports. 274 class URLFetcherDownloadProgressTest : public URLFetcherTest { 275 public: 276 URLFetcherDownloadProgressTest() 277 : previous_progress_(0), 278 expected_total_(0) { 279 } 280 281 // URLFetcherTest: 282 virtual void CreateFetcher(const GURL& url) OVERRIDE; 283 284 // URLFetcherDelegate: 285 virtual void OnURLFetchDownloadProgress(const URLFetcher* source, 286 int64 current, 287 int64 total) OVERRIDE; 288 289 protected: 290 // Download progress returned by the previous callback. 291 int64 previous_progress_; 292 // Size of the file being downloaded, known in advance (provided by each test 293 // case). 294 int64 expected_total_; 295 }; 296 297 // Version of URLFetcherTest that tests progress reports at cancellation. 298 class URLFetcherDownloadProgressCancelTest : public URLFetcherTest { 299 public: 300 // URLFetcherTest: 301 virtual void CreateFetcher(const GURL& url) OVERRIDE; 302 303 // URLFetcherDelegate: 304 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 305 virtual void OnURLFetchDownloadProgress(const URLFetcher* source, 306 int64 current, 307 int64 total) OVERRIDE; 308 protected: 309 bool cancelled_; 310 }; 311 312 // Version of URLFetcherTest that tests upload progress reports. 313 class URLFetcherUploadProgressTest : public URLFetcherTest { 314 public: 315 // URLFetcherTest: 316 virtual void CreateFetcher(const GURL& url) OVERRIDE; 317 318 // URLFetcherDelegate: 319 virtual void OnURLFetchUploadProgress(const URLFetcher* source, 320 int64 current, 321 int64 total) OVERRIDE; 322 protected: 323 int64 previous_progress_; 324 std::string chunk_; 325 int64 number_of_chunks_added_; 326 }; 327 328 // Version of URLFetcherTest that tests headers. 329 class URLFetcherHeadersTest : public URLFetcherTest { 330 public: 331 // URLFetcherDelegate: 332 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 333 }; 334 335 // Version of URLFetcherTest that tests SocketAddress. 336 class URLFetcherSocketAddressTest : public URLFetcherTest { 337 public: 338 // URLFetcherDelegate: 339 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 340 protected: 341 std::string expected_host_; 342 uint16 expected_port_; 343 }; 344 345 // Version of URLFetcherTest that tests stopping on a redirect. 346 class URLFetcherStopOnRedirectTest : public URLFetcherTest { 347 public: 348 URLFetcherStopOnRedirectTest(); 349 virtual ~URLFetcherStopOnRedirectTest(); 350 351 // URLFetcherTest: 352 virtual void CreateFetcher(const GURL& url) OVERRIDE; 353 354 // URLFetcherDelegate: 355 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 356 357 protected: 358 // The URL we should be redirected to. 359 static const char* kRedirectTarget; 360 361 bool callback_called_; // Set to true in OnURLFetchComplete(). 362 }; 363 364 // Version of URLFetcherTest that tests overload protection. 365 class URLFetcherProtectTest : public URLFetcherTest { 366 public: 367 // URLFetcherTest: 368 virtual void CreateFetcher(const GURL& url) OVERRIDE; 369 370 // URLFetcherDelegate: 371 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 372 private: 373 Time start_time_; 374 }; 375 376 // Version of URLFetcherTest that tests overload protection, when responses 377 // passed through. 378 class URLFetcherProtectTestPassedThrough : public URLFetcherTest { 379 public: 380 // URLFetcherTest: 381 virtual void CreateFetcher(const GURL& url) OVERRIDE; 382 383 // URLFetcherDelegate: 384 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 385 private: 386 Time start_time_; 387 }; 388 389 // Version of URLFetcherTest that tests bad HTTPS requests. 390 class URLFetcherBadHTTPSTest : public URLFetcherTest { 391 public: 392 URLFetcherBadHTTPSTest(); 393 394 // URLFetcherDelegate: 395 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 396 397 private: 398 base::FilePath cert_dir_; 399 }; 400 401 // Version of URLFetcherTest that tests request cancellation on shutdown. 402 class URLFetcherCancelTest : public URLFetcherTest { 403 public: 404 // URLFetcherTest: 405 virtual void CreateFetcher(const GURL& url) OVERRIDE; 406 407 // URLFetcherDelegate: 408 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 409 410 void CancelRequest(); 411 }; 412 413 // Version of TestURLRequestContext that posts a Quit task to the IO 414 // thread once it is deleted. 415 class CancelTestURLRequestContext : public ThrottlingTestURLRequestContext { 416 public: 417 explicit CancelTestURLRequestContext() { 418 } 419 420 private: 421 virtual ~CancelTestURLRequestContext() { 422 // The d'tor should execute in the IO thread. Post the quit task to the 423 // current thread. 424 base::MessageLoop::current()->PostTask(FROM_HERE, 425 base::MessageLoop::QuitClosure()); 426 } 427 }; 428 429 class CancelTestURLRequestContextGetter 430 : public TestURLRequestContextGetter { 431 public: 432 CancelTestURLRequestContextGetter( 433 base::MessageLoopProxy* io_message_loop_proxy, 434 const GURL& throttle_for_url) 435 : TestURLRequestContextGetter(io_message_loop_proxy), 436 io_message_loop_proxy_(io_message_loop_proxy), 437 context_created_(false, false), 438 throttle_for_url_(throttle_for_url) { 439 } 440 441 // TestURLRequestContextGetter: 442 virtual TestURLRequestContext* GetURLRequestContext() OVERRIDE { 443 if (!context_.get()) { 444 context_.reset(new CancelTestURLRequestContext()); 445 DCHECK(context_->throttler_manager()); 446 447 // Registers an entry for test url. The backoff time is calculated by: 448 // new_backoff = 2.0 * old_backoff + 0 449 // The initial backoff is 2 seconds and maximum backoff is 4 seconds. 450 // Maximum retries allowed is set to 2. 451 scoped_refptr<URLRequestThrottlerEntry> entry( 452 new URLRequestThrottlerEntry(context_->throttler_manager(), 453 std::string(), 454 200, 455 3, 456 2000, 457 2.0, 458 0.0, 459 4000)); 460 context_->throttler_manager() 461 ->OverrideEntryForTests(throttle_for_url_, entry.get()); 462 463 context_created_.Signal(); 464 } 465 return context_.get(); 466 } 467 468 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const { 469 return io_message_loop_proxy_; 470 } 471 472 void WaitForContextCreation() { 473 context_created_.Wait(); 474 } 475 476 protected: 477 virtual ~CancelTestURLRequestContextGetter() {} 478 479 private: 480 scoped_ptr<TestURLRequestContext> context_; 481 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; 482 base::WaitableEvent context_created_; 483 GURL throttle_for_url_; 484 }; 485 486 // Version of URLFetcherTest that tests retying the same request twice. 487 class URLFetcherMultipleAttemptTest : public URLFetcherTest { 488 public: 489 // URLFetcherDelegate: 490 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 491 private: 492 std::string data_; 493 }; 494 495 class URLFetcherFileTest : public URLFetcherTest { 496 public: 497 URLFetcherFileTest() : take_ownership_of_file_(false), 498 expected_file_error_(OK) {} 499 500 void CreateFetcherForFile(const GURL& url, const base::FilePath& file_path); 501 void CreateFetcherForTempFile(const GURL& url); 502 503 // URLFetcherDelegate: 504 virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; 505 506 protected: 507 base::FilePath expected_file_; 508 base::FilePath file_path_; 509 510 // Set by the test. Used in OnURLFetchComplete() to decide if 511 // the URLFetcher should own the temp file, so that we can test 512 // disowning prevents the file from being deleted. 513 bool take_ownership_of_file_; 514 515 // Expected file error code for the test. OK when expecting success. 516 int expected_file_error_; 517 }; 518 519 void URLFetcherPostTest::CreateFetcher(const GURL& url) { 520 fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); 521 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 522 io_message_loop_proxy().get(), request_context())); 523 fetcher_->SetUploadData("application/x-www-form-urlencoded", "bobsyeruncle"); 524 fetcher_->Start(); 525 } 526 527 void URLFetcherPostTest::OnURLFetchComplete(const URLFetcher* source) { 528 std::string data; 529 EXPECT_TRUE(source->GetResponseAsString(&data)); 530 EXPECT_EQ(std::string("bobsyeruncle"), data); 531 URLFetcherTest::OnURLFetchComplete(source); 532 } 533 534 URLFetcherPostFileTest::URLFetcherPostFileTest() 535 : range_offset_(0), 536 range_length_(kuint64max) { 537 PathService::Get(base::DIR_SOURCE_ROOT, &path_); 538 path_ = path_.Append(FILE_PATH_LITERAL("net")); 539 path_ = path_.Append(FILE_PATH_LITERAL("data")); 540 path_ = path_.Append(FILE_PATH_LITERAL("url_request_unittest")); 541 path_ = path_.Append(FILE_PATH_LITERAL("BullRunSpeech.txt")); 542 } 543 544 void URLFetcherPostFileTest::CreateFetcher(const GURL& url) { 545 fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); 546 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 547 io_message_loop_proxy().get(), request_context())); 548 fetcher_->SetUploadFilePath("application/x-www-form-urlencoded", 549 path_, 550 range_offset_, 551 range_length_, 552 base::MessageLoopProxy::current()); 553 fetcher_->Start(); 554 } 555 556 void URLFetcherPostFileTest::OnURLFetchComplete(const URLFetcher* source) { 557 std::string expected; 558 ASSERT_TRUE(file_util::ReadFileToString(path_, &expected)); 559 ASSERT_LE(range_offset_, expected.size()); 560 uint64 expected_size = 561 std::min(range_length_, expected.size() - range_offset_); 562 563 std::string data; 564 EXPECT_TRUE(source->GetResponseAsString(&data)); 565 EXPECT_EQ(expected.substr(range_offset_, expected_size), data); 566 URLFetcherTest::OnURLFetchComplete(source); 567 } 568 569 void URLFetcherEmptyPostTest::CreateFetcher(const GURL& url) { 570 fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); 571 fetcher_->SetRequestContext(new TestURLRequestContextGetter( 572 io_message_loop_proxy())); 573 fetcher_->SetUploadData("text/plain", std::string()); 574 fetcher_->Start(); 575 } 576 577 void URLFetcherEmptyPostTest::OnURLFetchComplete(const URLFetcher* source) { 578 EXPECT_TRUE(source->GetStatus().is_success()); 579 EXPECT_EQ(200, source->GetResponseCode()); // HTTP OK 580 581 std::string data; 582 EXPECT_TRUE(source->GetResponseAsString(&data)); 583 EXPECT_TRUE(data.empty()); 584 585 CleanupAfterFetchComplete(); 586 // Do not call the super class method URLFetcherTest::OnURLFetchComplete, 587 // since it expects a non-empty response. 588 } 589 590 void URLFetcherDownloadProgressTest::CreateFetcher(const GURL& url) { 591 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 592 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 593 io_message_loop_proxy().get(), request_context())); 594 fetcher_->Start(); 595 } 596 597 void URLFetcherDownloadProgressTest::OnURLFetchDownloadProgress( 598 const URLFetcher* source, int64 progress, int64 total) { 599 // Increasing between 0 and total. 600 EXPECT_LE(0, progress); 601 EXPECT_GE(total, progress); 602 EXPECT_LE(previous_progress_, progress); 603 EXPECT_EQ(expected_total_, total); 604 previous_progress_ = progress; 605 } 606 607 void URLFetcherDownloadProgressCancelTest::CreateFetcher(const GURL& url) { 608 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 609 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 610 io_message_loop_proxy().get(), request_context())); 611 cancelled_ = false; 612 fetcher_->Start(); 613 } 614 615 void URLFetcherDownloadProgressCancelTest::OnURLFetchDownloadProgress( 616 const URLFetcher* source, int64 current, int64 total) { 617 EXPECT_FALSE(cancelled_); 618 if (!cancelled_) { 619 cancelled_ = true; 620 CleanupAfterFetchComplete(); 621 } 622 } 623 624 void URLFetcherDownloadProgressCancelTest::OnURLFetchComplete( 625 const URLFetcher* source) { 626 // Should have been cancelled. 627 ADD_FAILURE(); 628 CleanupAfterFetchComplete(); 629 } 630 631 void URLFetcherUploadProgressTest::CreateFetcher(const GURL& url) { 632 fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); 633 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 634 io_message_loop_proxy().get(), request_context())); 635 previous_progress_ = 0; 636 // Large enough data to require more than one read from UploadDataStream. 637 chunk_.assign(1<<16, 'a'); 638 // Use chunked upload to wait for a timer event of progress notification. 639 fetcher_->SetChunkedUpload("application/x-www-form-urlencoded"); 640 fetcher_->Start(); 641 number_of_chunks_added_ = 1; 642 fetcher_->AppendChunkToUpload(chunk_, false); 643 } 644 645 void URLFetcherUploadProgressTest::OnURLFetchUploadProgress( 646 const URLFetcher* source, int64 current, int64 total) { 647 // Increasing between 0 and total. 648 EXPECT_LE(0, current); 649 EXPECT_GE(static_cast<int64>(chunk_.size()) * number_of_chunks_added_, 650 current); 651 EXPECT_LE(previous_progress_, current); 652 previous_progress_ = current; 653 EXPECT_EQ(-1, total); 654 655 if (number_of_chunks_added_ < 2) { 656 number_of_chunks_added_ += 1; 657 fetcher_->AppendChunkToUpload(chunk_, true); 658 } 659 } 660 661 void URLFetcherHeadersTest::OnURLFetchComplete( 662 const URLFetcher* source) { 663 std::string header; 664 EXPECT_TRUE(source->GetResponseHeaders()->GetNormalizedHeader("cache-control", 665 &header)); 666 EXPECT_EQ("private", header); 667 URLFetcherTest::OnURLFetchComplete(source); 668 } 669 670 void URLFetcherSocketAddressTest::OnURLFetchComplete( 671 const URLFetcher* source) { 672 EXPECT_EQ("127.0.0.1", source->GetSocketAddress().host()); 673 EXPECT_EQ(expected_port_, source->GetSocketAddress().port()); 674 URLFetcherTest::OnURLFetchComplete(source); 675 } 676 677 // static 678 const char* URLFetcherStopOnRedirectTest::kRedirectTarget = 679 "http://redirect.target.com"; 680 681 URLFetcherStopOnRedirectTest::URLFetcherStopOnRedirectTest() 682 : callback_called_(false) { 683 } 684 685 URLFetcherStopOnRedirectTest::~URLFetcherStopOnRedirectTest() { 686 } 687 688 void URLFetcherStopOnRedirectTest::CreateFetcher(const GURL& url) { 689 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 690 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 691 io_message_loop_proxy().get(), request_context())); 692 fetcher_->SetStopOnRedirect(true); 693 fetcher_->Start(); 694 } 695 696 void URLFetcherStopOnRedirectTest::OnURLFetchComplete( 697 const URLFetcher* source) { 698 callback_called_ = true; 699 EXPECT_EQ(GURL(kRedirectTarget), source->GetURL()); 700 EXPECT_EQ(URLRequestStatus::CANCELED, source->GetStatus().status()); 701 EXPECT_EQ(ERR_ABORTED, source->GetStatus().error()); 702 EXPECT_EQ(301, source->GetResponseCode()); 703 CleanupAfterFetchComplete(); 704 } 705 706 void URLFetcherProtectTest::CreateFetcher(const GURL& url) { 707 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 708 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 709 io_message_loop_proxy().get(), request_context())); 710 start_time_ = Time::Now(); 711 fetcher_->SetMaxRetriesOn5xx(11); 712 fetcher_->Start(); 713 } 714 715 void URLFetcherProtectTest::OnURLFetchComplete(const URLFetcher* source) { 716 const TimeDelta one_second = TimeDelta::FromMilliseconds(1000); 717 if (source->GetResponseCode() >= 500) { 718 // Now running ServerUnavailable test. 719 // It takes more than 1 second to finish all 11 requests. 720 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); 721 EXPECT_TRUE(source->GetStatus().is_success()); 722 std::string data; 723 EXPECT_TRUE(source->GetResponseAsString(&data)); 724 EXPECT_FALSE(data.empty()); 725 CleanupAfterFetchComplete(); 726 } else { 727 // Now running Overload test. 728 static int count = 0; 729 count++; 730 if (count < 20) { 731 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 732 io_message_loop_proxy().get(), request_context())); 733 fetcher_->Start(); 734 } else { 735 // We have already sent 20 requests continuously. And we expect that 736 // it takes more than 1 second due to the overload protection settings. 737 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); 738 URLFetcherTest::OnURLFetchComplete(source); 739 } 740 } 741 } 742 743 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) { 744 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 745 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 746 io_message_loop_proxy().get(), request_context())); 747 fetcher_->SetAutomaticallyRetryOn5xx(false); 748 start_time_ = Time::Now(); 749 fetcher_->SetMaxRetriesOn5xx(11); 750 fetcher_->Start(); 751 } 752 753 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete( 754 const URLFetcher* source) { 755 const TimeDelta one_minute = TimeDelta::FromMilliseconds(60000); 756 if (source->GetResponseCode() >= 500) { 757 // Now running ServerUnavailable test. 758 // It should get here on the first attempt, so almost immediately and 759 // *not* to attempt to execute all 11 requests (2.5 minutes). 760 EXPECT_TRUE(Time::Now() - start_time_ < one_minute); 761 EXPECT_TRUE(source->GetStatus().is_success()); 762 // Check that suggested back off time is bigger than 0. 763 EXPECT_GT(fetcher_->GetBackoffDelay().InMicroseconds(), 0); 764 std::string data; 765 EXPECT_TRUE(source->GetResponseAsString(&data)); 766 EXPECT_FALSE(data.empty()); 767 } else { 768 // We should not get here! 769 ADD_FAILURE(); 770 } 771 772 CleanupAfterFetchComplete(); 773 } 774 775 776 URLFetcherBadHTTPSTest::URLFetcherBadHTTPSTest() { 777 PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_); 778 cert_dir_ = cert_dir_.AppendASCII("chrome"); 779 cert_dir_ = cert_dir_.AppendASCII("test"); 780 cert_dir_ = cert_dir_.AppendASCII("data"); 781 cert_dir_ = cert_dir_.AppendASCII("ssl"); 782 cert_dir_ = cert_dir_.AppendASCII("certificates"); 783 } 784 785 // The "server certificate expired" error should result in automatic 786 // cancellation of the request by 787 // URLRequest::Delegate::OnSSLCertificateError. 788 void URLFetcherBadHTTPSTest::OnURLFetchComplete( 789 const URLFetcher* source) { 790 // This part is different from URLFetcherTest::OnURLFetchComplete 791 // because this test expects the request to be cancelled. 792 EXPECT_EQ(URLRequestStatus::CANCELED, source->GetStatus().status()); 793 EXPECT_EQ(ERR_ABORTED, source->GetStatus().error()); 794 EXPECT_EQ(-1, source->GetResponseCode()); 795 EXPECT_TRUE(source->GetCookies().empty()); 796 std::string data; 797 EXPECT_TRUE(source->GetResponseAsString(&data)); 798 EXPECT_TRUE(data.empty()); 799 CleanupAfterFetchComplete(); 800 } 801 802 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { 803 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 804 CancelTestURLRequestContextGetter* context_getter = 805 new CancelTestURLRequestContextGetter(io_message_loop_proxy().get(), url); 806 fetcher_->SetRequestContext(context_getter); 807 fetcher_->SetMaxRetriesOn5xx(2); 808 fetcher_->Start(); 809 // We need to wait for the creation of the URLRequestContext, since we 810 // rely on it being destroyed as a signal to end the test. 811 context_getter->WaitForContextCreation(); 812 CancelRequest(); 813 } 814 815 void URLFetcherCancelTest::OnURLFetchComplete( 816 const URLFetcher* source) { 817 // We should have cancelled the request before completion. 818 ADD_FAILURE(); 819 CleanupAfterFetchComplete(); 820 } 821 822 void URLFetcherCancelTest::CancelRequest() { 823 delete fetcher_; 824 // The URLFetcher's test context will post a Quit task once it is 825 // deleted. So if this test simply hangs, it means cancellation 826 // did not work. 827 } 828 829 void URLFetcherMultipleAttemptTest::OnURLFetchComplete( 830 const URLFetcher* source) { 831 EXPECT_TRUE(source->GetStatus().is_success()); 832 EXPECT_EQ(200, source->GetResponseCode()); // HTTP OK 833 std::string data; 834 EXPECT_TRUE(source->GetResponseAsString(&data)); 835 EXPECT_FALSE(data.empty()); 836 if (!data.empty() && data_.empty()) { 837 data_ = data; 838 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 839 io_message_loop_proxy().get(), request_context())); 840 fetcher_->Start(); 841 } else { 842 EXPECT_EQ(data, data_); 843 CleanupAfterFetchComplete(); 844 } 845 } 846 847 void URLFetcherFileTest::CreateFetcherForFile(const GURL& url, 848 const base::FilePath& file_path) { 849 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 850 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 851 io_message_loop_proxy().get(), request_context())); 852 853 // Use the IO message loop to do the file operations in this test. 854 fetcher_->SaveResponseToFileAtPath(file_path, io_message_loop_proxy()); 855 fetcher_->Start(); 856 } 857 858 void URLFetcherFileTest::CreateFetcherForTempFile(const GURL& url) { 859 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); 860 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( 861 io_message_loop_proxy().get(), request_context())); 862 863 // Use the IO message loop to do the file operations in this test. 864 fetcher_->SaveResponseToTemporaryFile(io_message_loop_proxy()); 865 fetcher_->Start(); 866 } 867 868 void URLFetcherFileTest::OnURLFetchComplete(const URLFetcher* source) { 869 if (expected_file_error_ == OK) { 870 EXPECT_TRUE(source->GetStatus().is_success()); 871 EXPECT_EQ(source->GetResponseCode(), 200); 872 873 int error_code = OK; 874 EXPECT_FALSE(fetcher_->FileErrorOccurred(&error_code)); 875 876 EXPECT_TRUE(source->GetResponseAsFilePath( 877 take_ownership_of_file_, &file_path_)); 878 879 EXPECT_TRUE(base::ContentsEqual(expected_file_, file_path_)); 880 } else { 881 int error_code = OK; 882 EXPECT_TRUE(fetcher_->FileErrorOccurred(&error_code)); 883 EXPECT_EQ(expected_file_error_, error_code); 884 } 885 CleanupAfterFetchComplete(); 886 } 887 888 TEST_F(URLFetcherTest, SameThreadsTest) { 889 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 890 SpawnedTestServer::kLocalhost, 891 base::FilePath(kDocRoot)); 892 ASSERT_TRUE(test_server.Start()); 893 894 // Create the fetcher on the main thread. Since IO will happen on the main 895 // thread, this will test URLFetcher's ability to do everything on one 896 // thread. 897 CreateFetcher(test_server.GetURL("defaultresponse")); 898 899 base::MessageLoop::current()->Run(); 900 } 901 902 TEST_F(URLFetcherTest, DifferentThreadsTest) { 903 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 904 SpawnedTestServer::kLocalhost, 905 base::FilePath(kDocRoot)); 906 ASSERT_TRUE(test_server.Start()); 907 908 // Create a separate thread that will create the URLFetcher. The current 909 // (main) thread will do the IO, and when the fetch is complete it will 910 // terminate the main thread's message loop; then the other thread's 911 // message loop will be shut down automatically as the thread goes out of 912 // scope. 913 base::Thread t("URLFetcher test thread"); 914 ASSERT_TRUE(t.Start()); 915 t.message_loop()->PostTask( 916 FROM_HERE, 917 base::Bind(&URLFetcherTest::CreateFetcher, 918 base::Unretained(this), 919 test_server.GetURL("defaultresponse"))); 920 921 base::MessageLoop::current()->Run(); 922 } 923 924 void CancelAllOnIO() { 925 EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores()); 926 URLFetcherImpl::CancelAll(); 927 EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores()); 928 } 929 930 // Tests to make sure CancelAll() will successfully cancel existing URLFetchers. 931 TEST_F(URLFetcherTest, CancelAll) { 932 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 933 SpawnedTestServer::kLocalhost, 934 base::FilePath(kDocRoot)); 935 ASSERT_TRUE(test_server.Start()); 936 EXPECT_EQ(0, GetNumFetcherCores()); 937 938 CreateFetcher(test_server.GetURL("defaultresponse")); 939 io_message_loop_proxy()->PostTaskAndReply( 940 FROM_HERE, base::Bind(&CancelAllOnIO), base::MessageLoop::QuitClosure()); 941 base::MessageLoop::current()->Run(); 942 EXPECT_EQ(0, GetNumFetcherCores()); 943 delete fetcher_; 944 } 945 946 TEST_F(URLFetcherMockDnsTest, DontRetryOnNetworkChangedByDefault) { 947 EXPECT_EQ(0, GetNumFetcherCores()); 948 EXPECT_FALSE(resolver_.has_pending_requests()); 949 950 // This posts a task to start the fetcher. 951 CreateFetcher(test_url_); 952 fetcher_->Start(); 953 EXPECT_EQ(0, GetNumFetcherCores()); 954 base::MessageLoop::current()->RunUntilIdle(); 955 956 // The fetcher is now running, but is pending the host resolve. 957 EXPECT_EQ(1, GetNumFetcherCores()); 958 EXPECT_TRUE(resolver_.has_pending_requests()); 959 ASSERT_FALSE(completed_fetcher_); 960 961 // A network change notification aborts the connect job. 962 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 963 base::MessageLoop::current()->RunUntilIdle(); 964 EXPECT_EQ(0, GetNumFetcherCores()); 965 EXPECT_FALSE(resolver_.has_pending_requests()); 966 ASSERT_TRUE(completed_fetcher_); 967 968 // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error. 969 EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error()); 970 } 971 972 TEST_F(URLFetcherMockDnsTest, RetryOnNetworkChangedAndFail) { 973 EXPECT_EQ(0, GetNumFetcherCores()); 974 EXPECT_FALSE(resolver_.has_pending_requests()); 975 976 // This posts a task to start the fetcher. 977 CreateFetcher(test_url_); 978 fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); 979 fetcher_->Start(); 980 EXPECT_EQ(0, GetNumFetcherCores()); 981 base::MessageLoop::current()->RunUntilIdle(); 982 983 // The fetcher is now running, but is pending the host resolve. 984 EXPECT_EQ(1, GetNumFetcherCores()); 985 EXPECT_TRUE(resolver_.has_pending_requests()); 986 ASSERT_FALSE(completed_fetcher_); 987 988 // Make it fail 3 times. 989 for (int i = 0; i < 3; ++i) { 990 // A network change notification aborts the connect job. 991 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 992 base::MessageLoop::current()->RunUntilIdle(); 993 994 // But the fetcher retries automatically. 995 EXPECT_EQ(1, GetNumFetcherCores()); 996 EXPECT_TRUE(resolver_.has_pending_requests()); 997 ASSERT_FALSE(completed_fetcher_); 998 } 999 1000 // A 4th failure doesn't trigger another retry, and propagates the error 1001 // to the owner of the fetcher. 1002 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1003 base::MessageLoop::current()->RunUntilIdle(); 1004 EXPECT_EQ(0, GetNumFetcherCores()); 1005 EXPECT_FALSE(resolver_.has_pending_requests()); 1006 ASSERT_TRUE(completed_fetcher_); 1007 1008 // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error. 1009 EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error()); 1010 } 1011 1012 TEST_F(URLFetcherMockDnsTest, RetryOnNetworkChangedAndSucceed) { 1013 EXPECT_EQ(0, GetNumFetcherCores()); 1014 EXPECT_FALSE(resolver_.has_pending_requests()); 1015 1016 // This posts a task to start the fetcher. 1017 CreateFetcher(test_url_); 1018 fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); 1019 fetcher_->Start(); 1020 EXPECT_EQ(0, GetNumFetcherCores()); 1021 base::MessageLoop::current()->RunUntilIdle(); 1022 1023 // The fetcher is now running, but is pending the host resolve. 1024 EXPECT_EQ(1, GetNumFetcherCores()); 1025 EXPECT_TRUE(resolver_.has_pending_requests()); 1026 ASSERT_FALSE(completed_fetcher_); 1027 1028 // Make it fail 3 times. 1029 for (int i = 0; i < 3; ++i) { 1030 // A network change notification aborts the connect job. 1031 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1032 base::MessageLoop::current()->RunUntilIdle(); 1033 1034 // But the fetcher retries automatically. 1035 EXPECT_EQ(1, GetNumFetcherCores()); 1036 EXPECT_TRUE(resolver_.has_pending_requests()); 1037 ASSERT_FALSE(completed_fetcher_); 1038 } 1039 1040 // Now let it succeed by resolving the pending request. 1041 resolver_.ResolveAllPending(); 1042 base::MessageLoop::current()->Run(); 1043 1044 // URLFetcherMockDnsTest::OnURLFetchComplete() will quit the loop. 1045 EXPECT_EQ(0, GetNumFetcherCores()); 1046 EXPECT_FALSE(resolver_.has_pending_requests()); 1047 ASSERT_TRUE(completed_fetcher_); 1048 1049 // This time the request succeeded. 1050 EXPECT_EQ(OK, completed_fetcher_->GetStatus().error()); 1051 EXPECT_EQ(200, completed_fetcher_->GetResponseCode()); 1052 } 1053 1054 TEST_F(URLFetcherPostTest, Basic) { 1055 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1056 SpawnedTestServer::kLocalhost, 1057 base::FilePath(kDocRoot)); 1058 ASSERT_TRUE(test_server.Start()); 1059 1060 CreateFetcher(test_server.GetURL("echo")); 1061 base::MessageLoop::current()->Run(); 1062 } 1063 1064 TEST_F(URLFetcherPostFileTest, Basic) { 1065 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1066 SpawnedTestServer::kLocalhost, 1067 base::FilePath(kDocRoot)); 1068 ASSERT_TRUE(test_server.Start()); 1069 1070 CreateFetcher(test_server.GetURL("echo")); 1071 base::MessageLoop::current()->Run(); 1072 } 1073 1074 TEST_F(URLFetcherPostFileTest, Range) { 1075 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1076 SpawnedTestServer::kLocalhost, 1077 base::FilePath(kDocRoot)); 1078 ASSERT_TRUE(test_server.Start()); 1079 1080 SetUploadRange(30, 100); 1081 1082 CreateFetcher(test_server.GetURL("echo")); 1083 base::MessageLoop::current()->Run(); 1084 } 1085 1086 TEST_F(URLFetcherEmptyPostTest, Basic) { 1087 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1088 SpawnedTestServer::kLocalhost, 1089 base::FilePath(kDocRoot)); 1090 ASSERT_TRUE(test_server.Start()); 1091 1092 CreateFetcher(test_server.GetURL("echo")); 1093 base::MessageLoop::current()->Run(); 1094 } 1095 1096 TEST_F(URLFetcherUploadProgressTest, Basic) { 1097 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1098 SpawnedTestServer::kLocalhost, 1099 base::FilePath(kDocRoot)); 1100 ASSERT_TRUE(test_server.Start()); 1101 1102 CreateFetcher(test_server.GetURL("echo")); 1103 base::MessageLoop::current()->Run(); 1104 } 1105 1106 TEST_F(URLFetcherDownloadProgressTest, Basic) { 1107 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1108 SpawnedTestServer::kLocalhost, 1109 base::FilePath(kDocRoot)); 1110 ASSERT_TRUE(test_server.Start()); 1111 1112 // Get a file large enough to require more than one read into 1113 // URLFetcher::Core's IOBuffer. 1114 static const char kFileToFetch[] = "animate1.gif"; 1115 // Hardcoded file size - it cannot be easily fetched when a remote http server 1116 // is used for testing. 1117 static const int64 kFileSize = 19021; 1118 1119 expected_total_ = kFileSize; 1120 1121 CreateFetcher(test_server.GetURL( 1122 std::string(kTestServerFilePrefix) + kFileToFetch)); 1123 1124 base::MessageLoop::current()->Run(); 1125 } 1126 1127 TEST_F(URLFetcherDownloadProgressCancelTest, CancelWhileProgressReport) { 1128 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1129 SpawnedTestServer::kLocalhost, 1130 base::FilePath(kDocRoot)); 1131 ASSERT_TRUE(test_server.Start()); 1132 1133 // Get a file large enough to require more than one read into 1134 // URLFetcher::Core's IOBuffer. 1135 static const char kFileToFetch[] = "animate1.gif"; 1136 CreateFetcher(test_server.GetURL( 1137 std::string(kTestServerFilePrefix) + kFileToFetch)); 1138 1139 base::MessageLoop::current()->Run(); 1140 } 1141 1142 TEST_F(URLFetcherHeadersTest, Headers) { 1143 SpawnedTestServer test_server( 1144 SpawnedTestServer::TYPE_HTTP, 1145 SpawnedTestServer::kLocalhost, 1146 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); 1147 ASSERT_TRUE(test_server.Start()); 1148 1149 CreateFetcher(test_server.GetURL("files/with-headers.html")); 1150 base::MessageLoop::current()->Run(); 1151 // The actual tests are in the URLFetcherHeadersTest fixture. 1152 } 1153 1154 TEST_F(URLFetcherSocketAddressTest, SocketAddress) { 1155 SpawnedTestServer test_server( 1156 SpawnedTestServer::TYPE_HTTP, 1157 SpawnedTestServer::kLocalhost, 1158 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); 1159 ASSERT_TRUE(test_server.Start()); 1160 expected_port_ = test_server.host_port_pair().port(); 1161 1162 // Reusing "with-headers.html" but doesn't really matter. 1163 CreateFetcher(test_server.GetURL("files/with-headers.html")); 1164 base::MessageLoop::current()->Run(); 1165 // The actual tests are in the URLFetcherSocketAddressTest fixture. 1166 } 1167 1168 TEST_F(URLFetcherStopOnRedirectTest, StopOnRedirect) { 1169 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1170 SpawnedTestServer::kLocalhost, 1171 base::FilePath(kDocRoot)); 1172 ASSERT_TRUE(test_server.Start()); 1173 1174 CreateFetcher( 1175 test_server.GetURL(std::string("server-redirect?") + kRedirectTarget)); 1176 base::MessageLoop::current()->Run(); 1177 EXPECT_TRUE(callback_called_); 1178 } 1179 1180 TEST_F(URLFetcherProtectTest, Overload) { 1181 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1182 SpawnedTestServer::kLocalhost, 1183 base::FilePath(kDocRoot)); 1184 ASSERT_TRUE(test_server.Start()); 1185 1186 GURL url(test_server.GetURL("defaultresponse")); 1187 1188 // Registers an entry for test url. It only allows 3 requests to be sent 1189 // in 200 milliseconds. 1190 scoped_refptr<URLRequestThrottlerEntry> entry( 1191 new URLRequestThrottlerEntry(request_context()->throttler_manager(), 1192 std::string(), 1193 200, 1194 3, 1195 1, 1196 2.0, 1197 0.0, 1198 256)); 1199 request_context()->throttler_manager() 1200 ->OverrideEntryForTests(url, entry.get()); 1201 1202 CreateFetcher(url); 1203 1204 base::MessageLoop::current()->Run(); 1205 } 1206 1207 TEST_F(URLFetcherProtectTest, ServerUnavailable) { 1208 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1209 SpawnedTestServer::kLocalhost, 1210 base::FilePath(kDocRoot)); 1211 ASSERT_TRUE(test_server.Start()); 1212 1213 GURL url(test_server.GetURL("files/server-unavailable.html")); 1214 1215 // Registers an entry for test url. The backoff time is calculated by: 1216 // new_backoff = 2.0 * old_backoff + 0 1217 // and maximum backoff time is 256 milliseconds. 1218 // Maximum retries allowed is set to 11. 1219 scoped_refptr<URLRequestThrottlerEntry> entry( 1220 new URLRequestThrottlerEntry(request_context()->throttler_manager(), 1221 std::string(), 1222 200, 1223 3, 1224 1, 1225 2.0, 1226 0.0, 1227 256)); 1228 request_context()->throttler_manager() 1229 ->OverrideEntryForTests(url, entry.get()); 1230 1231 CreateFetcher(url); 1232 1233 base::MessageLoop::current()->Run(); 1234 } 1235 1236 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) { 1237 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1238 SpawnedTestServer::kLocalhost, 1239 base::FilePath(kDocRoot)); 1240 ASSERT_TRUE(test_server.Start()); 1241 1242 GURL url(test_server.GetURL("files/server-unavailable.html")); 1243 1244 // Registers an entry for test url. The backoff time is calculated by: 1245 // new_backoff = 2.0 * old_backoff + 0 1246 // and maximum backoff time is 150000 milliseconds. 1247 // Maximum retries allowed is set to 11. 1248 scoped_refptr<URLRequestThrottlerEntry> entry( 1249 new URLRequestThrottlerEntry(request_context()->throttler_manager(), 1250 std::string(), 1251 200, 1252 3, 1253 100, 1254 2.0, 1255 0.0, 1256 150000)); 1257 // Total time if *not* for not doing automatic backoff would be 150s. 1258 // In reality it should be "as soon as server responds". 1259 request_context()->throttler_manager() 1260 ->OverrideEntryForTests(url, entry.get()); 1261 1262 CreateFetcher(url); 1263 1264 base::MessageLoop::current()->Run(); 1265 } 1266 1267 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) { 1268 SpawnedTestServer::SSLOptions ssl_options( 1269 SpawnedTestServer::SSLOptions::CERT_EXPIRED); 1270 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 1271 ssl_options, 1272 base::FilePath(kDocRoot)); 1273 ASSERT_TRUE(test_server.Start()); 1274 1275 CreateFetcher(test_server.GetURL("defaultresponse")); 1276 base::MessageLoop::current()->Run(); 1277 } 1278 1279 TEST_F(URLFetcherCancelTest, ReleasesContext) { 1280 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1281 SpawnedTestServer::kLocalhost, 1282 base::FilePath(kDocRoot)); 1283 ASSERT_TRUE(test_server.Start()); 1284 1285 GURL url(test_server.GetURL("files/server-unavailable.html")); 1286 1287 // Create a separate thread that will create the URLFetcher. The current 1288 // (main) thread will do the IO, and when the fetch is complete it will 1289 // terminate the main thread's message loop; then the other thread's 1290 // message loop will be shut down automatically as the thread goes out of 1291 // scope. 1292 base::Thread t("URLFetcher test thread"); 1293 ASSERT_TRUE(t.Start()); 1294 t.message_loop()->PostTask( 1295 FROM_HERE, 1296 base::Bind(&URLFetcherCancelTest::CreateFetcher, 1297 base::Unretained(this), url)); 1298 1299 base::MessageLoop::current()->Run(); 1300 } 1301 1302 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) { 1303 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1304 SpawnedTestServer::kLocalhost, 1305 base::FilePath(kDocRoot)); 1306 ASSERT_TRUE(test_server.Start()); 1307 1308 GURL url(test_server.GetURL("files/server-unavailable.html")); 1309 1310 // Register an entry for test url. 1311 // Using a sliding window of 4 seconds, and max of 1 request, under a fast 1312 // run we expect to have a 4 second delay when posting the Start task. 1313 scoped_refptr<URLRequestThrottlerEntry> entry( 1314 new URLRequestThrottlerEntry(request_context()->throttler_manager(), 1315 std::string(), 1316 4000, 1317 1, 1318 2000, 1319 2.0, 1320 0.0, 1321 4000)); 1322 request_context()->throttler_manager() 1323 ->OverrideEntryForTests(url, entry.get()); 1324 // Fake that a request has just started. 1325 entry->ReserveSendingTimeForNextRequest(base::TimeTicks()); 1326 1327 // The next request we try to send will be delayed by ~4 seconds. 1328 // The slower the test runs, the less the delay will be (since it takes the 1329 // time difference from now). 1330 1331 base::Thread t("URLFetcher test thread"); 1332 ASSERT_TRUE(t.Start()); 1333 t.message_loop()->PostTask( 1334 FROM_HERE, 1335 base::Bind(&URLFetcherTest::CreateFetcher, base::Unretained(this), url)); 1336 1337 base::MessageLoop::current()->Run(); 1338 } 1339 1340 TEST_F(URLFetcherMultipleAttemptTest, SameData) { 1341 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1342 SpawnedTestServer::kLocalhost, 1343 base::FilePath(kDocRoot)); 1344 ASSERT_TRUE(test_server.Start()); 1345 1346 // Create the fetcher on the main thread. Since IO will happen on the main 1347 // thread, this will test URLFetcher's ability to do everything on one 1348 // thread. 1349 CreateFetcher(test_server.GetURL("defaultresponse")); 1350 1351 base::MessageLoop::current()->Run(); 1352 } 1353 1354 TEST_F(URLFetcherFileTest, SmallGet) { 1355 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1356 SpawnedTestServer::kLocalhost, 1357 base::FilePath(kDocRoot)); 1358 ASSERT_TRUE(test_server.Start()); 1359 1360 base::ScopedTempDir temp_dir; 1361 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1362 1363 // Get a small file. 1364 static const char kFileToFetch[] = "simple.html"; 1365 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1366 CreateFetcherForFile( 1367 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1368 temp_dir.path().AppendASCII(kFileToFetch)); 1369 1370 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1371 1372 ASSERT_FALSE(base::PathExists(file_path_)) 1373 << file_path_.value() << " not removed."; 1374 } 1375 1376 TEST_F(URLFetcherFileTest, LargeGet) { 1377 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1378 SpawnedTestServer::kLocalhost, 1379 base::FilePath(kDocRoot)); 1380 ASSERT_TRUE(test_server.Start()); 1381 1382 base::ScopedTempDir temp_dir; 1383 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1384 1385 // Get a file large enough to require more than one read into 1386 // URLFetcher::Core's IOBuffer. 1387 static const char kFileToFetch[] = "animate1.gif"; 1388 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1389 CreateFetcherForFile( 1390 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1391 temp_dir.path().AppendASCII(kFileToFetch)); 1392 1393 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1394 } 1395 1396 TEST_F(URLFetcherFileTest, SavedOutputFileOwnerhisp) { 1397 // If the caller takes the ownership of the output file, the file should 1398 // persist even after URLFetcher is gone. If not, the file must be deleted. 1399 const bool kTake[] = {false, true}; 1400 for (size_t i = 0; i < arraysize(kTake); ++i) { 1401 take_ownership_of_file_ = kTake[i]; 1402 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1403 SpawnedTestServer::kLocalhost, 1404 base::FilePath(kDocRoot)); 1405 ASSERT_TRUE(test_server.Start()); 1406 1407 base::ScopedTempDir temp_dir; 1408 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1409 1410 // Get a small file. 1411 static const char kFileToFetch[] = "simple.html"; 1412 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1413 CreateFetcherForFile( 1414 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1415 temp_dir.path().AppendASCII(kFileToFetch)); 1416 1417 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1418 1419 base::MessageLoop::current()->RunUntilIdle(); 1420 ASSERT_EQ(kTake[i], base::PathExists(file_path_)) << 1421 "FilePath: " << file_path_.value(); 1422 } 1423 } 1424 1425 TEST_F(URLFetcherFileTest, OverwriteExistingFile) { 1426 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1427 SpawnedTestServer::kLocalhost, 1428 base::FilePath(kDocRoot)); 1429 ASSERT_TRUE(test_server.Start()); 1430 1431 base::ScopedTempDir temp_dir; 1432 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1433 1434 // Create a file before trying to fetch. 1435 static const char kFileToFetch[] = "simple.html"; 1436 std::string data(10000, '?'); // Meant to be larger than simple.html. 1437 file_path_ = temp_dir.path().AppendASCII(kFileToFetch); 1438 ASSERT_EQ(static_cast<int>(data.size()), 1439 file_util::WriteFile(file_path_, data.data(), data.size())); 1440 ASSERT_TRUE(base::PathExists(file_path_)); 1441 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1442 ASSERT_FALSE(base::ContentsEqual(file_path_, expected_file_)); 1443 1444 // Get a small file. 1445 CreateFetcherForFile( 1446 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1447 file_path_); 1448 1449 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1450 } 1451 1452 TEST_F(URLFetcherFileTest, TryToOverwriteDirectory) { 1453 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1454 SpawnedTestServer::kLocalhost, 1455 base::FilePath(kDocRoot)); 1456 ASSERT_TRUE(test_server.Start()); 1457 1458 base::ScopedTempDir temp_dir; 1459 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1460 1461 // Create a directory before trying to fetch. 1462 static const char kFileToFetch[] = "simple.html"; 1463 file_path_ = temp_dir.path().AppendASCII(kFileToFetch); 1464 ASSERT_TRUE(file_util::CreateDirectory(file_path_)); 1465 ASSERT_TRUE(base::PathExists(file_path_)); 1466 1467 // Get a small file. 1468 expected_file_error_ = ERR_ACCESS_DENIED; 1469 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1470 CreateFetcherForFile( 1471 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1472 file_path_); 1473 1474 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1475 1476 base::MessageLoop::current()->RunUntilIdle(); 1477 } 1478 1479 TEST_F(URLFetcherFileTest, SmallGetToTempFile) { 1480 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1481 SpawnedTestServer::kLocalhost, 1482 base::FilePath(kDocRoot)); 1483 ASSERT_TRUE(test_server.Start()); 1484 1485 // Get a small file. 1486 static const char kFileToFetch[] = "simple.html"; 1487 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1488 CreateFetcherForTempFile( 1489 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch)); 1490 1491 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1492 1493 ASSERT_FALSE(base::PathExists(file_path_)) 1494 << file_path_.value() << " not removed."; 1495 } 1496 1497 TEST_F(URLFetcherFileTest, LargeGetToTempFile) { 1498 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1499 SpawnedTestServer::kLocalhost, 1500 base::FilePath(kDocRoot)); 1501 ASSERT_TRUE(test_server.Start()); 1502 1503 // Get a file large enough to require more than one read into 1504 // URLFetcher::Core's IOBuffer. 1505 static const char kFileToFetch[] = "animate1.gif"; 1506 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1507 CreateFetcherForTempFile(test_server.GetURL( 1508 std::string(kTestServerFilePrefix) + kFileToFetch)); 1509 1510 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1511 } 1512 1513 TEST_F(URLFetcherFileTest, SavedOutputTempFileOwnerhisp) { 1514 // If the caller takes the ownership of the temp file, the file should persist 1515 // even after URLFetcher is gone. If not, the file must be deleted. 1516 const bool kTake[] = {false, true}; 1517 for (size_t i = 0; i < arraysize(kTake); ++i) { 1518 take_ownership_of_file_ = kTake[i]; 1519 1520 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1521 SpawnedTestServer::kLocalhost, 1522 base::FilePath(kDocRoot)); 1523 ASSERT_TRUE(test_server.Start()); 1524 1525 // Get a small file. 1526 static const char kFileToFetch[] = "simple.html"; 1527 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1528 CreateFetcherForTempFile(test_server.GetURL( 1529 std::string(kTestServerFilePrefix) + kFileToFetch)); 1530 1531 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1532 1533 base::MessageLoop::current()->RunUntilIdle(); 1534 ASSERT_EQ(kTake[i], base::PathExists(file_path_)) << 1535 "FilePath: " << file_path_.value(); 1536 } 1537 } 1538 1539 } // namespace 1540 1541 } // namespace net 1542