| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 "base/message_loop_proxy.h" | |
| 6 #include "base/synchronization/waitable_event.h" | |
| 7 #include "base/threading/thread.h" | |
| 8 #include "build/build_config.h" | |
| 9 #include "chrome/common/net/url_fetcher.h" | |
| 10 #include "net/http/http_response_headers.h" | |
| 11 #include "net/test/test_server.h" | |
| 12 #include "net/url_request/url_request_context_getter.h" | |
| 13 #include "net/url_request/url_request_test_util.h" | |
| 14 #include "net/url_request/url_request_throttler_manager.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | |
| 16 | |
| 17 #if defined(USE_NSS) | |
| 18 #include "net/ocsp/nss_ocsp.h" | |
| 19 #endif | |
| 20 | |
| 21 using base::Time; | |
| 22 using base::TimeDelta; | |
| 23 | |
| 24 // TODO(eroman): Add a regression test for http://crbug.com/40505. | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data"); | |
| 29 const std::string kTestServerFilePrefix = "files/"; | |
| 30 | |
| 31 class CurriedTask : public Task { | |
| 32 public: | |
| 33 CurriedTask(Task* task, MessageLoop* target_loop) | |
| 34 : task_(task), | |
| 35 target_loop_(target_loop) {} | |
| 36 | |
| 37 virtual void Run() { | |
| 38 target_loop_->PostTask(FROM_HERE, task_); | |
| 39 } | |
| 40 | |
| 41 private: | |
| 42 Task* const task_; | |
| 43 MessageLoop* const target_loop_; | |
| 44 | |
| 45 DISALLOW_COPY_AND_ASSIGN(CurriedTask); | |
| 46 }; | |
| 47 | |
| 48 class TestURLRequestContextGetter : public net::URLRequestContextGetter { | |
| 49 public: | |
| 50 explicit TestURLRequestContextGetter( | |
| 51 base::MessageLoopProxy* io_message_loop_proxy) | |
| 52 : io_message_loop_proxy_(io_message_loop_proxy) { | |
| 53 } | |
| 54 virtual net::URLRequestContext* GetURLRequestContext() { | |
| 55 if (!context_) | |
| 56 context_ = new TestURLRequestContext(); | |
| 57 return context_; | |
| 58 } | |
| 59 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const { | |
| 60 return io_message_loop_proxy_; | |
| 61 } | |
| 62 | |
| 63 protected: | |
| 64 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | |
| 65 | |
| 66 private: | |
| 67 ~TestURLRequestContextGetter() {} | |
| 68 | |
| 69 scoped_refptr<net::URLRequestContext> context_; | |
| 70 }; | |
| 71 | |
| 72 } // namespace | |
| 73 | |
| 74 class URLFetcherTest : public testing::Test, public URLFetcher::Delegate { | |
| 75 public: | |
| 76 URLFetcherTest() : fetcher_(NULL) { } | |
| 77 | |
| 78 // Creates a URLFetcher, using the program's main thread to do IO. | |
| 79 virtual void CreateFetcher(const GURL& url); | |
| 80 | |
| 81 // URLFetcher::Delegate | |
| 82 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 83 const GURL& url, | |
| 84 const net::URLRequestStatus& status, | |
| 85 int response_code, | |
| 86 const net::ResponseCookies& cookies, | |
| 87 const std::string& data); | |
| 88 | |
| 89 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() { | |
| 90 return io_message_loop_proxy_; | |
| 91 } | |
| 92 | |
| 93 protected: | |
| 94 virtual void SetUp() { | |
| 95 testing::Test::SetUp(); | |
| 96 | |
| 97 io_message_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread(); | |
| 98 | |
| 99 #if defined(USE_NSS) | |
| 100 net::EnsureOCSPInit(); | |
| 101 #endif | |
| 102 } | |
| 103 | |
| 104 virtual void TearDown() { | |
| 105 #if defined(USE_NSS) | |
| 106 net::ShutdownOCSP(); | |
| 107 #endif | |
| 108 } | |
| 109 | |
| 110 int GetNumFetcherCores() const { | |
| 111 return URLFetcher::GetNumFetcherCores(); | |
| 112 } | |
| 113 | |
| 114 // URLFetcher is designed to run on the main UI thread, but in our tests | |
| 115 // we assume that the current thread is the IO thread where the URLFetcher | |
| 116 // dispatches its requests to. When we wish to simulate being used from | |
| 117 // a UI thread, we dispatch a worker thread to do so. | |
| 118 MessageLoopForIO io_loop_; | |
| 119 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | |
| 120 | |
| 121 URLFetcher* fetcher_; | |
| 122 }; | |
| 123 | |
| 124 void URLFetcherTest::CreateFetcher(const GURL& url) { | |
| 125 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
| 126 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
| 127 io_message_loop_proxy())); | |
| 128 fetcher_->Start(); | |
| 129 } | |
| 130 | |
| 131 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source, | |
| 132 const GURL& url, | |
| 133 const net::URLRequestStatus& status, | |
| 134 int response_code, | |
| 135 const net::ResponseCookies& cookies, | |
| 136 const std::string& data) { | |
| 137 EXPECT_TRUE(status.is_success()); | |
| 138 EXPECT_EQ(200, response_code); // HTTP OK | |
| 139 EXPECT_FALSE(data.empty()); | |
| 140 | |
| 141 delete fetcher_; // Have to delete this here and not in the destructor, | |
| 142 // because the destructor won't necessarily run on the | |
| 143 // same thread that CreateFetcher() did. | |
| 144 | |
| 145 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
| 146 // If the current message loop is not the IO loop, it will be shut down when | |
| 147 // the main loop returns and this thread subsequently goes out of scope. | |
| 148 } | |
| 149 | |
| 150 namespace { | |
| 151 | |
| 152 // Version of URLFetcherTest that does a POST instead | |
| 153 class URLFetcherPostTest : public URLFetcherTest { | |
| 154 public: | |
| 155 virtual void CreateFetcher(const GURL& url); | |
| 156 | |
| 157 // URLFetcher::Delegate | |
| 158 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 159 const GURL& url, | |
| 160 const net::URLRequestStatus& status, | |
| 161 int response_code, | |
| 162 const net::ResponseCookies& cookies, | |
| 163 const std::string& data); | |
| 164 }; | |
| 165 | |
| 166 // Version of URLFetcherTest that tests headers. | |
| 167 class URLFetcherHeadersTest : public URLFetcherTest { | |
| 168 public: | |
| 169 // URLFetcher::Delegate | |
| 170 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 171 const GURL& url, | |
| 172 const net::URLRequestStatus& status, | |
| 173 int response_code, | |
| 174 const net::ResponseCookies& cookies, | |
| 175 const std::string& data); | |
| 176 }; | |
| 177 | |
| 178 // Version of URLFetcherTest that tests SocketAddress. | |
| 179 class URLFetcherSocketAddressTest : public URLFetcherTest { | |
| 180 public: | |
| 181 // URLFetcher::Delegate | |
| 182 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 183 const GURL& url, | |
| 184 const net::URLRequestStatus& status, | |
| 185 int response_code, | |
| 186 const net::ResponseCookies& cookies, | |
| 187 const std::string& data); | |
| 188 protected: | |
| 189 std::string expected_host_; | |
| 190 uint16 expected_port_; | |
| 191 }; | |
| 192 | |
| 193 // Version of URLFetcherTest that tests overload protection. | |
| 194 class URLFetcherProtectTest : public URLFetcherTest { | |
| 195 public: | |
| 196 virtual void CreateFetcher(const GURL& url); | |
| 197 // URLFetcher::Delegate | |
| 198 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 199 const GURL& url, | |
| 200 const net::URLRequestStatus& status, | |
| 201 int response_code, | |
| 202 const net::ResponseCookies& cookies, | |
| 203 const std::string& data); | |
| 204 private: | |
| 205 Time start_time_; | |
| 206 }; | |
| 207 | |
| 208 // Version of URLFetcherTest that tests overload protection, when responses | |
| 209 // passed through. | |
| 210 class URLFetcherProtectTestPassedThrough : public URLFetcherTest { | |
| 211 public: | |
| 212 virtual void CreateFetcher(const GURL& url); | |
| 213 // URLFetcher::Delegate | |
| 214 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 215 const GURL& url, | |
| 216 const net::URLRequestStatus& status, | |
| 217 int response_code, | |
| 218 const net::ResponseCookies& cookies, | |
| 219 const std::string& data); | |
| 220 private: | |
| 221 Time start_time_; | |
| 222 }; | |
| 223 | |
| 224 // Version of URLFetcherTest that tests bad HTTPS requests. | |
| 225 class URLFetcherBadHTTPSTest : public URLFetcherTest { | |
| 226 public: | |
| 227 URLFetcherBadHTTPSTest(); | |
| 228 | |
| 229 // URLFetcher::Delegate | |
| 230 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 231 const GURL& url, | |
| 232 const net::URLRequestStatus& status, | |
| 233 int response_code, | |
| 234 const net::ResponseCookies& cookies, | |
| 235 const std::string& data); | |
| 236 | |
| 237 private: | |
| 238 FilePath cert_dir_; | |
| 239 }; | |
| 240 | |
| 241 // Version of URLFetcherTest that tests request cancellation on shutdown. | |
| 242 class URLFetcherCancelTest : public URLFetcherTest { | |
| 243 public: | |
| 244 virtual void CreateFetcher(const GURL& url); | |
| 245 // URLFetcher::Delegate | |
| 246 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 247 const GURL& url, | |
| 248 const net::URLRequestStatus& status, | |
| 249 int response_code, | |
| 250 const net::ResponseCookies& cookies, | |
| 251 const std::string& data); | |
| 252 | |
| 253 void CancelRequest(); | |
| 254 }; | |
| 255 | |
| 256 // Version of TestURLRequestContext that posts a Quit task to the IO | |
| 257 // thread once it is deleted. | |
| 258 class CancelTestURLRequestContext : public TestURLRequestContext { | |
| 259 virtual ~CancelTestURLRequestContext() { | |
| 260 // The d'tor should execute in the IO thread. Post the quit task to the | |
| 261 // current thread. | |
| 262 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
| 263 } | |
| 264 }; | |
| 265 | |
| 266 class CancelTestURLRequestContextGetter : public net::URLRequestContextGetter { | |
| 267 public: | |
| 268 explicit CancelTestURLRequestContextGetter( | |
| 269 base::MessageLoopProxy* io_message_loop_proxy) | |
| 270 : io_message_loop_proxy_(io_message_loop_proxy), | |
| 271 context_created_(false, false) { | |
| 272 } | |
| 273 virtual net::URLRequestContext* GetURLRequestContext() { | |
| 274 if (!context_) { | |
| 275 context_ = new CancelTestURLRequestContext(); | |
| 276 context_created_.Signal(); | |
| 277 } | |
| 278 return context_; | |
| 279 } | |
| 280 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const { | |
| 281 return io_message_loop_proxy_; | |
| 282 } | |
| 283 void WaitForContextCreation() { | |
| 284 context_created_.Wait(); | |
| 285 } | |
| 286 | |
| 287 private: | |
| 288 ~CancelTestURLRequestContextGetter() {} | |
| 289 | |
| 290 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | |
| 291 base::WaitableEvent context_created_; | |
| 292 scoped_refptr<net::URLRequestContext> context_; | |
| 293 }; | |
| 294 | |
| 295 // Version of URLFetcherTest that tests retying the same request twice. | |
| 296 class URLFetcherMultipleAttemptTest : public URLFetcherTest { | |
| 297 public: | |
| 298 // URLFetcher::Delegate | |
| 299 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 300 const GURL& url, | |
| 301 const net::URLRequestStatus& status, | |
| 302 int response_code, | |
| 303 const net::ResponseCookies& cookies, | |
| 304 const std::string& data); | |
| 305 private: | |
| 306 std::string data_; | |
| 307 }; | |
| 308 | |
| 309 class URLFetcherTempFileTest : public URLFetcherTest { | |
| 310 public: | |
| 311 URLFetcherTempFileTest() | |
| 312 : take_ownership_of_temp_file_(false) { | |
| 313 } | |
| 314 | |
| 315 // URLFetcher::Delegate | |
| 316 virtual void OnURLFetchComplete(const URLFetcher* source); | |
| 317 | |
| 318 // This obsolete signature should not be used, but must be present | |
| 319 // to make clang happy. | |
| 320 virtual void OnURLFetchComplete(const URLFetcher* source, | |
| 321 const GURL& url, | |
| 322 const net::URLRequestStatus& status, | |
| 323 int response_code, | |
| 324 const net::ResponseCookies& cookies, | |
| 325 const std::string& data); | |
| 326 | |
| 327 virtual void CreateFetcher(const GURL& url); | |
| 328 | |
| 329 protected: | |
| 330 FilePath expected_file_; | |
| 331 FilePath temp_file_; | |
| 332 | |
| 333 // Set by the test. Used in OnURLFetchComplete() to decide if | |
| 334 // the URLFetcher should own the temp file, so that we can test | |
| 335 // disowning prevents the file from being deleted. | |
| 336 bool take_ownership_of_temp_file_; | |
| 337 }; | |
| 338 | |
| 339 void URLFetcherTempFileTest::CreateFetcher(const GURL& url) { | |
| 340 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
| 341 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
| 342 io_message_loop_proxy())); | |
| 343 | |
| 344 // Use the IO message loop to do the file operations in this test. | |
| 345 fetcher_->SaveResponseToTemporaryFile(io_message_loop_proxy()); | |
| 346 fetcher_->Start(); | |
| 347 } | |
| 348 | |
| 349 TEST_F(URLFetcherTempFileTest, SmallGet) { | |
| 350 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 351 ASSERT_TRUE(test_server.Start()); | |
| 352 | |
| 353 // Get a small file. | |
| 354 const char* kFileToFetch = "simple.html"; | |
| 355 expected_file_ = test_server.document_root().AppendASCII(kFileToFetch); | |
| 356 CreateFetcher(test_server.GetURL(kTestServerFilePrefix + kFileToFetch)); | |
| 357 | |
| 358 MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). | |
| 359 | |
| 360 ASSERT_FALSE(file_util::PathExists(temp_file_)) | |
| 361 << temp_file_.value() << " not removed."; | |
| 362 } | |
| 363 | |
| 364 TEST_F(URLFetcherTempFileTest, LargeGet) { | |
| 365 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 366 ASSERT_TRUE(test_server.Start()); | |
| 367 | |
| 368 // Get a file large enough to require more than one read into | |
| 369 // URLFetcher::Core's IOBuffer. | |
| 370 const char* kFileToFetch = "animate1.gif"; | |
| 371 expected_file_ = test_server.document_root().AppendASCII(kFileToFetch); | |
| 372 CreateFetcher(test_server.GetURL(kTestServerFilePrefix + kFileToFetch)); | |
| 373 | |
| 374 MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). | |
| 375 } | |
| 376 | |
| 377 TEST_F(URLFetcherTempFileTest, CanTakeOwnershipOfFile) { | |
| 378 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 379 ASSERT_TRUE(test_server.Start()); | |
| 380 | |
| 381 // Get a small file. | |
| 382 const char* kFileToFetch = "simple.html"; | |
| 383 expected_file_ = test_server.document_root().AppendASCII(kFileToFetch); | |
| 384 CreateFetcher(test_server.GetURL(kTestServerFilePrefix + kFileToFetch)); | |
| 385 | |
| 386 MessageLoop::current()->Run(); // OnURLFetchComplete() will Quit(). | |
| 387 | |
| 388 MessageLoop::current()->RunAllPending(); | |
| 389 ASSERT_FALSE(file_util::PathExists(temp_file_)) | |
| 390 << temp_file_.value() << " not removed."; | |
| 391 } | |
| 392 | |
| 393 // Wrapper that lets us call CreateFetcher() on a thread of our choice. We | |
| 394 // could make URLFetcherTest refcounted and use PostTask(FROM_HERE.. ) to call | |
| 395 // CreateFetcher() directly, but the ownership of the URLFetcherTest is a bit | |
| 396 // confusing in that case because GTest doesn't know about the refcounting. | |
| 397 // It's less confusing to just do it this way. | |
| 398 class FetcherWrapperTask : public Task { | |
| 399 public: | |
| 400 FetcherWrapperTask(URLFetcherTest* test, const GURL& url) | |
| 401 : test_(test), url_(url) { } | |
| 402 virtual void Run() { | |
| 403 test_->CreateFetcher(url_); | |
| 404 } | |
| 405 | |
| 406 private: | |
| 407 URLFetcherTest* test_; | |
| 408 GURL url_; | |
| 409 }; | |
| 410 | |
| 411 void URLFetcherPostTest::CreateFetcher(const GURL& url) { | |
| 412 fetcher_ = new URLFetcher(url, URLFetcher::POST, this); | |
| 413 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
| 414 io_message_loop_proxy())); | |
| 415 fetcher_->set_upload_data("application/x-www-form-urlencoded", | |
| 416 "bobsyeruncle"); | |
| 417 fetcher_->Start(); | |
| 418 } | |
| 419 | |
| 420 void URLFetcherPostTest::OnURLFetchComplete(const URLFetcher* source, | |
| 421 const GURL& url, | |
| 422 const net::URLRequestStatus& status, | |
| 423 int response_code, | |
| 424 const net::ResponseCookies& cookies, | |
| 425 const std::string& data) { | |
| 426 EXPECT_EQ(std::string("bobsyeruncle"), data); | |
| 427 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, | |
| 428 cookies, data); | |
| 429 } | |
| 430 | |
| 431 void URLFetcherHeadersTest::OnURLFetchComplete( | |
| 432 const URLFetcher* source, | |
| 433 const GURL& url, | |
| 434 const net::URLRequestStatus& status, | |
| 435 int response_code, | |
| 436 const net::ResponseCookies& cookies, | |
| 437 const std::string& data) { | |
| 438 std::string header; | |
| 439 EXPECT_TRUE(source->response_headers()->GetNormalizedHeader("cache-control", | |
| 440 &header)); | |
| 441 EXPECT_EQ("private", header); | |
| 442 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, | |
| 443 cookies, data); | |
| 444 } | |
| 445 | |
| 446 void URLFetcherSocketAddressTest::OnURLFetchComplete( | |
| 447 const URLFetcher* source, | |
| 448 const GURL& url, | |
| 449 const net::URLRequestStatus& status, | |
| 450 int response_code, | |
| 451 const net::ResponseCookies& cookies, | |
| 452 const std::string& data) { | |
| 453 EXPECT_EQ("127.0.0.1", source->socket_address().host()); | |
| 454 EXPECT_EQ(expected_port_, source->socket_address().port()); | |
| 455 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, | |
| 456 cookies, data); | |
| 457 } | |
| 458 | |
| 459 void URLFetcherProtectTest::CreateFetcher(const GURL& url) { | |
| 460 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
| 461 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
| 462 io_message_loop_proxy())); | |
| 463 start_time_ = Time::Now(); | |
| 464 fetcher_->set_max_retries(11); | |
| 465 fetcher_->Start(); | |
| 466 } | |
| 467 | |
| 468 void URLFetcherProtectTest::OnURLFetchComplete( | |
| 469 const URLFetcher* source, | |
| 470 const GURL& url, | |
| 471 const net::URLRequestStatus& status, | |
| 472 int response_code, | |
| 473 const net::ResponseCookies& cookies, | |
| 474 const std::string& data) { | |
| 475 const TimeDelta one_second = TimeDelta::FromMilliseconds(1000); | |
| 476 if (response_code >= 500) { | |
| 477 // Now running ServerUnavailable test. | |
| 478 // It takes more than 1 second to finish all 11 requests. | |
| 479 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); | |
| 480 EXPECT_TRUE(status.is_success()); | |
| 481 EXPECT_FALSE(data.empty()); | |
| 482 delete fetcher_; | |
| 483 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
| 484 } else { | |
| 485 // Now running Overload test. | |
| 486 static int count = 0; | |
| 487 count++; | |
| 488 if (count < 20) { | |
| 489 fetcher_->Start(); | |
| 490 } else { | |
| 491 // We have already sent 20 requests continuously. And we expect that | |
| 492 // it takes more than 1 second due to the overload protection settings. | |
| 493 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); | |
| 494 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, | |
| 495 cookies, data); | |
| 496 } | |
| 497 } | |
| 498 } | |
| 499 | |
| 500 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) { | |
| 501 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
| 502 fetcher_->set_request_context(new TestURLRequestContextGetter( | |
| 503 io_message_loop_proxy())); | |
| 504 fetcher_->set_automatically_retry_on_5xx(false); | |
| 505 start_time_ = Time::Now(); | |
| 506 fetcher_->set_max_retries(11); | |
| 507 fetcher_->Start(); | |
| 508 } | |
| 509 | |
| 510 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete( | |
| 511 const URLFetcher* source, | |
| 512 const GURL& url, | |
| 513 const net::URLRequestStatus& status, | |
| 514 int response_code, | |
| 515 const net::ResponseCookies& cookies, | |
| 516 const std::string& data) { | |
| 517 const TimeDelta one_minute = TimeDelta::FromMilliseconds(60000); | |
| 518 if (response_code >= 500) { | |
| 519 // Now running ServerUnavailable test. | |
| 520 // It should get here on the first attempt, so almost immediately and | |
| 521 // *not* to attempt to execute all 11 requests (2.5 minutes). | |
| 522 EXPECT_TRUE(Time::Now() - start_time_ < one_minute); | |
| 523 EXPECT_TRUE(status.is_success()); | |
| 524 // Check that suggested back off time is bigger than 0. | |
| 525 EXPECT_GT(fetcher_->backoff_delay().InMicroseconds(), 0); | |
| 526 EXPECT_FALSE(data.empty()); | |
| 527 } else { | |
| 528 // We should not get here! | |
| 529 ADD_FAILURE(); | |
| 530 } | |
| 531 | |
| 532 delete fetcher_; | |
| 533 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
| 534 } | |
| 535 | |
| 536 | |
| 537 URLFetcherBadHTTPSTest::URLFetcherBadHTTPSTest() { | |
| 538 PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_); | |
| 539 cert_dir_ = cert_dir_.AppendASCII("chrome"); | |
| 540 cert_dir_ = cert_dir_.AppendASCII("test"); | |
| 541 cert_dir_ = cert_dir_.AppendASCII("data"); | |
| 542 cert_dir_ = cert_dir_.AppendASCII("ssl"); | |
| 543 cert_dir_ = cert_dir_.AppendASCII("certificates"); | |
| 544 } | |
| 545 | |
| 546 // The "server certificate expired" error should result in automatic | |
| 547 // cancellation of the request by | |
| 548 // net::URLRequest::Delegate::OnSSLCertificateError. | |
| 549 void URLFetcherBadHTTPSTest::OnURLFetchComplete( | |
| 550 const URLFetcher* source, | |
| 551 const GURL& url, | |
| 552 const net::URLRequestStatus& status, | |
| 553 int response_code, | |
| 554 const net::ResponseCookies& cookies, | |
| 555 const std::string& data) { | |
| 556 // This part is different from URLFetcherTest::OnURLFetchComplete | |
| 557 // because this test expects the request to be cancelled. | |
| 558 EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status()); | |
| 559 EXPECT_EQ(net::ERR_ABORTED, status.os_error()); | |
| 560 EXPECT_EQ(-1, response_code); | |
| 561 EXPECT_TRUE(cookies.empty()); | |
| 562 EXPECT_TRUE(data.empty()); | |
| 563 | |
| 564 // The rest is the same as URLFetcherTest::OnURLFetchComplete. | |
| 565 delete fetcher_; | |
| 566 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
| 567 } | |
| 568 | |
| 569 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { | |
| 570 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); | |
| 571 CancelTestURLRequestContextGetter* context_getter = | |
| 572 new CancelTestURLRequestContextGetter(io_message_loop_proxy()); | |
| 573 fetcher_->set_request_context(context_getter); | |
| 574 fetcher_->set_max_retries(2); | |
| 575 fetcher_->Start(); | |
| 576 // We need to wait for the creation of the net::URLRequestContext, since we | |
| 577 // rely on it being destroyed as a signal to end the test. | |
| 578 context_getter->WaitForContextCreation(); | |
| 579 CancelRequest(); | |
| 580 } | |
| 581 | |
| 582 void URLFetcherCancelTest::OnURLFetchComplete( | |
| 583 const URLFetcher* source, | |
| 584 const GURL& url, | |
| 585 const net::URLRequestStatus& status, | |
| 586 int response_code, | |
| 587 const net::ResponseCookies& cookies, | |
| 588 const std::string& data) { | |
| 589 // We should have cancelled the request before completion. | |
| 590 ADD_FAILURE(); | |
| 591 delete fetcher_; | |
| 592 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
| 593 } | |
| 594 | |
| 595 void URLFetcherCancelTest::CancelRequest() { | |
| 596 delete fetcher_; | |
| 597 // The URLFetcher's test context will post a Quit task once it is | |
| 598 // deleted. So if this test simply hangs, it means cancellation | |
| 599 // did not work. | |
| 600 } | |
| 601 | |
| 602 void URLFetcherMultipleAttemptTest::OnURLFetchComplete( | |
| 603 const URLFetcher* source, | |
| 604 const GURL& url, | |
| 605 const net::URLRequestStatus& status, | |
| 606 int response_code, | |
| 607 const net::ResponseCookies& cookies, | |
| 608 const std::string& data) { | |
| 609 EXPECT_TRUE(status.is_success()); | |
| 610 EXPECT_EQ(200, response_code); // HTTP OK | |
| 611 EXPECT_FALSE(data.empty()); | |
| 612 if (!data.empty() && data_.empty()) { | |
| 613 data_ = data; | |
| 614 fetcher_->Start(); | |
| 615 } else { | |
| 616 EXPECT_EQ(data, data_); | |
| 617 delete fetcher_; // Have to delete this here and not in the destructor, | |
| 618 // because the destructor won't necessarily run on the | |
| 619 // same thread that CreateFetcher() did. | |
| 620 | |
| 621 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
| 622 // If the current message loop is not the IO loop, it will be shut down when | |
| 623 // the main loop returns and this thread subsequently goes out of scope. | |
| 624 } | |
| 625 } | |
| 626 | |
| 627 void URLFetcherTempFileTest::OnURLFetchComplete(const URLFetcher* source) { | |
| 628 EXPECT_TRUE(source->status().is_success()); | |
| 629 EXPECT_EQ(source->response_code(), 200); | |
| 630 | |
| 631 EXPECT_TRUE(source->GetResponseAsFilePath( | |
| 632 take_ownership_of_temp_file_, &temp_file_)); | |
| 633 | |
| 634 EXPECT_TRUE(file_util::ContentsEqual(expected_file_, temp_file_)); | |
| 635 | |
| 636 delete fetcher_; | |
| 637 | |
| 638 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | |
| 639 } | |
| 640 | |
| 641 void URLFetcherTempFileTest::OnURLFetchComplete( | |
| 642 const URLFetcher* source, | |
| 643 const GURL& url, | |
| 644 const net::URLRequestStatus& status, | |
| 645 int response_code, | |
| 646 const net::ResponseCookies& cookies, | |
| 647 const std::string& data) { | |
| 648 NOTREACHED(); | |
| 649 } | |
| 650 | |
| 651 | |
| 652 TEST_F(URLFetcherTest, SameThreadsTest) { | |
| 653 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 654 ASSERT_TRUE(test_server.Start()); | |
| 655 | |
| 656 // Create the fetcher on the main thread. Since IO will happen on the main | |
| 657 // thread, this will test URLFetcher's ability to do everything on one | |
| 658 // thread. | |
| 659 CreateFetcher(test_server.GetURL("defaultresponse")); | |
| 660 | |
| 661 MessageLoop::current()->Run(); | |
| 662 } | |
| 663 | |
| 664 #if defined(OS_MACOSX) | |
| 665 // SIGSEGV on Mac: http://crbug.com/60426 | |
| 666 TEST_F(URLFetcherTest, DISABLED_DifferentThreadsTest) { | |
| 667 #else | |
| 668 TEST_F(URLFetcherTest, DifferentThreadsTest) { | |
| 669 #endif | |
| 670 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 671 ASSERT_TRUE(test_server.Start()); | |
| 672 | |
| 673 // Create a separate thread that will create the URLFetcher. The current | |
| 674 // (main) thread will do the IO, and when the fetch is complete it will | |
| 675 // terminate the main thread's message loop; then the other thread's | |
| 676 // message loop will be shut down automatically as the thread goes out of | |
| 677 // scope. | |
| 678 base::Thread t("URLFetcher test thread"); | |
| 679 ASSERT_TRUE(t.Start()); | |
| 680 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, | |
| 681 test_server.GetURL("defaultresponse"))); | |
| 682 | |
| 683 MessageLoop::current()->Run(); | |
| 684 } | |
| 685 | |
| 686 #if defined(OS_MACOSX) | |
| 687 // SIGSEGV on Mac: http://crbug.com/60426 | |
| 688 TEST_F(URLFetcherPostTest, DISABLED_Basic) { | |
| 689 #else | |
| 690 TEST_F(URLFetcherPostTest, Basic) { | |
| 691 #endif | |
| 692 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 693 ASSERT_TRUE(test_server.Start()); | |
| 694 | |
| 695 CreateFetcher(test_server.GetURL("echo")); | |
| 696 MessageLoop::current()->Run(); | |
| 697 } | |
| 698 | |
| 699 TEST_F(URLFetcherHeadersTest, Headers) { | |
| 700 net::TestServer test_server(net::TestServer::TYPE_HTTP, | |
| 701 FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
| 702 ASSERT_TRUE(test_server.Start()); | |
| 703 | |
| 704 CreateFetcher(test_server.GetURL("files/with-headers.html")); | |
| 705 MessageLoop::current()->Run(); | |
| 706 // The actual tests are in the URLFetcherHeadersTest fixture. | |
| 707 } | |
| 708 | |
| 709 TEST_F(URLFetcherSocketAddressTest, SocketAddress) { | |
| 710 net::TestServer test_server(net::TestServer::TYPE_HTTP, | |
| 711 FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
| 712 ASSERT_TRUE(test_server.Start()); | |
| 713 expected_port_ = test_server.host_port_pair().port(); | |
| 714 | |
| 715 // Reusing "with-headers.html" but doesn't really matter. | |
| 716 CreateFetcher(test_server.GetURL("files/with-headers.html")); | |
| 717 MessageLoop::current()->Run(); | |
| 718 // The actual tests are in the URLFetcherSocketAddressTest fixture. | |
| 719 } | |
| 720 | |
| 721 TEST_F(URLFetcherProtectTest, Overload) { | |
| 722 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 723 ASSERT_TRUE(test_server.Start()); | |
| 724 | |
| 725 GURL url(test_server.GetURL("defaultresponse")); | |
| 726 | |
| 727 // Registers an entry for test url. It only allows 3 requests to be sent | |
| 728 // in 200 milliseconds. | |
| 729 net::URLRequestThrottlerManager* manager = | |
| 730 net::URLRequestThrottlerManager::GetInstance(); | |
| 731 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
| 732 new net::URLRequestThrottlerEntry(manager, "", 200, 3, 1, 2.0, 0.0, 256)); | |
| 733 manager->OverrideEntryForTests(url, entry); | |
| 734 | |
| 735 CreateFetcher(url); | |
| 736 | |
| 737 MessageLoop::current()->Run(); | |
| 738 | |
| 739 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
| 740 } | |
| 741 | |
| 742 TEST_F(URLFetcherProtectTest, ServerUnavailable) { | |
| 743 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 744 ASSERT_TRUE(test_server.Start()); | |
| 745 | |
| 746 GURL url(test_server.GetURL("files/server-unavailable.html")); | |
| 747 | |
| 748 // Registers an entry for test url. The backoff time is calculated by: | |
| 749 // new_backoff = 2.0 * old_backoff + 0 | |
| 750 // and maximum backoff time is 256 milliseconds. | |
| 751 // Maximum retries allowed is set to 11. | |
| 752 net::URLRequestThrottlerManager* manager = | |
| 753 net::URLRequestThrottlerManager::GetInstance(); | |
| 754 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
| 755 new net::URLRequestThrottlerEntry(manager, "", 200, 3, 1, 2.0, 0.0, 256)); | |
| 756 manager->OverrideEntryForTests(url, entry); | |
| 757 | |
| 758 CreateFetcher(url); | |
| 759 | |
| 760 MessageLoop::current()->Run(); | |
| 761 | |
| 762 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
| 763 } | |
| 764 | |
| 765 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) { | |
| 766 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 767 ASSERT_TRUE(test_server.Start()); | |
| 768 | |
| 769 GURL url(test_server.GetURL("files/server-unavailable.html")); | |
| 770 | |
| 771 // Registers an entry for test url. The backoff time is calculated by: | |
| 772 // new_backoff = 2.0 * old_backoff + 0 | |
| 773 // and maximum backoff time is 150000 milliseconds. | |
| 774 // Maximum retries allowed is set to 11. | |
| 775 net::URLRequestThrottlerManager* manager = | |
| 776 net::URLRequestThrottlerManager::GetInstance(); | |
| 777 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
| 778 new net::URLRequestThrottlerEntry( | |
| 779 manager, "", 200, 3, 100, 2.0, 0.0, 150000)); | |
| 780 // Total time if *not* for not doing automatic backoff would be 150s. | |
| 781 // In reality it should be "as soon as server responds". | |
| 782 manager->OverrideEntryForTests(url, entry); | |
| 783 | |
| 784 CreateFetcher(url); | |
| 785 | |
| 786 MessageLoop::current()->Run(); | |
| 787 | |
| 788 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
| 789 } | |
| 790 | |
| 791 #if defined(OS_MACOSX) | |
| 792 // SIGSEGV on Mac: http://crbug.com/60426 | |
| 793 TEST_F(URLFetcherBadHTTPSTest, DISABLED_BadHTTPSTest) { | |
| 794 #else | |
| 795 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) { | |
| 796 #endif | |
| 797 net::TestServer::HTTPSOptions https_options( | |
| 798 net::TestServer::HTTPSOptions::CERT_EXPIRED); | |
| 799 net::TestServer test_server(https_options, FilePath(kDocRoot)); | |
| 800 ASSERT_TRUE(test_server.Start()); | |
| 801 | |
| 802 CreateFetcher(test_server.GetURL("defaultresponse")); | |
| 803 MessageLoop::current()->Run(); | |
| 804 } | |
| 805 | |
| 806 #if defined(OS_MACOSX) | |
| 807 // SIGSEGV on Mac: http://crbug.com/60426 | |
| 808 TEST_F(URLFetcherCancelTest, DISABLED_ReleasesContext) { | |
| 809 #else | |
| 810 TEST_F(URLFetcherCancelTest, ReleasesContext) { | |
| 811 #endif | |
| 812 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 813 ASSERT_TRUE(test_server.Start()); | |
| 814 | |
| 815 GURL url(test_server.GetURL("files/server-unavailable.html")); | |
| 816 | |
| 817 // Registers an entry for test url. The backoff time is calculated by: | |
| 818 // new_backoff = 2.0 * old_backoff +0 | |
| 819 // The initial backoff is 2 seconds and maximum backoff is 4 seconds. | |
| 820 // Maximum retries allowed is set to 2. | |
| 821 net::URLRequestThrottlerManager* manager = | |
| 822 net::URLRequestThrottlerManager::GetInstance(); | |
| 823 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
| 824 new net::URLRequestThrottlerEntry( | |
| 825 manager, "", 200, 3, 2000, 2.0, 0.0, 4000)); | |
| 826 manager->OverrideEntryForTests(url, entry); | |
| 827 | |
| 828 // Create a separate thread that will create the URLFetcher. The current | |
| 829 // (main) thread will do the IO, and when the fetch is complete it will | |
| 830 // terminate the main thread's message loop; then the other thread's | |
| 831 // message loop will be shut down automatically as the thread goes out of | |
| 832 // scope. | |
| 833 base::Thread t("URLFetcher test thread"); | |
| 834 ASSERT_TRUE(t.Start()); | |
| 835 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); | |
| 836 | |
| 837 MessageLoop::current()->Run(); | |
| 838 | |
| 839 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
| 840 } | |
| 841 | |
| 842 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) { | |
| 843 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 844 ASSERT_TRUE(test_server.Start()); | |
| 845 | |
| 846 GURL url(test_server.GetURL("files/server-unavailable.html")); | |
| 847 | |
| 848 // Register an entry for test url. | |
| 849 // Using a sliding window of 4 seconds, and max of 1 request, under a fast | |
| 850 // run we expect to have a 4 second delay when posting the Start task. | |
| 851 net::URLRequestThrottlerManager* manager = | |
| 852 net::URLRequestThrottlerManager::GetInstance(); | |
| 853 scoped_refptr<net::URLRequestThrottlerEntry> entry( | |
| 854 new net::URLRequestThrottlerEntry( | |
| 855 manager, "", 4000, 1, 2000, 2.0, 0.0, 4000)); | |
| 856 manager->OverrideEntryForTests(url, entry); | |
| 857 // Fake that a request has just started. | |
| 858 entry->ReserveSendingTimeForNextRequest(base::TimeTicks()); | |
| 859 | |
| 860 // The next request we try to send will be delayed by ~4 seconds. | |
| 861 // The slower the test runs, the less the delay will be (since it takes the | |
| 862 // time difference from now). | |
| 863 | |
| 864 base::Thread t("URLFetcher test thread"); | |
| 865 ASSERT_TRUE(t.Start()); | |
| 866 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); | |
| 867 | |
| 868 MessageLoop::current()->Run(); | |
| 869 | |
| 870 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url); | |
| 871 } | |
| 872 | |
| 873 TEST_F(URLFetcherMultipleAttemptTest, SameData) { | |
| 874 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 875 ASSERT_TRUE(test_server.Start()); | |
| 876 | |
| 877 // Create the fetcher on the main thread. Since IO will happen on the main | |
| 878 // thread, this will test URLFetcher's ability to do everything on one | |
| 879 // thread. | |
| 880 CreateFetcher(test_server.GetURL("defaultresponse")); | |
| 881 | |
| 882 MessageLoop::current()->Run(); | |
| 883 } | |
| 884 | |
| 885 // Tests to make sure CancelAll() will successfully cancel existing URLFetchers. | |
| 886 TEST_F(URLFetcherTest, CancelAll) { | |
| 887 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); | |
| 888 ASSERT_TRUE(test_server.Start()); | |
| 889 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 890 | |
| 891 CreateFetcher(test_server.GetURL("defaultresponse")); | |
| 892 io_message_loop_proxy()->PostTask( | |
| 893 FROM_HERE, | |
| 894 new CurriedTask(new MessageLoop::QuitTask(), MessageLoop::current())); | |
| 895 MessageLoop::current()->Run(); | |
| 896 EXPECT_EQ(1, GetNumFetcherCores()); | |
| 897 URLFetcher::CancelAll(); | |
| 898 EXPECT_EQ(0, GetNumFetcherCores()); | |
| 899 delete fetcher_; | |
| 900 } | |
| 901 | |
| 902 } // namespace. | |
| OLD | NEW |