Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/url_request/url_fetcher_impl.h" | 5 #include "net/url_request/url_fetcher_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 void OnURLFetchUploadProgress(const URLFetcher* source, | 399 void OnURLFetchUploadProgress(const URLFetcher* source, |
| 400 int64 current, | 400 int64 current, |
| 401 int64 total) override; | 401 int64 total) override; |
| 402 | 402 |
| 403 protected: | 403 protected: |
| 404 int64 previous_progress_; | 404 int64 previous_progress_; |
| 405 std::string chunk_; | 405 std::string chunk_; |
| 406 int64 number_of_chunks_added_; | 406 int64 number_of_chunks_added_; |
| 407 }; | 407 }; |
| 408 | 408 |
| 409 // Version of URLFetcherTest that tests bad HTTPS requests. | |
| 410 class URLFetcherBadHTTPSTest : public URLFetcherTest { | |
| 411 public: | |
| 412 URLFetcherBadHTTPSTest(); | |
| 413 | |
| 414 // URLFetcherTest: | |
| 415 void SetUpServer() override; | |
| 416 | |
| 417 // URLFetcherDelegate: | |
| 418 void OnURLFetchComplete(const URLFetcher* source) override; | |
| 419 | |
| 420 private: | |
| 421 base::FilePath cert_dir_; | |
| 422 }; | |
| 423 | |
| 424 // Version of URLFetcherTest that tests request cancellation on shutdown. | 409 // Version of URLFetcherTest that tests request cancellation on shutdown. |
| 425 class URLFetcherCancelTest : public URLFetcherTest { | 410 class URLFetcherCancelTest : public URLFetcherTest { |
| 426 public: | 411 public: |
| 427 // URLFetcherTest: | 412 // URLFetcherTest: |
| 428 void CreateFetcher(const GURL& url) override; | 413 void CreateFetcher(const GURL& url) override; |
| 429 | 414 |
| 430 // URLFetcherDelegate: | 415 // URLFetcherDelegate: |
| 431 void OnURLFetchComplete(const URLFetcher* source) override; | 416 void OnURLFetchComplete(const URLFetcher* source) override; |
| 432 | 417 |
| 433 void CancelRequest(); | 418 void CancelRequest(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 protected: | 484 protected: |
| 500 ~CancelTestURLRequestContextGetter() override {} | 485 ~CancelTestURLRequestContextGetter() override {} |
| 501 | 486 |
| 502 private: | 487 private: |
| 503 scoped_ptr<TestURLRequestContext> context_; | 488 scoped_ptr<TestURLRequestContext> context_; |
| 504 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 489 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
| 505 base::WaitableEvent context_created_; | 490 base::WaitableEvent context_created_; |
| 506 GURL throttle_for_url_; | 491 GURL throttle_for_url_; |
| 507 }; | 492 }; |
| 508 | 493 |
| 509 // Version of URLFetcherTest that tests retying the same request twice. | 494 // Version of URLFetcherTest that tests bad HTTPS requests. |
| 510 class URLFetcherMultipleAttemptTest : public URLFetcherTest { | 495 class URLFetcherBadHTTPSTest : public URLFetcherTest { |
|
mmenke
2015/04/16 19:33:28
Moved this test fixture (Which we have to keep) an
| |
| 511 public: | 496 public: |
| 512 // URLFetcherDelegate: | 497 URLFetcherBadHTTPSTest() {} |
| 513 void OnURLFetchComplete(const URLFetcher* source) override; | |
| 514 | 498 |
| 515 private: | 499 // URLFetcherTest: |
| 516 std::string data_; | 500 void SetUpServer() override { |
| 501 SpawnedTestServer::SSLOptions ssl_options( | |
| 502 SpawnedTestServer::SSLOptions::CERT_EXPIRED); | |
| 503 test_server_.reset(new SpawnedTestServer( | |
| 504 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath(kDocRoot))); | |
| 505 } | |
| 517 }; | 506 }; |
| 518 | 507 |
| 519 void URLFetcherDownloadProgressTest::CreateFetcher(const GURL& url) { | 508 void URLFetcherDownloadProgressTest::CreateFetcher(const GURL& url) { |
| 520 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); | 509 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); |
| 521 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( | 510 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( |
| 522 io_message_loop_proxy().get(), request_context())); | 511 io_message_loop_proxy().get(), request_context())); |
| 523 fetcher_->Start(); | 512 fetcher_->Start(); |
| 524 } | 513 } |
| 525 | 514 |
| 526 void URLFetcherDownloadProgressTest::OnURLFetchDownloadProgress( | 515 void URLFetcherDownloadProgressTest::OnURLFetchDownloadProgress( |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 EXPECT_LE(previous_progress_, current); | 569 EXPECT_LE(previous_progress_, current); |
| 581 previous_progress_ = current; | 570 previous_progress_ = current; |
| 582 EXPECT_EQ(-1, total); | 571 EXPECT_EQ(-1, total); |
| 583 | 572 |
| 584 if (number_of_chunks_added_ < 2) { | 573 if (number_of_chunks_added_ < 2) { |
| 585 number_of_chunks_added_ += 1; | 574 number_of_chunks_added_ += 1; |
| 586 fetcher_->AppendChunkToUpload(chunk_, true); | 575 fetcher_->AppendChunkToUpload(chunk_, true); |
| 587 } | 576 } |
| 588 } | 577 } |
| 589 | 578 |
| 590 URLFetcherBadHTTPSTest::URLFetcherBadHTTPSTest() { | |
| 591 PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_); | |
| 592 cert_dir_ = cert_dir_.AppendASCII("chrome"); | |
| 593 cert_dir_ = cert_dir_.AppendASCII("test"); | |
| 594 cert_dir_ = cert_dir_.AppendASCII("data"); | |
| 595 cert_dir_ = cert_dir_.AppendASCII("ssl"); | |
| 596 cert_dir_ = cert_dir_.AppendASCII("certificates"); | |
| 597 } | |
| 598 | |
| 599 void URLFetcherBadHTTPSTest::SetUpServer() { | |
| 600 SpawnedTestServer::SSLOptions ssl_options( | |
| 601 SpawnedTestServer::SSLOptions::CERT_EXPIRED); | |
| 602 test_server_.reset(new SpawnedTestServer( | |
| 603 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath(kDocRoot))); | |
| 604 } | |
| 605 | |
| 606 // The "server certificate expired" error should result in automatic | |
| 607 // cancellation of the request by | |
| 608 // URLRequest::Delegate::OnSSLCertificateError. | |
| 609 void URLFetcherBadHTTPSTest::OnURLFetchComplete( | |
| 610 const URLFetcher* source) { | |
| 611 // This part is different from URLFetcherTest::OnURLFetchComplete | |
| 612 // because this test expects the request to be cancelled. | |
| 613 EXPECT_EQ(URLRequestStatus::CANCELED, source->GetStatus().status()); | |
| 614 EXPECT_EQ(ERR_ABORTED, source->GetStatus().error()); | |
| 615 EXPECT_EQ(-1, source->GetResponseCode()); | |
| 616 EXPECT_TRUE(source->GetCookies().empty()); | |
| 617 std::string data; | |
| 618 EXPECT_TRUE(source->GetResponseAsString(&data)); | |
| 619 EXPECT_TRUE(data.empty()); | |
| 620 CleanupAfterFetchComplete(); | |
| 621 } | |
| 622 | |
| 623 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { | 579 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { |
| 624 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); | 580 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); |
| 625 CancelTestURLRequestContextGetter* context_getter = | 581 CancelTestURLRequestContextGetter* context_getter = |
| 626 new CancelTestURLRequestContextGetter(io_message_loop_proxy().get(), url); | 582 new CancelTestURLRequestContextGetter(io_message_loop_proxy().get(), url); |
| 627 fetcher_->SetRequestContext(context_getter); | 583 fetcher_->SetRequestContext(context_getter); |
| 628 fetcher_->SetMaxRetriesOn5xx(2); | 584 fetcher_->SetMaxRetriesOn5xx(2); |
| 629 fetcher_->Start(); | 585 fetcher_->Start(); |
| 630 // We need to wait for the creation of the URLRequestContext, since we | 586 // We need to wait for the creation of the URLRequestContext, since we |
| 631 // rely on it being destroyed as a signal to end the test. | 587 // rely on it being destroyed as a signal to end the test. |
| 632 context_getter->WaitForContextCreation(); | 588 context_getter->WaitForContextCreation(); |
| 633 CancelRequest(); | 589 CancelRequest(); |
| 634 } | 590 } |
| 635 | 591 |
| 636 void URLFetcherCancelTest::OnURLFetchComplete( | 592 void URLFetcherCancelTest::OnURLFetchComplete( |
| 637 const URLFetcher* source) { | 593 const URLFetcher* source) { |
| 638 // We should have cancelled the request before completion. | 594 // We should have cancelled the request before completion. |
| 639 ADD_FAILURE(); | 595 ADD_FAILURE(); |
| 640 CleanupAfterFetchComplete(); | 596 CleanupAfterFetchComplete(); |
| 641 } | 597 } |
| 642 | 598 |
| 643 void URLFetcherCancelTest::CancelRequest() { | 599 void URLFetcherCancelTest::CancelRequest() { |
| 644 delete fetcher_; | 600 delete fetcher_; |
| 645 // The URLFetcher's test context will post a Quit task once it is | 601 // The URLFetcher's test context will post a Quit task once it is |
| 646 // deleted. So if this test simply hangs, it means cancellation | 602 // deleted. So if this test simply hangs, it means cancellation |
| 647 // did not work. | 603 // did not work. |
| 648 } | 604 } |
| 649 | 605 |
| 650 void URLFetcherMultipleAttemptTest::OnURLFetchComplete( | |
| 651 const URLFetcher* source) { | |
| 652 EXPECT_TRUE(source->GetStatus().is_success()); | |
| 653 EXPECT_EQ(200, source->GetResponseCode()); // HTTP OK | |
| 654 std::string data; | |
| 655 EXPECT_TRUE(source->GetResponseAsString(&data)); | |
| 656 EXPECT_FALSE(data.empty()); | |
| 657 if (!data.empty() && data_.empty()) { | |
| 658 data_ = data; | |
| 659 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( | |
| 660 io_message_loop_proxy().get(), request_context())); | |
| 661 fetcher_->Start(); | |
| 662 } else { | |
| 663 EXPECT_EQ(data, data_); | |
| 664 CleanupAfterFetchComplete(); | |
| 665 } | |
| 666 } | |
| 667 | |
| 668 // Create the fetcher on the main thread. Since network IO will happen on the | 606 // Create the fetcher on the main thread. Since network IO will happen on the |
| 669 // main thread, this will test URLFetcher's ability to do everything on one | 607 // main thread, this will test URLFetcher's ability to do everything on one |
| 670 // thread. | 608 // thread. |
| 671 TEST_F(URLFetcherTest, SameThreadTest) { | 609 TEST_F(URLFetcherTest, SameThreadTest) { |
| 672 WaitingURLFetcherDelegate delegate; | 610 WaitingURLFetcherDelegate delegate; |
| 673 delegate.CreateFetcherWithContext(test_server_->GetURL(kDefaultResponsePath), | 611 delegate.CreateFetcherWithContext(test_server_->GetURL(kDefaultResponsePath), |
| 674 URLFetcher::GET, request_context()); | 612 URLFetcher::GET, request_context()); |
| 675 delegate.StartFetcherAndWait(); | 613 delegate.StartFetcherAndWait(); |
| 676 | 614 |
| 677 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); | 615 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1120 std::string data; | 1058 std::string data; |
| 1121 ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); | 1059 ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); |
| 1122 EXPECT_FALSE(data.empty()); | 1060 EXPECT_FALSE(data.empty()); |
| 1123 EXPECT_GT(delegate.fetcher()->GetBackoffDelay().InMicroseconds(), 0); | 1061 EXPECT_GT(delegate.fetcher()->GetBackoffDelay().InMicroseconds(), 0); |
| 1124 | 1062 |
| 1125 // The request should not have been retried at all. If it had attempted all | 1063 // The request should not have been retried at all. If it had attempted all |
| 1126 // 11 retries, that should have taken 2.5 minutes. | 1064 // 11 retries, that should have taken 2.5 minutes. |
| 1127 EXPECT_TRUE(Time::Now() - start_time < TimeDelta::FromMinutes(1)); | 1065 EXPECT_TRUE(Time::Now() - start_time < TimeDelta::FromMinutes(1)); |
| 1128 } | 1066 } |
| 1129 | 1067 |
| 1130 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) { | |
| 1131 CreateFetcher(test_server_->GetURL(kDefaultResponsePath)); | |
| 1132 base::MessageLoop::current()->Run(); | |
| 1133 } | |
| 1134 | |
| 1135 TEST_F(URLFetcherCancelTest, ReleasesContext) { | 1068 TEST_F(URLFetcherCancelTest, ReleasesContext) { |
| 1136 GURL url(test_server_->GetURL("files/server-unavailable.html")); | 1069 GURL url(test_server_->GetURL("files/server-unavailable.html")); |
| 1137 | 1070 |
| 1138 // Create a separate thread that will create the URLFetcher. The current | 1071 // Create a separate thread that will create the URLFetcher. The current |
| 1139 // (main) thread will do the IO, and when the fetch is complete it will | 1072 // (main) thread will do the IO, and when the fetch is complete it will |
| 1140 // terminate the main thread's message loop; then the other thread's | 1073 // terminate the main thread's message loop; then the other thread's |
| 1141 // message loop will be shut down automatically as the thread goes out of | 1074 // message loop will be shut down automatically as the thread goes out of |
| 1142 // scope. | 1075 // scope. |
| 1143 base::Thread t("URLFetcher test thread"); | 1076 base::Thread t("URLFetcher test thread"); |
| 1144 ASSERT_TRUE(t.Start()); | 1077 ASSERT_TRUE(t.Start()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1176 | 1109 |
| 1177 base::Thread t("URLFetcher test thread"); | 1110 base::Thread t("URLFetcher test thread"); |
| 1178 ASSERT_TRUE(t.Start()); | 1111 ASSERT_TRUE(t.Start()); |
| 1179 t.message_loop()->PostTask( | 1112 t.message_loop()->PostTask( |
| 1180 FROM_HERE, | 1113 FROM_HERE, |
| 1181 base::Bind(&URLFetcherTest::CreateFetcher, base::Unretained(this), url)); | 1114 base::Bind(&URLFetcherTest::CreateFetcher, base::Unretained(this), url)); |
| 1182 | 1115 |
| 1183 base::MessageLoop::current()->Run(); | 1116 base::MessageLoop::current()->Run(); |
| 1184 } | 1117 } |
| 1185 | 1118 |
| 1186 TEST_F(URLFetcherMultipleAttemptTest, SameData) { | 1119 // A URLFetcherDelegate that expects to receive a response body of "request1" |
| 1187 // Create the fetcher on the main thread. Since IO will happen on the main | 1120 // and then reuses the fetcher for the same URL, setting the "test" request |
| 1188 // thread, this will test URLFetcher's ability to do everything on one | 1121 // header to "request2". |
| 1189 // thread. | 1122 class ReuseFetcherDelegate : public WaitingURLFetcherDelegate { |
| 1190 CreateFetcher(test_server_->GetURL(kDefaultResponsePath)); | 1123 public: |
| 1124 // |second_request_context_getter| is the context getter used for the second | |
| 1125 // request. Can't reuse the old one because fetchers release it on completion. | |
|
davidben
2015/04/16 21:48:39
Yuck. :-P I don't have a much better suggestion th
| |
| 1126 ReuseFetcherDelegate( | |
| 1127 scoped_refptr<URLRequestContextGetter> second_request_context_getter) | |
| 1128 : first_request_complete_(false), | |
| 1129 second_request_context_getter_(second_request_context_getter) {} | |
| 1191 | 1130 |
| 1192 base::MessageLoop::current()->Run(); | 1131 ~ReuseFetcherDelegate() override {} |
| 1132 | |
| 1133 void OnURLFetchComplete(const URLFetcher* source) override { | |
| 1134 EXPECT_EQ(fetcher(), source); | |
| 1135 if (!first_request_complete_) { | |
| 1136 first_request_complete_ = true; | |
| 1137 EXPECT_TRUE(fetcher()->GetStatus().is_success()); | |
| 1138 EXPECT_EQ(200, fetcher()->GetResponseCode()); | |
| 1139 std::string data; | |
| 1140 ASSERT_TRUE(fetcher()->GetResponseAsString(&data)); | |
| 1141 EXPECT_EQ("request1", data); | |
| 1142 | |
| 1143 fetcher()->SetRequestContext(second_request_context_getter_.get()); | |
| 1144 fetcher()->SetExtraRequestHeaders("test: request2"); | |
| 1145 fetcher()->Start(); | |
| 1146 return; | |
| 1147 } | |
| 1148 WaitingURLFetcherDelegate::OnURLFetchComplete(source); | |
| 1149 } | |
| 1150 | |
| 1151 private: | |
| 1152 bool first_request_complete_; | |
| 1153 scoped_refptr<URLRequestContextGetter> second_request_context_getter_; | |
| 1154 | |
| 1155 DISALLOW_COPY_AND_ASSIGN(ReuseFetcherDelegate); | |
| 1156 }; | |
| 1157 | |
| 1158 TEST_F(URLFetcherTest, ReuseFetcherForSameURL) { | |
| 1159 // TODO(mmenke): It's really weird that this is supported, particularly | |
| 1160 // some fields can be modified between requests, but some (Like upload body) | |
| 1161 // cannot be. Can we get rid of support for this? | |
|
davidben
2015/04/16 21:48:39
Especially weird that you have to specify a new ge
mmenke
2015/04/16 21:56:29
I think the intent is to prevent the fetcher from
| |
| 1162 ReuseFetcherDelegate delegate(new TrivialURLRequestContextGetter( | |
| 1163 request_context(), base::MessageLoopProxy::current())); | |
| 1164 delegate.CreateFetcherWithContext(test_server_->GetURL("echoheader?test"), | |
| 1165 URLFetcher::GET, request_context()); | |
| 1166 delegate.fetcher()->SetExtraRequestHeaders("test: request1"); | |
| 1167 delegate.StartFetcherAndWait(); | |
| 1168 | |
| 1169 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); | |
| 1170 EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); | |
| 1171 std::string data; | |
| 1172 ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); | |
| 1173 EXPECT_EQ("request2", data); | |
| 1193 } | 1174 } |
| 1194 | 1175 |
| 1195 // Get a small file. | 1176 // Get a small file. |
| 1196 TEST_F(URLFetcherTest, FileTestSmallGet) { | 1177 TEST_F(URLFetcherTest, FileTestSmallGet) { |
| 1197 const char kFileToFetch[] = "simple.html"; | 1178 const char kFileToFetch[] = "simple.html"; |
| 1198 | 1179 |
| 1199 base::ScopedTempDir temp_dir; | 1180 base::ScopedTempDir temp_dir; |
| 1200 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 1181 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 1201 base::FilePath out_path = temp_dir.path().AppendASCII(kFileToFetch); | 1182 base::FilePath out_path = temp_dir.path().AppendASCII(kFileToFetch); |
| 1202 SaveFileTest(kFileToFetch, false, out_path, false); | 1183 SaveFileTest(kFileToFetch, false, out_path, false); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1274 TEST_F(URLFetcherTest, TempFileTestLargeGet) { | 1255 TEST_F(URLFetcherTest, TempFileTestLargeGet) { |
| 1275 SaveFileTest("animate1.gif", true, base::FilePath(), false); | 1256 SaveFileTest("animate1.gif", true, base::FilePath(), false); |
| 1276 } | 1257 } |
| 1277 | 1258 |
| 1278 // If the caller takes the ownership of the temp file, check that the file | 1259 // If the caller takes the ownership of the temp file, check that the file |
| 1279 // persists even after URLFetcher is gone. | 1260 // persists even after URLFetcher is gone. |
| 1280 TEST_F(URLFetcherTest, TempFileTestTakeOwnership) { | 1261 TEST_F(URLFetcherTest, TempFileTestTakeOwnership) { |
| 1281 SaveFileTest("simple.html", true, base::FilePath(), true); | 1262 SaveFileTest("simple.html", true, base::FilePath(), true); |
| 1282 } | 1263 } |
| 1283 | 1264 |
| 1265 TEST_F(URLFetcherBadHTTPSTest, BadHTTPS) { | |
| 1266 WaitingURLFetcherDelegate delegate; | |
| 1267 delegate.CreateFetcherWithContext(test_server_->GetURL(kDefaultResponsePath), | |
| 1268 URLFetcher::GET, request_context()); | |
| 1269 delegate.StartFetcherAndWait(); | |
| 1270 | |
| 1271 EXPECT_EQ(URLRequestStatus::CANCELED, | |
| 1272 delegate.fetcher()->GetStatus().status()); | |
| 1273 EXPECT_EQ(ERR_ABORTED, delegate.fetcher()->GetStatus().error()); | |
| 1274 EXPECT_EQ(-1, delegate.fetcher()->GetResponseCode()); | |
| 1275 EXPECT_TRUE(delegate.fetcher()->GetCookies().empty()); | |
| 1276 std::string data; | |
| 1277 EXPECT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); | |
| 1278 EXPECT_TRUE(data.empty()); | |
| 1279 } | |
| 1280 | |
| 1284 } // namespace | 1281 } // namespace |
| 1285 | 1282 |
| 1286 } // namespace net | 1283 } // namespace net |
| OLD | NEW |