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 <stdint.h> | 7 #include <stdint.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <limits> | 11 #include <limits> |
12 #include <string> | 12 #include <string> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
16 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
17 #include "base/files/scoped_temp_dir.h" | 17 #include "base/files/scoped_temp_dir.h" |
18 #include "base/location.h" | 18 #include "base/location.h" |
19 #include "base/macros.h" | 19 #include "base/macros.h" |
20 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/scoped_ptr.h" |
21 #include "base/path_service.h" | 21 #include "base/path_service.h" |
22 #include "base/run_loop.h" | 22 #include "base/run_loop.h" |
23 #include "base/single_thread_task_runner.h" | 23 #include "base/single_thread_task_runner.h" |
24 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
25 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
26 #include "base/synchronization/waitable_event.h" | 26 #include "base/synchronization/waitable_event.h" |
27 #include "base/test/test_timeouts.h" | |
27 #include "base/thread_task_runner_handle.h" | 28 #include "base/thread_task_runner_handle.h" |
29 #include "base/threading/platform_thread.h" | |
28 #include "base/threading/thread.h" | 30 #include "base/threading/thread.h" |
29 #include "build/build_config.h" | 31 #include "build/build_config.h" |
30 #include "crypto/nss_util.h" | 32 #include "crypto/nss_util.h" |
31 #include "net/base/elements_upload_data_stream.h" | 33 #include "net/base/elements_upload_data_stream.h" |
32 #include "net/base/network_change_notifier.h" | 34 #include "net/base/network_change_notifier.h" |
33 #include "net/base/upload_bytes_element_reader.h" | 35 #include "net/base/upload_bytes_element_reader.h" |
34 #include "net/base/upload_element_reader.h" | 36 #include "net/base/upload_element_reader.h" |
35 #include "net/base/upload_file_element_reader.h" | 37 #include "net/base/upload_file_element_reader.h" |
36 #include "net/dns/mock_host_resolver.h" | 38 #include "net/dns/mock_host_resolver.h" |
37 #include "net/http/http_response_headers.h" | 39 #include "net/http/http_response_headers.h" |
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
768 delegate.StartFetcherAndWait(); | 770 delegate.StartFetcherAndWait(); |
769 | 771 |
770 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); | 772 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); |
771 EXPECT_EQ(500, delegate.fetcher()->GetResponseCode()); | 773 EXPECT_EQ(500, delegate.fetcher()->GetResponseCode()); |
772 std::string data; | 774 std::string data; |
773 ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); | 775 ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); |
774 EXPECT_EQ(kCreateUploadStreamBody, data); | 776 EXPECT_EQ(kCreateUploadStreamBody, data); |
775 EXPECT_EQ(2u, num_upload_streams_created()); | 777 EXPECT_EQ(2u, num_upload_streams_created()); |
776 } | 778 } |
777 | 779 |
780 // Tests simple chunked POST case. | |
781 TEST_F(URLFetcherTest, PostChunked) { | |
782 scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( | |
783 CreateCrossThreadContextGetter()); | |
784 | |
785 WaitingURLFetcherDelegate delegate; | |
786 delegate.CreateFetcher(test_server_->GetURL("/echo"), URLFetcher::POST, | |
787 CreateCrossThreadContextGetter()); | |
788 | |
789 delegate.fetcher()->SetChunkedUpload("text/plain"); | |
790 | |
791 // This posts a task to start the fetcher. | |
792 delegate.fetcher()->Start(); | |
793 | |
794 delegate.fetcher()->AppendChunkToUpload(kCreateUploadStreamBody, false); | |
795 delegate.fetcher()->AppendChunkToUpload(kCreateUploadStreamBody, true); | |
796 | |
797 delegate.WaitForComplete(); | |
798 | |
799 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); | |
800 EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); | |
801 std::string data; | |
802 ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); | |
803 EXPECT_EQ(std::string(kCreateUploadStreamBody) + | |
804 std::string(kCreateUploadStreamBody), | |
805 data); | |
806 } | |
807 | |
808 // Tests that data can be appended to a request after it fails. This is needed | |
809 // because the consumer may try to append data to a request after it failed, but | |
810 // before the consumer learns that it failed. | |
811 TEST_F(URLFetcherTest, PostAppendChunkAfterError) { | |
812 // This test has to use a single thread, so it can easily wait until the | |
813 // request has reached the HostResolver, at which point network changes will | |
814 // cause a failure. | |
815 scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( | |
816 CreateCrossThreadContextGetter()); | |
817 | |
818 WaitingURLFetcherDelegate delegate; | |
819 // Request that will fail almost immediately after being started, due to using | |
820 // a reserved port. | |
821 delegate.CreateFetcher(GURL("http://127.0.0.1:7"), URLFetcher::POST, | |
822 context_getter); | |
823 | |
824 delegate.fetcher()->SetChunkedUpload("text/plain"); | |
825 | |
826 // This posts a task to start the fetcher. | |
827 delegate.fetcher()->Start(); | |
828 | |
829 // Give the request a chance to fail, and inform the fetcher of the failure, | |
830 // while blocking the current thread so the error doesn't reach the delegate. | |
831 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
eroman
2016/03/26 00:55:16
Hmm this is subtle.
Is there a way to run this te
mmenke
2016/03/28 17:33:11
This test doesn't really need to be cross-thread,
| |
832 | |
833 // Try to append data. | |
834 delegate.fetcher()->AppendChunkToUpload("kCreateUploadStreamBody", false); | |
835 delegate.fetcher()->AppendChunkToUpload("kCreateUploadStreamBody", true); | |
836 | |
837 delegate.WaitForComplete(); | |
838 | |
839 // Make sure the request failed, as expected. | |
840 EXPECT_FALSE(delegate.fetcher()->GetStatus().is_success()); | |
841 EXPECT_EQ(ERR_UNSAFE_PORT, delegate.fetcher()->GetStatus().error()); | |
842 } | |
843 | |
778 // Checks that upload progress increases over time, never exceeds what's already | 844 // Checks that upload progress increases over time, never exceeds what's already |
779 // been sent, and adds a chunk whenever all previously appended chunks have | 845 // been sent, and adds a chunk whenever all previously appended chunks have |
780 // been uploaded. | 846 // been uploaded. |
781 class CheckUploadProgressDelegate : public WaitingURLFetcherDelegate { | 847 class CheckUploadProgressDelegate : public WaitingURLFetcherDelegate { |
782 public: | 848 public: |
783 CheckUploadProgressDelegate() | 849 CheckUploadProgressDelegate() |
784 : chunk_(1 << 16, 'a'), num_chunks_appended_(0), last_seen_progress_(0) {} | 850 : chunk_(1 << 16, 'a'), num_chunks_appended_(0), last_seen_progress_(0) {} |
785 ~CheckUploadProgressDelegate() override {} | 851 ~CheckUploadProgressDelegate() override {} |
786 | 852 |
787 void OnURLFetchUploadProgress(const URLFetcher* source, | 853 void OnURLFetchUploadProgress(const URLFetcher* source, |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1036 | 1102 |
1037 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); | 1103 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); |
1038 EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); | 1104 EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); |
1039 } | 1105 } |
1040 | 1106 |
1041 // 20 requests were sent. Due to throttling, they should have collectively | 1107 // 20 requests were sent. Due to throttling, they should have collectively |
1042 // taken over 1 second. | 1108 // taken over 1 second. |
1043 EXPECT_GE(Time::Now() - start_time, base::TimeDelta::FromSeconds(1)); | 1109 EXPECT_GE(Time::Now() - start_time, base::TimeDelta::FromSeconds(1)); |
1044 } | 1110 } |
1045 | 1111 |
1112 // If throttling kicks in for a chunked upload, there should be no crash. | |
1113 TEST_F(URLFetcherTest, ThrottleChunkedUpload) { | |
1114 base::Time start_time = Time::Now(); | |
1115 GURL url(test_server_->GetURL("/echo")); | |
1116 | |
1117 scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( | |
1118 CreateSameThreadContextGetter()); | |
1119 | |
1120 // Registers an entry for test url. It only allows 3 requests to be sent | |
1121 // in 200 milliseconds. | |
1122 context_getter->AddThrottlerEntry( | |
1123 url, std::string() /* url_id */, 200 /* sliding_window_period_ms */, | |
1124 3 /* max_send_threshold */, 1 /* initial_backoff_ms */, | |
1125 2.0 /* multiply_factor */, 0.0 /* jitter_factor */, | |
1126 256 /* maximum_backoff_ms */, | |
1127 false /* reserve_sending_time_for_next_request*/); | |
1128 | |
1129 for (int i = 0; i < 20; ++i) { | |
1130 WaitingURLFetcherDelegate delegate; | |
1131 delegate.CreateFetcher(url, URLFetcher::POST, context_getter); | |
1132 delegate.fetcher()->SetChunkedUpload("text/plain"); | |
1133 delegate.fetcher()->Start(); | |
1134 delegate.fetcher()->AppendChunkToUpload(kCreateUploadStreamBody, true); | |
1135 delegate.WaitForComplete(); | |
1136 | |
1137 EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success()); | |
1138 EXPECT_EQ(200, delegate.fetcher()->GetResponseCode()); | |
1139 std::string data; | |
1140 ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); | |
1141 EXPECT_EQ(kCreateUploadStreamBody, data); | |
1142 } | |
1143 | |
1144 // 20 requests were sent. Due to throttling, they should have collectively | |
1145 // taken over 1 second. | |
1146 EXPECT_GE(Time::Now() - start_time, base::TimeDelta::FromSeconds(1)); | |
eroman
2016/03/26 00:55:16
Is this timing exact, or can this fail?
Would it b
mmenke
2016/03/28 17:33:11
Removed. This was copied from the above test...I
| |
1147 } | |
1148 | |
1046 TEST_F(URLFetcherTest, ThrottleOn5xxRetries) { | 1149 TEST_F(URLFetcherTest, ThrottleOn5xxRetries) { |
1047 base::Time start_time = Time::Now(); | 1150 base::Time start_time = Time::Now(); |
1048 GURL url(test_server_->GetURL("/server-unavailable.html")); | 1151 GURL url(test_server_->GetURL("/server-unavailable.html")); |
1049 | 1152 |
1050 scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( | 1153 scoped_refptr<FetcherTestURLRequestContextGetter> context_getter( |
1051 CreateSameThreadContextGetter()); | 1154 CreateSameThreadContextGetter()); |
1052 | 1155 |
1053 // Registers an entry for test url. The backoff time is calculated by: | 1156 // Registers an entry for test url. The backoff time is calculated by: |
1054 // new_backoff = 2.0 * old_backoff + 0 | 1157 // new_backoff = 2.0 * old_backoff + 0 |
1055 // and maximum backoff time is 256 milliseconds. | 1158 // and maximum backoff time is 256 milliseconds. |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1427 EXPECT_EQ(-1, delegate.fetcher()->GetResponseCode()); | 1530 EXPECT_EQ(-1, delegate.fetcher()->GetResponseCode()); |
1428 EXPECT_TRUE(delegate.fetcher()->GetCookies().empty()); | 1531 EXPECT_TRUE(delegate.fetcher()->GetCookies().empty()); |
1429 std::string data; | 1532 std::string data; |
1430 EXPECT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); | 1533 EXPECT_TRUE(delegate.fetcher()->GetResponseAsString(&data)); |
1431 EXPECT_TRUE(data.empty()); | 1534 EXPECT_TRUE(data.empty()); |
1432 } | 1535 } |
1433 | 1536 |
1434 } // namespace | 1537 } // namespace |
1435 | 1538 |
1436 } // namespace net | 1539 } // namespace net |
OLD | NEW |