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" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
| 13 #include "base/message_loop/message_loop_proxy.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
| 17 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
| 18 #include "build/build_config.h" | 18 #include "build/build_config.h" |
| 19 #include "crypto/nss_util.h" | 19 #include "crypto/nss_util.h" |
| 20 #include "net/base/elements_upload_data_stream.h" | |
| 20 #include "net/base/network_change_notifier.h" | 21 #include "net/base/network_change_notifier.h" |
| 22 #include "net/base/upload_bytes_element_reader.h" | |
| 23 #include "net/base/upload_element_reader.h" | |
| 24 #include "net/base/upload_file_element_reader.h" | |
| 21 #include "net/dns/mock_host_resolver.h" | 25 #include "net/dns/mock_host_resolver.h" |
| 22 #include "net/http/http_response_headers.h" | 26 #include "net/http/http_response_headers.h" |
| 23 #include "net/test/spawned_test_server/spawned_test_server.h" | 27 #include "net/test/spawned_test_server/spawned_test_server.h" |
| 24 #include "net/url_request/url_fetcher_delegate.h" | 28 #include "net/url_request/url_fetcher_delegate.h" |
| 25 #include "net/url_request/url_request_context_getter.h" | 29 #include "net/url_request/url_request_context_getter.h" |
| 26 #include "net/url_request/url_request_test_util.h" | 30 #include "net/url_request/url_request_test_util.h" |
| 27 #include "net/url_request/url_request_throttler_manager.h" | 31 #include "net/url_request/url_request_throttler_manager.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 29 | 33 |
| 30 #if defined(USE_NSS) || defined(OS_IOS) | 34 #if defined(USE_NSS) || defined(OS_IOS) |
| 31 #include "net/ocsp/nss_ocsp.h" | 35 #include "net/ocsp/nss_ocsp.h" |
| 32 #endif | 36 #endif |
| 33 | 37 |
| 34 namespace net { | 38 namespace net { |
| 35 | 39 |
| 36 using base::Time; | 40 using base::Time; |
| 37 using base::TimeDelta; | 41 using base::TimeDelta; |
| 38 | 42 |
| 39 // TODO(eroman): Add a regression test for http://crbug.com/40505. | 43 // TODO(eroman): Add a regression test for http://crbug.com/40505. |
| 40 | 44 |
| 41 namespace { | 45 namespace { |
| 42 | 46 |
| 43 // TODO(akalin): Move all the test data to somewhere under net/. | 47 // TODO(akalin): Move all the test data to somewhere under net/. |
| 44 const base::FilePath::CharType kDocRoot[] = | 48 const base::FilePath::CharType kDocRoot[] = |
| 45 FILE_PATH_LITERAL("net/data/url_fetcher_impl_unittest"); | 49 FILE_PATH_LITERAL("net/data/url_fetcher_impl_unittest"); |
| 46 const char kTestServerFilePrefix[] = "files/"; | 50 const char kTestServerFilePrefix[] = "files/"; |
| 47 | 51 |
| 52 scoped_ptr<UploadDataStream> CreateUploadStream(size_t* call_count) { | |
| 53 ++*call_count; | |
| 54 const std::string str("bobsyeruncle\n"); | |
| 55 std::vector<char> buffer(str.begin(), str.end()); | |
| 56 return ElementsUploadDataStream::CreateWithReader( | |
| 57 scoped_ptr<UploadElementReader>( | |
| 58 new UploadOwnedBytesElementReader(&buffer)), | |
| 59 0); | |
| 60 } | |
| 61 | |
| 48 class ThrottlingTestURLRequestContext : public TestURLRequestContext { | 62 class ThrottlingTestURLRequestContext : public TestURLRequestContext { |
| 49 public: | 63 public: |
| 50 ThrottlingTestURLRequestContext() : TestURLRequestContext(true) { | 64 ThrottlingTestURLRequestContext() : TestURLRequestContext(true) { |
| 51 set_throttler_manager(&throttler_manager_); | 65 set_throttler_manager(&throttler_manager_); |
| 52 Init(); | 66 Init(); |
| 53 DCHECK(throttler_manager() != NULL); | 67 DCHECK(throttler_manager() != NULL); |
| 54 } | 68 } |
| 55 | 69 |
| 56 private: | 70 private: |
| 57 URLRequestThrottlerManager throttler_manager_; | 71 URLRequestThrottlerManager throttler_manager_; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 74 ~ThrottlingTestURLRequestContextGetter() override {} | 88 ~ThrottlingTestURLRequestContextGetter() override {} |
| 75 | 89 |
| 76 TestURLRequestContext* const context_; | 90 TestURLRequestContext* const context_; |
| 77 }; | 91 }; |
| 78 | 92 |
| 79 } // namespace | 93 } // namespace |
| 80 | 94 |
| 81 class URLFetcherTest : public testing::Test, | 95 class URLFetcherTest : public testing::Test, |
| 82 public URLFetcherDelegate { | 96 public URLFetcherDelegate { |
| 83 public: | 97 public: |
| 84 URLFetcherTest() : fetcher_(NULL) {} | 98 URLFetcherTest() : fetcher_(NULL), expected_status_code_(200) {} |
| 85 | 99 |
| 86 static int GetNumFetcherCores() { | 100 static int GetNumFetcherCores() { |
| 87 return URLFetcherImpl::GetNumFetcherCores(); | 101 return URLFetcherImpl::GetNumFetcherCores(); |
| 88 } | 102 } |
| 89 | 103 |
| 90 // Creates a URLFetcher, using the program's main thread to do IO. | 104 // Creates a URLFetcher, using the program's main thread to do IO. |
| 91 virtual void CreateFetcher(const GURL& url); | 105 virtual void CreateFetcher(const GURL& url); |
| 92 | 106 |
| 93 // URLFetcherDelegate: | 107 // URLFetcherDelegate: |
| 94 // Subclasses that override this should either call this function or | 108 // Subclasses that override this should either call this function or |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 } | 142 } |
| 129 | 143 |
| 130 // URLFetcher is designed to run on the main UI thread, but in our tests | 144 // URLFetcher is designed to run on the main UI thread, but in our tests |
| 131 // we assume that the current thread is the IO thread where the URLFetcher | 145 // we assume that the current thread is the IO thread where the URLFetcher |
| 132 // dispatches its requests to. When we wish to simulate being used from | 146 // dispatches its requests to. When we wish to simulate being used from |
| 133 // a UI thread, we dispatch a worker thread to do so. | 147 // a UI thread, we dispatch a worker thread to do so. |
| 134 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; | 148 scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; |
| 135 | 149 |
| 136 URLFetcherImpl* fetcher_; | 150 URLFetcherImpl* fetcher_; |
| 137 scoped_ptr<TestURLRequestContext> context_; | 151 scoped_ptr<TestURLRequestContext> context_; |
| 152 int expected_status_code_; | |
| 138 }; | 153 }; |
| 139 | 154 |
| 140 // A test fixture that uses a MockHostResolver, so that name resolutions can | 155 // A test fixture that uses a MockHostResolver, so that name resolutions can |
| 141 // be manipulated by the tests to keep connections in the resolving state. | 156 // be manipulated by the tests to keep connections in the resolving state. |
| 142 class URLFetcherMockDnsTest : public URLFetcherTest { | 157 class URLFetcherMockDnsTest : public URLFetcherTest { |
| 143 public: | 158 public: |
| 144 // testing::Test: | 159 // testing::Test: |
| 145 void SetUp() override; | 160 void SetUp() override; |
| 146 | 161 |
| 147 // URLFetcherTest: | 162 // URLFetcherTest: |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 159 | 174 |
| 160 void URLFetcherTest::CreateFetcher(const GURL& url) { | 175 void URLFetcherTest::CreateFetcher(const GURL& url) { |
| 161 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); | 176 fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this); |
| 162 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( | 177 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( |
| 163 io_message_loop_proxy().get(), request_context())); | 178 io_message_loop_proxy().get(), request_context())); |
| 164 fetcher_->Start(); | 179 fetcher_->Start(); |
| 165 } | 180 } |
| 166 | 181 |
| 167 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) { | 182 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) { |
| 168 EXPECT_TRUE(source->GetStatus().is_success()); | 183 EXPECT_TRUE(source->GetStatus().is_success()); |
| 169 EXPECT_EQ(200, source->GetResponseCode()); // HTTP OK | 184 EXPECT_EQ(expected_status_code_, source->GetResponseCode()); // HTTP OK |
| 170 | 185 |
| 171 std::string data; | 186 std::string data; |
| 172 EXPECT_TRUE(source->GetResponseAsString(&data)); | 187 EXPECT_TRUE(source->GetResponseAsString(&data)); |
| 173 EXPECT_FALSE(data.empty()); | 188 EXPECT_FALSE(data.empty()); |
| 174 | 189 |
| 175 CleanupAfterFetchComplete(); | 190 CleanupAfterFetchComplete(); |
| 176 } | 191 } |
| 177 | 192 |
| 178 void URLFetcherTest::CleanupAfterFetchComplete() { | 193 void URLFetcherTest::CleanupAfterFetchComplete() { |
| 179 delete fetcher_; // Have to delete this here and not in the destructor, | 194 delete fetcher_; // Have to delete this here and not in the destructor, |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 | 267 |
| 253 // URLFetcherDelegate: | 268 // URLFetcherDelegate: |
| 254 void OnURLFetchComplete(const URLFetcher* source) override; | 269 void OnURLFetchComplete(const URLFetcher* source) override; |
| 255 | 270 |
| 256 private: | 271 private: |
| 257 base::FilePath path_; | 272 base::FilePath path_; |
| 258 uint64 range_offset_; | 273 uint64 range_offset_; |
| 259 uint64 range_length_; | 274 uint64 range_length_; |
| 260 }; | 275 }; |
| 261 | 276 |
| 277 class URLFetcherPostStreamTest : public URLFetcherTest { | |
| 278 public: | |
| 279 URLFetcherPostStreamTest() : create_stream_count_(0) {} | |
| 280 | |
| 281 // URLFetcherTest: | |
| 282 void CreateFetcher(const GURL& url) override; | |
| 283 | |
| 284 // URLFetcherDelegate: | |
| 285 void OnURLFetchComplete(const URLFetcher* source) override; | |
| 286 | |
| 287 protected: | |
| 288 // Count of calling CreateStream. | |
| 289 size_t create_stream_count_; | |
| 290 }; | |
| 291 | |
| 262 // Version of URLFetcherTest that does a POST instead with empty upload body | 292 // Version of URLFetcherTest that does a POST instead with empty upload body |
| 263 class URLFetcherEmptyPostTest : public URLFetcherTest { | 293 class URLFetcherEmptyPostTest : public URLFetcherTest { |
| 264 public: | 294 public: |
| 265 // URLFetcherTest: | 295 // URLFetcherTest: |
| 266 void CreateFetcher(const GURL& url) override; | 296 void CreateFetcher(const GURL& url) override; |
| 267 | 297 |
| 268 // URLFetcherDelegate: | 298 // URLFetcherDelegate: |
| 269 void OnURLFetchComplete(const URLFetcher* source) override; | 299 void OnURLFetchComplete(const URLFetcher* source) override; |
| 270 }; | 300 }; |
| 271 | 301 |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 564 ASSERT_LE(range_offset_, expected.size()); | 594 ASSERT_LE(range_offset_, expected.size()); |
| 565 uint64 expected_size = | 595 uint64 expected_size = |
| 566 std::min(range_length_, expected.size() - range_offset_); | 596 std::min(range_length_, expected.size() - range_offset_); |
| 567 | 597 |
| 568 std::string data; | 598 std::string data; |
| 569 EXPECT_TRUE(source->GetResponseAsString(&data)); | 599 EXPECT_TRUE(source->GetResponseAsString(&data)); |
| 570 EXPECT_EQ(expected.substr(range_offset_, expected_size), data); | 600 EXPECT_EQ(expected.substr(range_offset_, expected_size), data); |
| 571 URLFetcherTest::OnURLFetchComplete(source); | 601 URLFetcherTest::OnURLFetchComplete(source); |
| 572 } | 602 } |
| 573 | 603 |
| 604 void URLFetcherPostStreamTest::CreateFetcher(const GURL& url) { | |
| 605 fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); | |
| 606 fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( | |
| 607 io_message_loop_proxy().get(), request_context())); | |
| 608 fetcher_->SetUploadStreamFactory( | |
| 609 "text/plain", base::Bind(&CreateUploadStream, &create_stream_count_)); | |
| 610 fetcher_->SetAutomaticallyRetryOn5xx(true); | |
| 611 fetcher_->SetMaxRetriesOn5xx(1); | |
| 612 fetcher_->Start(); | |
| 613 } | |
| 614 | |
| 615 void URLFetcherPostStreamTest::OnURLFetchComplete(const URLFetcher* source) { | |
| 616 std::string data; | |
| 617 EXPECT_TRUE(source->GetResponseAsString(&data)); | |
| 618 EXPECT_EQ(std::string("bobsyeruncle\n"), data); | |
|
mmenke
2015/01/15 15:38:54
nit: set::string isn't needed here.
hirono
2015/01/16 03:55:58
Done.
| |
| 619 URLFetcherTest::OnURLFetchComplete(source); | |
| 620 } | |
| 621 | |
| 574 void URLFetcherEmptyPostTest::CreateFetcher(const GURL& url) { | 622 void URLFetcherEmptyPostTest::CreateFetcher(const GURL& url) { |
| 575 fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); | 623 fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); |
| 576 fetcher_->SetRequestContext(new TestURLRequestContextGetter( | 624 fetcher_->SetRequestContext(new TestURLRequestContextGetter( |
| 577 io_message_loop_proxy())); | 625 io_message_loop_proxy())); |
| 578 fetcher_->SetUploadData("text/plain", std::string()); | 626 fetcher_->SetUploadData("text/plain", std::string()); |
| 579 fetcher_->Start(); | 627 fetcher_->Start(); |
| 580 } | 628 } |
| 581 | 629 |
| 582 void URLFetcherEmptyPostTest::OnURLFetchComplete(const URLFetcher* source) { | 630 void URLFetcherEmptyPostTest::OnURLFetchComplete(const URLFetcher* source) { |
| 583 EXPECT_TRUE(source->GetStatus().is_success()); | 631 EXPECT_TRUE(source->GetStatus().is_success()); |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1078 SpawnedTestServer::kLocalhost, | 1126 SpawnedTestServer::kLocalhost, |
| 1079 base::FilePath(kDocRoot)); | 1127 base::FilePath(kDocRoot)); |
| 1080 ASSERT_TRUE(test_server.Start()); | 1128 ASSERT_TRUE(test_server.Start()); |
| 1081 | 1129 |
| 1082 SetUploadRange(30, 100); | 1130 SetUploadRange(30, 100); |
| 1083 | 1131 |
| 1084 CreateFetcher(test_server.GetURL("echo")); | 1132 CreateFetcher(test_server.GetURL("echo")); |
| 1085 base::MessageLoop::current()->Run(); | 1133 base::MessageLoop::current()->Run(); |
| 1086 } | 1134 } |
| 1087 | 1135 |
| 1136 TEST_F(URLFetcherPostStreamTest, Basic) { | |
| 1137 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, | |
| 1138 SpawnedTestServer::kLocalhost, | |
| 1139 base::FilePath(kDocRoot)); | |
| 1140 ASSERT_TRUE(test_server.Start()); | |
| 1141 | |
| 1142 CreateFetcher(test_server.GetURL("echo")); | |
| 1143 base::MessageLoop::current()->Run(); | |
| 1144 ASSERT_EQ(1u, create_stream_count_); | |
| 1145 } | |
| 1146 | |
| 1147 TEST_F(URLFetcherPostStreamTest, Retry) { | |
| 1148 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, | |
| 1149 SpawnedTestServer::kLocalhost, | |
| 1150 base::FilePath(kDocRoot)); | |
| 1151 ASSERT_TRUE(test_server.Start()); | |
| 1152 expected_status_code_ = 500; | |
| 1153 CreateFetcher(test_server.GetURL("echo?status=500")); | |
| 1154 base::MessageLoop::current()->Run(); | |
| 1155 ASSERT_EQ(2u, create_stream_count_); | |
| 1156 } | |
| 1157 | |
| 1088 TEST_F(URLFetcherEmptyPostTest, Basic) { | 1158 TEST_F(URLFetcherEmptyPostTest, Basic) { |
| 1089 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, | 1159 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP, |
| 1090 SpawnedTestServer::kLocalhost, | 1160 SpawnedTestServer::kLocalhost, |
| 1091 base::FilePath(kDocRoot)); | 1161 base::FilePath(kDocRoot)); |
| 1092 ASSERT_TRUE(test_server.Start()); | 1162 ASSERT_TRUE(test_server.Start()); |
| 1093 | 1163 |
| 1094 CreateFetcher(test_server.GetURL("echo")); | 1164 CreateFetcher(test_server.GetURL("echo")); |
| 1095 base::MessageLoop::current()->Run(); | 1165 base::MessageLoop::current()->Run(); |
| 1096 } | 1166 } |
| 1097 | 1167 |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1534 | 1604 |
| 1535 base::MessageLoop::current()->RunUntilIdle(); | 1605 base::MessageLoop::current()->RunUntilIdle(); |
| 1536 ASSERT_EQ(kTake[i], base::PathExists(file_path_)) << | 1606 ASSERT_EQ(kTake[i], base::PathExists(file_path_)) << |
| 1537 "FilePath: " << file_path_.value(); | 1607 "FilePath: " << file_path_.value(); |
| 1538 } | 1608 } |
| 1539 } | 1609 } |
| 1540 | 1610 |
| 1541 } // namespace | 1611 } // namespace |
| 1542 | 1612 |
| 1543 } // namespace net | 1613 } // namespace net |
| OLD | NEW |