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(base::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(OK, source->GetStatus().error()); 872 EXPECT_EQ(200, source->GetResponseCode()); 873 874 EXPECT_TRUE(source->GetResponseAsFilePath( 875 take_ownership_of_file_, &file_path_)); 876 877 EXPECT_TRUE(base::ContentsEqual(expected_file_, file_path_)); 878 } else { 879 EXPECT_FALSE(source->GetStatus().is_success()); 880 EXPECT_EQ(expected_file_error_, source->GetStatus().error()); 881 } 882 CleanupAfterFetchComplete(); 883 } 884 885 TEST_F(URLFetcherTest, SameThreadsTest) { 886 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 887 SpawnedTestServer::kLocalhost, 888 base::FilePath(kDocRoot)); 889 ASSERT_TRUE(test_server.Start()); 890 891 // Create the fetcher on the main thread. Since IO will happen on the main 892 // thread, this will test URLFetcher's ability to do everything on one 893 // thread. 894 CreateFetcher(test_server.GetURL("defaultresponse")); 895 896 base::MessageLoop::current()->Run(); 897 } 898 899 TEST_F(URLFetcherTest, DifferentThreadsTest) { 900 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 901 SpawnedTestServer::kLocalhost, 902 base::FilePath(kDocRoot)); 903 ASSERT_TRUE(test_server.Start()); 904 905 // Create a separate thread that will create the URLFetcher. The current 906 // (main) thread will do the IO, and when the fetch is complete it will 907 // terminate the main thread's message loop; then the other thread's 908 // message loop will be shut down automatically as the thread goes out of 909 // scope. 910 base::Thread t("URLFetcher test thread"); 911 ASSERT_TRUE(t.Start()); 912 t.message_loop()->PostTask( 913 FROM_HERE, 914 base::Bind(&URLFetcherTest::CreateFetcher, 915 base::Unretained(this), 916 test_server.GetURL("defaultresponse"))); 917 918 base::MessageLoop::current()->Run(); 919 } 920 921 void CancelAllOnIO() { 922 EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores()); 923 URLFetcherImpl::CancelAll(); 924 EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores()); 925 } 926 927 // Tests to make sure CancelAll() will successfully cancel existing URLFetchers. 928 TEST_F(URLFetcherTest, CancelAll) { 929 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 930 SpawnedTestServer::kLocalhost, 931 base::FilePath(kDocRoot)); 932 ASSERT_TRUE(test_server.Start()); 933 EXPECT_EQ(0, GetNumFetcherCores()); 934 935 CreateFetcher(test_server.GetURL("defaultresponse")); 936 io_message_loop_proxy()->PostTaskAndReply( 937 FROM_HERE, base::Bind(&CancelAllOnIO), base::MessageLoop::QuitClosure()); 938 base::MessageLoop::current()->Run(); 939 EXPECT_EQ(0, GetNumFetcherCores()); 940 delete fetcher_; 941 } 942 943 TEST_F(URLFetcherMockDnsTest, DontRetryOnNetworkChangedByDefault) { 944 EXPECT_EQ(0, GetNumFetcherCores()); 945 EXPECT_FALSE(resolver_.has_pending_requests()); 946 947 // This posts a task to start the fetcher. 948 CreateFetcher(test_url_); 949 fetcher_->Start(); 950 EXPECT_EQ(0, GetNumFetcherCores()); 951 base::MessageLoop::current()->RunUntilIdle(); 952 953 // The fetcher is now running, but is pending the host resolve. 954 EXPECT_EQ(1, GetNumFetcherCores()); 955 EXPECT_TRUE(resolver_.has_pending_requests()); 956 ASSERT_FALSE(completed_fetcher_); 957 958 // A network change notification aborts the connect job. 959 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 960 base::MessageLoop::current()->RunUntilIdle(); 961 EXPECT_EQ(0, GetNumFetcherCores()); 962 EXPECT_FALSE(resolver_.has_pending_requests()); 963 ASSERT_TRUE(completed_fetcher_); 964 965 // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error. 966 EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error()); 967 } 968 969 TEST_F(URLFetcherMockDnsTest, RetryOnNetworkChangedAndFail) { 970 EXPECT_EQ(0, GetNumFetcherCores()); 971 EXPECT_FALSE(resolver_.has_pending_requests()); 972 973 // This posts a task to start the fetcher. 974 CreateFetcher(test_url_); 975 fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); 976 fetcher_->Start(); 977 EXPECT_EQ(0, GetNumFetcherCores()); 978 base::MessageLoop::current()->RunUntilIdle(); 979 980 // The fetcher is now running, but is pending the host resolve. 981 EXPECT_EQ(1, GetNumFetcherCores()); 982 EXPECT_TRUE(resolver_.has_pending_requests()); 983 ASSERT_FALSE(completed_fetcher_); 984 985 // Make it fail 3 times. 986 for (int i = 0; i < 3; ++i) { 987 // A network change notification aborts the connect job. 988 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 989 base::MessageLoop::current()->RunUntilIdle(); 990 991 // But the fetcher retries automatically. 992 EXPECT_EQ(1, GetNumFetcherCores()); 993 EXPECT_TRUE(resolver_.has_pending_requests()); 994 ASSERT_FALSE(completed_fetcher_); 995 } 996 997 // A 4th failure doesn't trigger another retry, and propagates the error 998 // to the owner of the fetcher. 999 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1000 base::MessageLoop::current()->RunUntilIdle(); 1001 EXPECT_EQ(0, GetNumFetcherCores()); 1002 EXPECT_FALSE(resolver_.has_pending_requests()); 1003 ASSERT_TRUE(completed_fetcher_); 1004 1005 // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error. 1006 EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error()); 1007 } 1008 1009 TEST_F(URLFetcherMockDnsTest, RetryOnNetworkChangedAndSucceed) { 1010 EXPECT_EQ(0, GetNumFetcherCores()); 1011 EXPECT_FALSE(resolver_.has_pending_requests()); 1012 1013 // This posts a task to start the fetcher. 1014 CreateFetcher(test_url_); 1015 fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); 1016 fetcher_->Start(); 1017 EXPECT_EQ(0, GetNumFetcherCores()); 1018 base::MessageLoop::current()->RunUntilIdle(); 1019 1020 // The fetcher is now running, but is pending the host resolve. 1021 EXPECT_EQ(1, GetNumFetcherCores()); 1022 EXPECT_TRUE(resolver_.has_pending_requests()); 1023 ASSERT_FALSE(completed_fetcher_); 1024 1025 // Make it fail 3 times. 1026 for (int i = 0; i < 3; ++i) { 1027 // A network change notification aborts the connect job. 1028 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1029 base::MessageLoop::current()->RunUntilIdle(); 1030 1031 // But the fetcher retries automatically. 1032 EXPECT_EQ(1, GetNumFetcherCores()); 1033 EXPECT_TRUE(resolver_.has_pending_requests()); 1034 ASSERT_FALSE(completed_fetcher_); 1035 } 1036 1037 // Now let it succeed by resolving the pending request. 1038 resolver_.ResolveAllPending(); 1039 base::MessageLoop::current()->Run(); 1040 1041 // URLFetcherMockDnsTest::OnURLFetchComplete() will quit the loop. 1042 EXPECT_EQ(0, GetNumFetcherCores()); 1043 EXPECT_FALSE(resolver_.has_pending_requests()); 1044 ASSERT_TRUE(completed_fetcher_); 1045 1046 // This time the request succeeded. 1047 EXPECT_EQ(OK, completed_fetcher_->GetStatus().error()); 1048 EXPECT_EQ(200, completed_fetcher_->GetResponseCode()); 1049 } 1050 1051 TEST_F(URLFetcherPostTest, Basic) { 1052 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1053 SpawnedTestServer::kLocalhost, 1054 base::FilePath(kDocRoot)); 1055 ASSERT_TRUE(test_server.Start()); 1056 1057 CreateFetcher(test_server.GetURL("echo")); 1058 base::MessageLoop::current()->Run(); 1059 } 1060 1061 TEST_F(URLFetcherPostFileTest, Basic) { 1062 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1063 SpawnedTestServer::kLocalhost, 1064 base::FilePath(kDocRoot)); 1065 ASSERT_TRUE(test_server.Start()); 1066 1067 CreateFetcher(test_server.GetURL("echo")); 1068 base::MessageLoop::current()->Run(); 1069 } 1070 1071 TEST_F(URLFetcherPostFileTest, Range) { 1072 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1073 SpawnedTestServer::kLocalhost, 1074 base::FilePath(kDocRoot)); 1075 ASSERT_TRUE(test_server.Start()); 1076 1077 SetUploadRange(30, 100); 1078 1079 CreateFetcher(test_server.GetURL("echo")); 1080 base::MessageLoop::current()->Run(); 1081 } 1082 1083 TEST_F(URLFetcherEmptyPostTest, Basic) { 1084 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1085 SpawnedTestServer::kLocalhost, 1086 base::FilePath(kDocRoot)); 1087 ASSERT_TRUE(test_server.Start()); 1088 1089 CreateFetcher(test_server.GetURL("echo")); 1090 base::MessageLoop::current()->Run(); 1091 } 1092 1093 TEST_F(URLFetcherUploadProgressTest, Basic) { 1094 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1095 SpawnedTestServer::kLocalhost, 1096 base::FilePath(kDocRoot)); 1097 ASSERT_TRUE(test_server.Start()); 1098 1099 CreateFetcher(test_server.GetURL("echo")); 1100 base::MessageLoop::current()->Run(); 1101 } 1102 1103 TEST_F(URLFetcherDownloadProgressTest, Basic) { 1104 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1105 SpawnedTestServer::kLocalhost, 1106 base::FilePath(kDocRoot)); 1107 ASSERT_TRUE(test_server.Start()); 1108 1109 // Get a file large enough to require more than one read into 1110 // URLFetcher::Core's IOBuffer. 1111 static const char kFileToFetch[] = "animate1.gif"; 1112 // Hardcoded file size - it cannot be easily fetched when a remote http server 1113 // is used for testing. 1114 static const int64 kFileSize = 19021; 1115 1116 expected_total_ = kFileSize; 1117 1118 CreateFetcher(test_server.GetURL( 1119 std::string(kTestServerFilePrefix) + kFileToFetch)); 1120 1121 base::MessageLoop::current()->Run(); 1122 } 1123 1124 TEST_F(URLFetcherDownloadProgressCancelTest, CancelWhileProgressReport) { 1125 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1126 SpawnedTestServer::kLocalhost, 1127 base::FilePath(kDocRoot)); 1128 ASSERT_TRUE(test_server.Start()); 1129 1130 // Get a file large enough to require more than one read into 1131 // URLFetcher::Core's IOBuffer. 1132 static const char kFileToFetch[] = "animate1.gif"; 1133 CreateFetcher(test_server.GetURL( 1134 std::string(kTestServerFilePrefix) + kFileToFetch)); 1135 1136 base::MessageLoop::current()->Run(); 1137 } 1138 1139 TEST_F(URLFetcherHeadersTest, Headers) { 1140 SpawnedTestServer test_server( 1141 SpawnedTestServer::TYPE_HTTP, 1142 SpawnedTestServer::kLocalhost, 1143 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); 1144 ASSERT_TRUE(test_server.Start()); 1145 1146 CreateFetcher(test_server.GetURL("files/with-headers.html")); 1147 base::MessageLoop::current()->Run(); 1148 // The actual tests are in the URLFetcherHeadersTest fixture. 1149 } 1150 1151 TEST_F(URLFetcherSocketAddressTest, SocketAddress) { 1152 SpawnedTestServer test_server( 1153 SpawnedTestServer::TYPE_HTTP, 1154 SpawnedTestServer::kLocalhost, 1155 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); 1156 ASSERT_TRUE(test_server.Start()); 1157 expected_port_ = test_server.host_port_pair().port(); 1158 1159 // Reusing "with-headers.html" but doesn't really matter. 1160 CreateFetcher(test_server.GetURL("files/with-headers.html")); 1161 base::MessageLoop::current()->Run(); 1162 // The actual tests are in the URLFetcherSocketAddressTest fixture. 1163 } 1164 1165 TEST_F(URLFetcherStopOnRedirectTest, StopOnRedirect) { 1166 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1167 SpawnedTestServer::kLocalhost, 1168 base::FilePath(kDocRoot)); 1169 ASSERT_TRUE(test_server.Start()); 1170 1171 CreateFetcher( 1172 test_server.GetURL(std::string("server-redirect?") + kRedirectTarget)); 1173 base::MessageLoop::current()->Run(); 1174 EXPECT_TRUE(callback_called_); 1175 } 1176 1177 TEST_F(URLFetcherProtectTest, Overload) { 1178 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1179 SpawnedTestServer::kLocalhost, 1180 base::FilePath(kDocRoot)); 1181 ASSERT_TRUE(test_server.Start()); 1182 1183 GURL url(test_server.GetURL("defaultresponse")); 1184 1185 // Registers an entry for test url. It only allows 3 requests to be sent 1186 // in 200 milliseconds. 1187 scoped_refptr<URLRequestThrottlerEntry> entry( 1188 new URLRequestThrottlerEntry(request_context()->throttler_manager(), 1189 std::string(), 1190 200, 1191 3, 1192 1, 1193 2.0, 1194 0.0, 1195 256)); 1196 request_context()->throttler_manager() 1197 ->OverrideEntryForTests(url, entry.get()); 1198 1199 CreateFetcher(url); 1200 1201 base::MessageLoop::current()->Run(); 1202 } 1203 1204 TEST_F(URLFetcherProtectTest, ServerUnavailable) { 1205 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1206 SpawnedTestServer::kLocalhost, 1207 base::FilePath(kDocRoot)); 1208 ASSERT_TRUE(test_server.Start()); 1209 1210 GURL url(test_server.GetURL("files/server-unavailable.html")); 1211 1212 // Registers an entry for test url. The backoff time is calculated by: 1213 // new_backoff = 2.0 * old_backoff + 0 1214 // and maximum backoff time is 256 milliseconds. 1215 // Maximum retries allowed is set to 11. 1216 scoped_refptr<URLRequestThrottlerEntry> entry( 1217 new URLRequestThrottlerEntry(request_context()->throttler_manager(), 1218 std::string(), 1219 200, 1220 3, 1221 1, 1222 2.0, 1223 0.0, 1224 256)); 1225 request_context()->throttler_manager() 1226 ->OverrideEntryForTests(url, entry.get()); 1227 1228 CreateFetcher(url); 1229 1230 base::MessageLoop::current()->Run(); 1231 } 1232 1233 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) { 1234 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1235 SpawnedTestServer::kLocalhost, 1236 base::FilePath(kDocRoot)); 1237 ASSERT_TRUE(test_server.Start()); 1238 1239 GURL url(test_server.GetURL("files/server-unavailable.html")); 1240 1241 // Registers an entry for test url. The backoff time is calculated by: 1242 // new_backoff = 2.0 * old_backoff + 0 1243 // and maximum backoff time is 150000 milliseconds. 1244 // Maximum retries allowed is set to 11. 1245 scoped_refptr<URLRequestThrottlerEntry> entry( 1246 new URLRequestThrottlerEntry(request_context()->throttler_manager(), 1247 std::string(), 1248 200, 1249 3, 1250 100, 1251 2.0, 1252 0.0, 1253 150000)); 1254 // Total time if *not* for not doing automatic backoff would be 150s. 1255 // In reality it should be "as soon as server responds". 1256 request_context()->throttler_manager() 1257 ->OverrideEntryForTests(url, entry.get()); 1258 1259 CreateFetcher(url); 1260 1261 base::MessageLoop::current()->Run(); 1262 } 1263 1264 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) { 1265 SpawnedTestServer::SSLOptions ssl_options( 1266 SpawnedTestServer::SSLOptions::CERT_EXPIRED); 1267 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 1268 ssl_options, 1269 base::FilePath(kDocRoot)); 1270 ASSERT_TRUE(test_server.Start()); 1271 1272 CreateFetcher(test_server.GetURL("defaultresponse")); 1273 base::MessageLoop::current()->Run(); 1274 } 1275 1276 TEST_F(URLFetcherCancelTest, ReleasesContext) { 1277 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1278 SpawnedTestServer::kLocalhost, 1279 base::FilePath(kDocRoot)); 1280 ASSERT_TRUE(test_server.Start()); 1281 1282 GURL url(test_server.GetURL("files/server-unavailable.html")); 1283 1284 // Create a separate thread that will create the URLFetcher. The current 1285 // (main) thread will do the IO, and when the fetch is complete it will 1286 // terminate the main thread's message loop; then the other thread's 1287 // message loop will be shut down automatically as the thread goes out of 1288 // scope. 1289 base::Thread t("URLFetcher test thread"); 1290 ASSERT_TRUE(t.Start()); 1291 t.message_loop()->PostTask( 1292 FROM_HERE, 1293 base::Bind(&URLFetcherCancelTest::CreateFetcher, 1294 base::Unretained(this), url)); 1295 1296 base::MessageLoop::current()->Run(); 1297 } 1298 1299 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) { 1300 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1301 SpawnedTestServer::kLocalhost, 1302 base::FilePath(kDocRoot)); 1303 ASSERT_TRUE(test_server.Start()); 1304 1305 GURL url(test_server.GetURL("files/server-unavailable.html")); 1306 1307 // Register an entry for test url. 1308 // Using a sliding window of 4 seconds, and max of 1 request, under a fast 1309 // run we expect to have a 4 second delay when posting the Start task. 1310 scoped_refptr<URLRequestThrottlerEntry> entry( 1311 new URLRequestThrottlerEntry(request_context()->throttler_manager(), 1312 std::string(), 1313 4000, 1314 1, 1315 2000, 1316 2.0, 1317 0.0, 1318 4000)); 1319 request_context()->throttler_manager() 1320 ->OverrideEntryForTests(url, entry.get()); 1321 // Fake that a request has just started. 1322 entry->ReserveSendingTimeForNextRequest(base::TimeTicks()); 1323 1324 // The next request we try to send will be delayed by ~4 seconds. 1325 // The slower the test runs, the less the delay will be (since it takes the 1326 // time difference from now). 1327 1328 base::Thread t("URLFetcher test thread"); 1329 ASSERT_TRUE(t.Start()); 1330 t.message_loop()->PostTask( 1331 FROM_HERE, 1332 base::Bind(&URLFetcherTest::CreateFetcher, base::Unretained(this), url)); 1333 1334 base::MessageLoop::current()->Run(); 1335 } 1336 1337 TEST_F(URLFetcherMultipleAttemptTest, SameData) { 1338 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1339 SpawnedTestServer::kLocalhost, 1340 base::FilePath(kDocRoot)); 1341 ASSERT_TRUE(test_server.Start()); 1342 1343 // Create the fetcher on the main thread. Since IO will happen on the main 1344 // thread, this will test URLFetcher's ability to do everything on one 1345 // thread. 1346 CreateFetcher(test_server.GetURL("defaultresponse")); 1347 1348 base::MessageLoop::current()->Run(); 1349 } 1350 1351 TEST_F(URLFetcherFileTest, SmallGet) { 1352 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1353 SpawnedTestServer::kLocalhost, 1354 base::FilePath(kDocRoot)); 1355 ASSERT_TRUE(test_server.Start()); 1356 1357 base::ScopedTempDir temp_dir; 1358 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1359 1360 // Get a small file. 1361 static const char kFileToFetch[] = "simple.html"; 1362 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1363 CreateFetcherForFile( 1364 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1365 temp_dir.path().AppendASCII(kFileToFetch)); 1366 1367 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1368 1369 ASSERT_FALSE(base::PathExists(file_path_)) 1370 << file_path_.value() << " not removed."; 1371 } 1372 1373 TEST_F(URLFetcherFileTest, LargeGet) { 1374 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1375 SpawnedTestServer::kLocalhost, 1376 base::FilePath(kDocRoot)); 1377 ASSERT_TRUE(test_server.Start()); 1378 1379 base::ScopedTempDir temp_dir; 1380 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1381 1382 // Get a file large enough to require more than one read into 1383 // URLFetcher::Core's IOBuffer. 1384 static const char kFileToFetch[] = "animate1.gif"; 1385 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1386 CreateFetcherForFile( 1387 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1388 temp_dir.path().AppendASCII(kFileToFetch)); 1389 1390 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1391 } 1392 1393 TEST_F(URLFetcherFileTest, SavedOutputFileOwnerhisp) { 1394 // If the caller takes the ownership of the output file, the file should 1395 // persist even after URLFetcher is gone. If not, the file must be deleted. 1396 const bool kTake[] = {false, true}; 1397 for (size_t i = 0; i < arraysize(kTake); ++i) { 1398 take_ownership_of_file_ = kTake[i]; 1399 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1400 SpawnedTestServer::kLocalhost, 1401 base::FilePath(kDocRoot)); 1402 ASSERT_TRUE(test_server.Start()); 1403 1404 base::ScopedTempDir temp_dir; 1405 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1406 1407 // Get a small file. 1408 static const char kFileToFetch[] = "simple.html"; 1409 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1410 CreateFetcherForFile( 1411 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1412 temp_dir.path().AppendASCII(kFileToFetch)); 1413 1414 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1415 1416 base::MessageLoop::current()->RunUntilIdle(); 1417 ASSERT_EQ(kTake[i], base::PathExists(file_path_)) << 1418 "FilePath: " << file_path_.value(); 1419 } 1420 } 1421 1422 TEST_F(URLFetcherFileTest, OverwriteExistingFile) { 1423 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1424 SpawnedTestServer::kLocalhost, 1425 base::FilePath(kDocRoot)); 1426 ASSERT_TRUE(test_server.Start()); 1427 1428 base::ScopedTempDir temp_dir; 1429 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1430 1431 // Create a file before trying to fetch. 1432 static const char kFileToFetch[] = "simple.html"; 1433 std::string data(10000, '?'); // Meant to be larger than simple.html. 1434 file_path_ = temp_dir.path().AppendASCII(kFileToFetch); 1435 ASSERT_EQ(static_cast<int>(data.size()), 1436 file_util::WriteFile(file_path_, data.data(), data.size())); 1437 ASSERT_TRUE(base::PathExists(file_path_)); 1438 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1439 ASSERT_FALSE(base::ContentsEqual(file_path_, expected_file_)); 1440 1441 // Get a small file. 1442 CreateFetcherForFile( 1443 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1444 file_path_); 1445 1446 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1447 } 1448 1449 TEST_F(URLFetcherFileTest, TryToOverwriteDirectory) { 1450 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1451 SpawnedTestServer::kLocalhost, 1452 base::FilePath(kDocRoot)); 1453 ASSERT_TRUE(test_server.Start()); 1454 1455 base::ScopedTempDir temp_dir; 1456 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1457 1458 // Create a directory before trying to fetch. 1459 static const char kFileToFetch[] = "simple.html"; 1460 file_path_ = temp_dir.path().AppendASCII(kFileToFetch); 1461 ASSERT_TRUE(base::CreateDirectory(file_path_)); 1462 ASSERT_TRUE(base::PathExists(file_path_)); 1463 1464 // Get a small file. 1465 expected_file_error_ = ERR_ACCESS_DENIED; 1466 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1467 CreateFetcherForFile( 1468 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch), 1469 file_path_); 1470 1471 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1472 1473 base::MessageLoop::current()->RunUntilIdle(); 1474 } 1475 1476 TEST_F(URLFetcherFileTest, SmallGetToTempFile) { 1477 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1478 SpawnedTestServer::kLocalhost, 1479 base::FilePath(kDocRoot)); 1480 ASSERT_TRUE(test_server.Start()); 1481 1482 // Get a small file. 1483 static const char kFileToFetch[] = "simple.html"; 1484 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1485 CreateFetcherForTempFile( 1486 test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch)); 1487 1488 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1489 1490 ASSERT_FALSE(base::PathExists(file_path_)) 1491 << file_path_.value() << " not removed."; 1492 } 1493 1494 TEST_F(URLFetcherFileTest, LargeGetToTempFile) { 1495 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1496 SpawnedTestServer::kLocalhost, 1497 base::FilePath(kDocRoot)); 1498 ASSERT_TRUE(test_server.Start()); 1499 1500 // Get a file large enough to require more than one read into 1501 // URLFetcher::Core's IOBuffer. 1502 static const char kFileToFetch[] = "animate1.gif"; 1503 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1504 CreateFetcherForTempFile(test_server.GetURL( 1505 std::string(kTestServerFilePrefix) + kFileToFetch)); 1506 1507 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1508 } 1509 1510 TEST_F(URLFetcherFileTest, SavedOutputTempFileOwnerhisp) { 1511 // If the caller takes the ownership of the temp file, the file should persist 1512 // even after URLFetcher is gone. If not, the file must be deleted. 1513 const bool kTake[] = {false, true}; 1514 for (size_t i = 0; i < arraysize(kTake); ++i) { 1515 take_ownership_of_file_ = kTake[i]; 1516 1517 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, 1518 SpawnedTestServer::kLocalhost, 1519 base::FilePath(kDocRoot)); 1520 ASSERT_TRUE(test_server.Start()); 1521 1522 // Get a small file. 1523 static const char kFileToFetch[] = "simple.html"; 1524 expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch); 1525 CreateFetcherForTempFile(test_server.GetURL( 1526 std::string(kTestServerFilePrefix) + kFileToFetch)); 1527 1528 base::MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). 1529 1530 base::MessageLoop::current()->RunUntilIdle(); 1531 ASSERT_EQ(kTake[i], base::PathExists(file_path_)) << 1532 "FilePath: " << file_path_.value(); 1533 } 1534 } 1535 1536 } // namespace 1537 1538 } // namespace net 1539