OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/cert_net/cert_net_fetcher_impl.h" | 5 #include "net/cert_net/cert_net_fetcher_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 13 #include "base/synchronization/lock.h" |
| 14 #include "net/cert/cert_net_fetcher.h" |
13 #include "net/cert/ct_policy_enforcer.h" | 15 #include "net/cert/ct_policy_enforcer.h" |
14 #include "net/cert/mock_cert_verifier.h" | 16 #include "net/cert/mock_cert_verifier.h" |
15 #include "net/cert/multi_log_ct_verifier.h" | 17 #include "net/cert/multi_log_ct_verifier.h" |
16 #include "net/dns/mock_host_resolver.h" | 18 #include "net/dns/mock_host_resolver.h" |
17 #include "net/http/http_server_properties_impl.h" | 19 #include "net/http/http_server_properties_impl.h" |
18 #include "net/test/embedded_test_server/embedded_test_server.h" | 20 #include "net/test/embedded_test_server/embedded_test_server.h" |
19 #include "net/test/gtest_util.h" | 21 #include "net/test/gtest_util.h" |
20 #include "net/url_request/url_request_job_factory_impl.h" | 22 #include "net/url_request/url_request_job_factory_impl.h" |
21 #include "net/url_request/url_request_test_util.h" | 23 #include "net/url_request/url_request_test_util.h" |
22 #include "testing/gmock/include/gmock/gmock.h" | 24 #include "testing/gmock/include/gmock/gmock.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
24 #include "testing/platform_test.h" | 26 #include "testing/platform_test.h" |
25 | 27 |
26 using net::test::IsOk; | 28 using net::test::IsOk; |
27 | 29 |
28 // TODO(eroman): Test that cookies aren't sent. | 30 // TODO(eroman): Test that cookies aren't sent. |
29 | 31 |
30 using base::ASCIIToUTF16; | |
31 | |
32 namespace net { | 32 namespace net { |
33 | 33 |
34 namespace { | 34 namespace { |
35 | 35 |
36 const base::FilePath::CharType kDocRoot[] = | 36 const base::FilePath::CharType kDocRoot[] = |
37 FILE_PATH_LITERAL("net/data/cert_net_fetcher_impl_unittest"); | 37 FILE_PATH_LITERAL("net/data/cert_net_fetcher_impl_unittest"); |
38 | 38 |
39 // A non-mock URLRequestContext which can access http:// urls. | 39 // A non-mock URLRequestContext which can access http:// urls. |
40 class RequestContext : public URLRequestContext { | 40 class RequestContext : public URLRequestContext { |
41 public: | 41 public: |
(...skipping 28 matching lines...) Expand all Loading... |
70 false /* set_up_quic_server_info */)); | 70 false /* set_up_quic_server_info */)); |
71 storage_.set_job_factory(base::MakeUnique<URLRequestJobFactoryImpl>()); | 71 storage_.set_job_factory(base::MakeUnique<URLRequestJobFactoryImpl>()); |
72 } | 72 } |
73 | 73 |
74 ~RequestContext() override { AssertNoURLRequests(); } | 74 ~RequestContext() override { AssertNoURLRequests(); } |
75 | 75 |
76 private: | 76 private: |
77 URLRequestContextStorage storage_; | 77 URLRequestContextStorage storage_; |
78 }; | 78 }; |
79 | 79 |
80 class FetchResult { | 80 // Wait for the request to complete, and verify that it completed successfully |
81 public: | 81 // with the indicated bytes. |
82 FetchResult(Error net_error, const std::vector<uint8_t>& response_body) | 82 void VerifySuccess(const std::string& expected_body, |
83 : net_error_(net_error), response_body_(response_body) {} | 83 CertNetFetcher::Request* request) { |
| 84 Error actual_error; |
| 85 std::vector<uint8_t> actual_body; |
| 86 request->WaitForResult(&actual_error, &actual_body); |
84 | 87 |
85 void VerifySuccess(const std::string& expected_body) { | 88 EXPECT_THAT(actual_error, IsOk()); |
86 EXPECT_THAT(net_error_, IsOk()); | 89 EXPECT_EQ(expected_body, std::string(actual_body.begin(), actual_body.end())); |
87 EXPECT_EQ(expected_body, | 90 } |
88 std::string(response_body_.begin(), response_body_.end())); | |
89 } | |
90 | 91 |
91 void VerifyFailure(Error expected_error) { | 92 // Wait for the request to complete, and verify that it completed with the |
92 EXPECT_EQ(expected_error, net_error_); | 93 // indicated failure. |
93 EXPECT_EQ(0u, response_body_.size()); | 94 void VerifyFailure(Error expected_error, CertNetFetcher::Request* request) { |
94 } | 95 Error actual_error; |
| 96 std::vector<uint8_t> actual_body; |
| 97 request->WaitForResult(&actual_error, &actual_body); |
95 | 98 |
96 private: | 99 EXPECT_EQ(expected_error, actual_error); |
97 const Error net_error_; | 100 EXPECT_EQ(0u, actual_body.size()); |
98 const std::vector<uint8_t> response_body_; | 101 } |
| 102 |
| 103 struct NetworkThreadState { |
| 104 TestNetworkDelegate network_delegate; |
| 105 RequestContext context; |
99 }; | 106 }; |
100 | 107 |
101 // Helper to synchronously wait for the fetch completion. This is similar to | |
102 // net's TestCompletionCallback, but built around FetchCallback. | |
103 class TestFetchCallback { | |
104 public: | |
105 TestFetchCallback() | |
106 : callback_(base::Bind(&TestFetchCallback::OnCallback, | |
107 base::Unretained(this))) {} | |
108 | |
109 const CertNetFetcher::FetchCallback& callback() const { return callback_; } | |
110 | |
111 std::unique_ptr<FetchResult> WaitForResult() { | |
112 DCHECK(quit_closure_.is_null()); | |
113 while (!HasResult()) { | |
114 base::RunLoop run_loop; | |
115 quit_closure_ = run_loop.QuitClosure(); | |
116 run_loop.Run(); | |
117 quit_closure_.Reset(); | |
118 } | |
119 return std::move(result_); | |
120 } | |
121 | |
122 bool HasResult() const { return result_.get(); } | |
123 | |
124 // Sets an extra action (in addition to recording the result) that is run when | |
125 // the FetchCallback is invoked. | |
126 void set_extra_closure(const base::Closure& closure) { | |
127 extra_closure_ = closure; | |
128 } | |
129 | |
130 private: | |
131 void OnCallback(Error net_error, const std::vector<uint8_t>& response_body) { | |
132 DCHECK(!HasResult()); | |
133 result_.reset(new FetchResult(net_error, response_body)); | |
134 | |
135 if (!extra_closure_.is_null()) | |
136 extra_closure_.Run(); | |
137 | |
138 if (!quit_closure_.is_null()) | |
139 quit_closure_.Run(); | |
140 } | |
141 | |
142 CertNetFetcher::FetchCallback callback_; | |
143 std::unique_ptr<FetchResult> result_; | |
144 base::Closure quit_closure_; | |
145 base::Closure extra_closure_; | |
146 }; | |
147 | |
148 } // namespace | |
149 | |
150 class CertNetFetcherImplTest : public PlatformTest { | 108 class CertNetFetcherImplTest : public PlatformTest { |
151 public: | 109 public: |
152 CertNetFetcherImplTest() { | 110 CertNetFetcherImplTest() { |
153 test_server_.AddDefaultHandlers(base::FilePath(kDocRoot)); | 111 test_server_.AddDefaultHandlers(base::FilePath(kDocRoot)); |
154 context_.set_network_delegate(&network_delegate_); | 112 StartNetworkThread(); |
| 113 } |
| 114 |
| 115 ~CertNetFetcherImplTest() override { |
| 116 network_thread_->task_runner()->PostTask( |
| 117 FROM_HERE, base::Bind(&CertNetFetcherImplTest::TeardownOnNetworkThread, |
| 118 base::Unretained(this))); |
| 119 network_thread_->Stop(); |
155 } | 120 } |
156 | 121 |
157 protected: | 122 protected: |
| 123 std::unique_ptr<CertNetFetcher> CreateFetcher() { |
| 124 scoped_refptr<TrivialURLRequestContextGetter> context_getter( |
| 125 new TrivialURLRequestContextGetter(&state_->context, |
| 126 network_thread_->task_runner())); |
| 127 return CreateCertNetFetcher(context_getter.get()); |
| 128 } |
| 129 |
| 130 int NumCreatedRequests() { |
| 131 int count = 0; |
| 132 base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, |
| 133 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 134 network_thread_->task_runner()->PostTask( |
| 135 FROM_HERE, base::Bind(&CertNetFetcherImplTest::CountCreatedRequests, |
| 136 base::Unretained(this), &count, &done)); |
| 137 done.Wait(); |
| 138 return count; |
| 139 } |
| 140 |
| 141 void StartNetworkThread() { |
| 142 // Start the network thread. |
| 143 network_thread_.reset(new base::Thread("network thread")); |
| 144 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); |
| 145 EXPECT_TRUE(network_thread_->StartWithOptions(options)); |
| 146 |
| 147 // Initialize the URLRequestContext (and wait till it has completed). |
| 148 base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, |
| 149 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 150 network_thread_->task_runner()->PostTask( |
| 151 FROM_HERE, base::Bind(&CertNetFetcherImplTest::InitOnNetworkThread, |
| 152 base::Unretained(this), &done)); |
| 153 done.Wait(); |
| 154 } |
| 155 |
| 156 void InitOnNetworkThread(base::WaitableEvent* done) { |
| 157 state_.reset(new NetworkThreadState); |
| 158 state_->context.set_network_delegate(&state_->network_delegate); |
| 159 done->Signal(); |
| 160 } |
| 161 |
| 162 void TeardownOnNetworkThread() { state_.reset(); } |
| 163 |
| 164 void CountCreatedRequests(int* count, base::WaitableEvent* done) { |
| 165 *count = state_->network_delegate.created_requests(); |
| 166 done->Signal(); |
| 167 } |
| 168 |
158 EmbeddedTestServer test_server_; | 169 EmbeddedTestServer test_server_; |
159 TestNetworkDelegate network_delegate_; | 170 std::unique_ptr<base::Thread> network_thread_; |
160 RequestContext context_; | 171 |
| 172 std::unique_ptr<NetworkThreadState> state_; |
161 }; | 173 }; |
162 | 174 |
163 // Helper to start an AIA fetch using default parameters. | 175 // Helper to start an AIA fetch using default parameters. |
164 WARN_UNUSED_RESULT std::unique_ptr<CertNetFetcher::Request> StartRequest( | 176 WARN_UNUSED_RESULT std::unique_ptr<CertNetFetcher::Request> StartRequest( |
165 CertNetFetcher* fetcher, | 177 CertNetFetcher* fetcher, |
166 const GURL& url, | 178 const GURL& url) { |
167 const TestFetchCallback& callback) { | |
168 return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, | 179 return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, |
169 CertNetFetcher::DEFAULT, callback.callback()); | 180 CertNetFetcher::DEFAULT); |
170 } | 181 } |
171 | 182 |
172 // Flaky on Android. See http://crbug.com/646147. | 183 // Flaky on Android. See http://crbug.com/646147. |
173 #if defined(OS_ANDROID) | 184 #if defined(OS_ANDROID) |
174 #define MAYBE_ParallelFetchNoDuplicates DISABLED_ParallelFetchNoDuplicates | 185 #define MAYBE_ParallelFetchNoDuplicates DISABLED_ParallelFetchNoDuplicates |
175 #else | 186 #else |
176 #define MAYBE_ParallelFetchNoDuplicates ParallelFetchNoDuplicates | 187 #define MAYBE_ParallelFetchNoDuplicates ParallelFetchNoDuplicates |
177 #endif | 188 #endif |
178 // Fetch a few unique URLs using GET in parallel. Each URL has a different body | 189 // Fetch a few unique URLs using GET in parallel. Each URL has a different body |
179 // and Content-Type. | 190 // and Content-Type. |
180 TEST_F(CertNetFetcherImplTest, MAYBE_ParallelFetchNoDuplicates) { | 191 TEST_F(CertNetFetcherImplTest, MAYBE_ParallelFetchNoDuplicates) { |
181 ASSERT_TRUE(test_server_.Start()); | 192 ASSERT_TRUE(test_server_.Start()); |
182 | 193 |
183 CertNetFetcherImpl fetcher(&context_); | 194 auto fetcher = CreateFetcher(); |
184 TestFetchCallback callback1; | |
185 TestFetchCallback callback2; | |
186 TestFetchCallback callback3; | |
187 | 195 |
188 // Request a URL with Content-Type "application/pkix-cert" | 196 // Request a URL with Content-Type "application/pkix-cert" |
189 GURL url1 = test_server_.GetURL("/cert.crt"); | 197 GURL url1 = test_server_.GetURL("/cert.crt"); |
190 std::unique_ptr<CertNetFetcher::Request> request1 = | 198 std::unique_ptr<CertNetFetcher::Request> request1 = |
191 StartRequest(&fetcher, url1, callback1); | 199 StartRequest(fetcher.get(), url1); |
192 | 200 |
193 // Request a URL with Content-Type "application/pkix-crl" | 201 // Request a URL with Content-Type "application/pkix-crl" |
194 GURL url2 = test_server_.GetURL("/root.crl"); | 202 GURL url2 = test_server_.GetURL("/root.crl"); |
195 std::unique_ptr<CertNetFetcher::Request> request2 = | 203 std::unique_ptr<CertNetFetcher::Request> request2 = |
196 StartRequest(&fetcher, url2, callback2); | 204 StartRequest(fetcher.get(), url2); |
197 | 205 |
198 // Request a URL with Content-Type "application/pkcs7-mime" | 206 // Request a URL with Content-Type "application/pkcs7-mime" |
199 GURL url3 = test_server_.GetURL("/certs.p7c"); | 207 GURL url3 = test_server_.GetURL("/certs.p7c"); |
200 std::unique_ptr<CertNetFetcher::Request> request3 = | 208 std::unique_ptr<CertNetFetcher::Request> request3 = |
201 StartRequest(&fetcher, url3, callback3); | 209 StartRequest(fetcher.get(), url3); |
202 | 210 |
203 // Wait for all of the requests to complete. | 211 // Wait for all of the requests to complete and verify the fetch results. |
204 std::unique_ptr<FetchResult> result1 = callback1.WaitForResult(); | 212 VerifySuccess("-cert.crt-\n", request1.get()); |
205 std::unique_ptr<FetchResult> result2 = callback2.WaitForResult(); | 213 VerifySuccess("-root.crl-\n", request2.get()); |
206 std::unique_ptr<FetchResult> result3 = callback3.WaitForResult(); | 214 VerifySuccess("-certs.p7c-\n", request3.get()); |
207 | 215 |
208 // Verify the fetch results. | 216 EXPECT_EQ(3, NumCreatedRequests()); |
209 result1->VerifySuccess("-cert.crt-\n"); | |
210 result2->VerifySuccess("-root.crl-\n"); | |
211 result3->VerifySuccess("-certs.p7c-\n"); | |
212 | |
213 EXPECT_EQ(3, network_delegate_.created_requests()); | |
214 } | 217 } |
215 | 218 |
216 // Fetch a caIssuers URL which has an unexpected extension and Content-Type. | 219 // Fetch a caIssuers URL which has an unexpected extension and Content-Type. |
217 // The extension is .txt and the Content-Type is text/plain. Despite being | 220 // The extension is .txt and the Content-Type is text/plain. Despite being |
218 // unusual this succeeds as the extension and Content-Type are not required to | 221 // unusual this succeeds as the extension and Content-Type are not required to |
219 // be meaningful. | 222 // be meaningful. |
220 TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) { | 223 TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) { |
221 ASSERT_TRUE(test_server_.Start()); | 224 ASSERT_TRUE(test_server_.Start()); |
222 | 225 |
223 CertNetFetcherImpl fetcher(&context_); | 226 auto fetcher = CreateFetcher(); |
224 | 227 |
225 TestFetchCallback callback; | |
226 GURL url = test_server_.GetURL("/foo.txt"); | 228 GURL url = test_server_.GetURL("/foo.txt"); |
227 std::unique_ptr<CertNetFetcher::Request> request = | 229 std::unique_ptr<CertNetFetcher::Request> request = |
228 StartRequest(&fetcher, url, callback); | 230 StartRequest(fetcher.get(), url); |
229 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 231 VerifySuccess("-foo.txt-\n", request.get()); |
230 result->VerifySuccess("-foo.txt-\n"); | |
231 } | 232 } |
232 | 233 |
233 // Fetch a URLs whose HTTP response code is not 200. These are considered | 234 // Fetch a URLs whose HTTP response code is not 200. These are considered |
234 // failures. | 235 // failures. |
235 TEST_F(CertNetFetcherImplTest, HttpStatusCode) { | 236 TEST_F(CertNetFetcherImplTest, HttpStatusCode) { |
236 ASSERT_TRUE(test_server_.Start()); | 237 ASSERT_TRUE(test_server_.Start()); |
237 | 238 |
238 CertNetFetcherImpl fetcher(&context_); | 239 auto fetcher = CreateFetcher(); |
239 | 240 |
240 // Response was HTTP status 404. | 241 // Response was HTTP status 404. |
241 { | 242 { |
242 TestFetchCallback callback; | |
243 GURL url = test_server_.GetURL("/404.html"); | 243 GURL url = test_server_.GetURL("/404.html"); |
244 std::unique_ptr<CertNetFetcher::Request> request = | 244 std::unique_ptr<CertNetFetcher::Request> request = |
245 StartRequest(&fetcher, url, callback); | 245 StartRequest(fetcher.get(), url); |
246 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 246 VerifyFailure(ERR_FAILED, request.get()); |
247 result->VerifyFailure(ERR_FAILED); | |
248 } | 247 } |
249 | 248 |
250 // Response was HTTP status 500. | 249 // Response was HTTP status 500. |
251 { | 250 { |
252 TestFetchCallback callback; | |
253 GURL url = test_server_.GetURL("/500.html"); | 251 GURL url = test_server_.GetURL("/500.html"); |
254 std::unique_ptr<CertNetFetcher::Request> request = | 252 std::unique_ptr<CertNetFetcher::Request> request = |
255 StartRequest(&fetcher, url, callback); | 253 StartRequest(fetcher.get(), url); |
256 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 254 VerifyFailure(ERR_FAILED, request.get()); |
257 result->VerifyFailure(ERR_FAILED); | |
258 } | 255 } |
259 } | 256 } |
260 | 257 |
261 // Fetching a URL with a Content-Disposition header should have no effect. | 258 // Fetching a URL with a Content-Disposition header should have no effect. |
262 TEST_F(CertNetFetcherImplTest, ContentDisposition) { | 259 TEST_F(CertNetFetcherImplTest, ContentDisposition) { |
263 ASSERT_TRUE(test_server_.Start()); | 260 ASSERT_TRUE(test_server_.Start()); |
264 | 261 |
265 CertNetFetcherImpl fetcher(&context_); | 262 auto fetcher = CreateFetcher(); |
266 | 263 |
267 TestFetchCallback callback; | |
268 GURL url = test_server_.GetURL("/downloadable.js"); | 264 GURL url = test_server_.GetURL("/downloadable.js"); |
269 std::unique_ptr<CertNetFetcher::Request> request = | 265 std::unique_ptr<CertNetFetcher::Request> request = |
270 StartRequest(&fetcher, url, callback); | 266 StartRequest(fetcher.get(), url); |
271 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 267 VerifySuccess("-downloadable.js-\n", request.get()); |
272 result->VerifySuccess("-downloadable.js-\n"); | |
273 } | 268 } |
274 | 269 |
275 // Verifies that a cachable request will be served from the HTTP cache the | 270 // Verifies that a cachable request will be served from the HTTP cache the |
276 // second time it is requested. | 271 // second time it is requested. |
277 TEST_F(CertNetFetcherImplTest, Cache) { | 272 TEST_F(CertNetFetcherImplTest, Cache) { |
278 ASSERT_TRUE(test_server_.Start()); | 273 ASSERT_TRUE(test_server_.Start()); |
279 | 274 |
280 CertNetFetcherImpl fetcher(&context_); | 275 auto fetcher = CreateFetcher(); |
281 | 276 |
282 // Fetch a URL whose HTTP headers make it cacheable for 1 hour. | 277 // Fetch a URL whose HTTP headers make it cacheable for 1 hour. |
283 GURL url(test_server_.GetURL("/cacheable_1hr.crt")); | 278 GURL url(test_server_.GetURL("/cacheable_1hr.crt")); |
284 { | 279 { |
285 TestFetchCallback callback; | |
286 | |
287 std::unique_ptr<CertNetFetcher::Request> request = | 280 std::unique_ptr<CertNetFetcher::Request> request = |
288 StartRequest(&fetcher, url, callback); | 281 StartRequest(fetcher.get(), url); |
289 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 282 VerifySuccess("-cacheable_1hr.crt-\n", request.get()); |
290 result->VerifySuccess("-cacheable_1hr.crt-\n"); | |
291 } | 283 } |
292 | 284 |
293 EXPECT_EQ(1, network_delegate_.created_requests()); | 285 EXPECT_EQ(1, NumCreatedRequests()); |
294 | 286 |
295 // Kill the HTTP server. | 287 // Kill the HTTP server. |
296 ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete()); | 288 ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete()); |
297 | 289 |
298 // Fetch again -- will fail unless served from cache. | 290 // Fetch again -- will fail unless served from cache. |
299 { | 291 { |
300 TestFetchCallback callback; | |
301 std::unique_ptr<CertNetFetcher::Request> request = | 292 std::unique_ptr<CertNetFetcher::Request> request = |
302 StartRequest(&fetcher, url, callback); | 293 StartRequest(fetcher.get(), url); |
303 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 294 VerifySuccess("-cacheable_1hr.crt-\n", request.get()); |
304 result->VerifySuccess("-cacheable_1hr.crt-\n"); | |
305 } | 295 } |
306 | 296 |
307 EXPECT_EQ(2, network_delegate_.created_requests()); | 297 EXPECT_EQ(2, NumCreatedRequests()); |
308 } | 298 } |
309 | 299 |
310 // Verify that the maximum response body constraints are enforced by fetching a | 300 // Verify that the maximum response body constraints are enforced by fetching a |
311 // resource that is larger than the limit. | 301 // resource that is larger than the limit. |
312 TEST_F(CertNetFetcherImplTest, TooLarge) { | 302 TEST_F(CertNetFetcherImplTest, TooLarge) { |
313 ASSERT_TRUE(test_server_.Start()); | 303 ASSERT_TRUE(test_server_.Start()); |
314 | 304 |
315 CertNetFetcherImpl fetcher(&context_); | 305 auto fetcher = CreateFetcher(); |
316 | 306 |
317 // This file has a response body 12 bytes long. So setting the maximum to 11 | 307 // This file has a response body 12 bytes long. So setting the maximum to 11 |
318 // bytes will cause it to fail. | 308 // bytes will cause it to fail. |
319 GURL url(test_server_.GetURL("/certs.p7c")); | 309 GURL url(test_server_.GetURL("/certs.p7c")); |
320 TestFetchCallback callback; | 310 std::unique_ptr<CertNetFetcher::Request> request = |
321 std::unique_ptr<CertNetFetcher::Request> request = fetcher.FetchCaIssuers( | 311 fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, 11); |
322 url, CertNetFetcher::DEFAULT, 11, callback.callback()); | |
323 | 312 |
324 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 313 VerifyFailure(ERR_FILE_TOO_BIG, request.get()); |
325 result->VerifyFailure(ERR_FILE_TOO_BIG); | |
326 } | 314 } |
327 | 315 |
328 // Set the timeout to 10 milliseconds, and try fetching a URL that takes 5 | 316 // Set the timeout to 10 milliseconds, and try fetching a URL that takes 5 |
329 // seconds to complete. It should fail due to a timeout. | 317 // seconds to complete. It should fail due to a timeout. |
330 TEST_F(CertNetFetcherImplTest, Hang) { | 318 TEST_F(CertNetFetcherImplTest, Hang) { |
331 ASSERT_TRUE(test_server_.Start()); | 319 ASSERT_TRUE(test_server_.Start()); |
332 | 320 |
333 CertNetFetcherImpl fetcher(&context_); | 321 auto fetcher = CreateFetcher(); |
334 | 322 |
335 GURL url(test_server_.GetURL("/slow/certs.p7c?5")); | 323 GURL url(test_server_.GetURL("/slow/certs.p7c?5")); |
336 TestFetchCallback callback; | 324 std::unique_ptr<CertNetFetcher::Request> request = |
337 std::unique_ptr<CertNetFetcher::Request> request = fetcher.FetchCaIssuers( | 325 fetcher->FetchCaIssuers(url, 10, CertNetFetcher::DEFAULT); |
338 url, 10, CertNetFetcher::DEFAULT, callback.callback()); | 326 VerifyFailure(ERR_TIMED_OUT, request.get()); |
339 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | |
340 result->VerifyFailure(ERR_TIMED_OUT); | |
341 } | 327 } |
342 | 328 |
343 // Verify that if a response is gzip-encoded it gets inflated before being | 329 // Verify that if a response is gzip-encoded it gets inflated before being |
344 // returned to the caller. | 330 // returned to the caller. |
345 TEST_F(CertNetFetcherImplTest, Gzip) { | 331 TEST_F(CertNetFetcherImplTest, Gzip) { |
346 ASSERT_TRUE(test_server_.Start()); | 332 ASSERT_TRUE(test_server_.Start()); |
347 | 333 |
348 CertNetFetcherImpl fetcher(&context_); | 334 auto fetcher = CreateFetcher(); |
349 | 335 |
350 GURL url(test_server_.GetURL("/gzipped_crl")); | 336 GURL url(test_server_.GetURL("/gzipped_crl")); |
351 TestFetchCallback callback; | |
352 std::unique_ptr<CertNetFetcher::Request> request = | 337 std::unique_ptr<CertNetFetcher::Request> request = |
353 StartRequest(&fetcher, url, callback); | 338 StartRequest(fetcher.get(), url); |
354 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 339 VerifySuccess("-gzipped_crl-\n", request.get()); |
355 result->VerifySuccess("-gzipped_crl-\n"); | |
356 } | 340 } |
357 | 341 |
358 // Try fetching an unsupported URL scheme (https). | 342 // Try fetching an unsupported URL scheme (https). |
359 TEST_F(CertNetFetcherImplTest, HttpsNotAllowed) { | 343 TEST_F(CertNetFetcherImplTest, HttpsNotAllowed) { |
360 ASSERT_TRUE(test_server_.Start()); | 344 ASSERT_TRUE(test_server_.Start()); |
361 | 345 |
362 CertNetFetcherImpl fetcher(&context_); | 346 auto fetcher = CreateFetcher(); |
363 | 347 |
364 GURL url("https://foopy/foo.crt"); | 348 GURL url("https://foopy/foo.crt"); |
365 TestFetchCallback callback; | |
366 std::unique_ptr<CertNetFetcher::Request> request = | 349 std::unique_ptr<CertNetFetcher::Request> request = |
367 StartRequest(&fetcher, url, callback); | 350 StartRequest(fetcher.get(), url); |
368 // Should NOT complete synchronously despite being a test that could be done | 351 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get()); |
369 // immediately. | |
370 EXPECT_FALSE(callback.HasResult()); | |
371 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | |
372 result->VerifyFailure(ERR_DISALLOWED_URL_SCHEME); | |
373 | 352 |
374 // No request was created because the URL scheme was unsupported. | 353 // No request was created because the URL scheme was unsupported. |
375 EXPECT_EQ(0, network_delegate_.created_requests()); | 354 EXPECT_EQ(0, NumCreatedRequests()); |
376 } | 355 } |
377 | 356 |
378 // Try fetching a URL which redirects to https. | 357 // Try fetching a URL which redirects to https. |
379 TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) { | 358 TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) { |
380 ASSERT_TRUE(test_server_.Start()); | 359 ASSERT_TRUE(test_server_.Start()); |
381 | 360 |
382 CertNetFetcherImpl fetcher(&context_); | 361 auto fetcher = CreateFetcher(); |
383 | 362 |
384 GURL url(test_server_.GetURL("/redirect_https")); | 363 GURL url(test_server_.GetURL("/redirect_https")); |
385 TestFetchCallback callback; | |
386 | 364 |
387 std::unique_ptr<CertNetFetcher::Request> request = | 365 std::unique_ptr<CertNetFetcher::Request> request = |
388 StartRequest(&fetcher, url, callback); | 366 StartRequest(fetcher.get(), url); |
389 std::unique_ptr<FetchResult> result = callback.WaitForResult(); | 367 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get()); |
390 result->VerifyFailure(ERR_DISALLOWED_URL_SCHEME); | |
391 | 368 |
392 EXPECT_EQ(1, network_delegate_.created_requests()); | 369 EXPECT_EQ(1, NumCreatedRequests()); |
393 } | 370 } |
394 | 371 |
395 // Try fetching an unsupported URL scheme (https) and then immediately | 372 // Try fetching an unsupported URL scheme (https) and then immediately |
396 // cancelling. This is a bit special because this codepath needs to post a task. | 373 // cancelling. This is a bit special because this codepath needs to post a task. |
397 TEST_F(CertNetFetcherImplTest, CancelHttpsNotAllowed) { | 374 TEST_F(CertNetFetcherImplTest, CancelHttpsNotAllowed) { |
398 ASSERT_TRUE(test_server_.Start()); | 375 ASSERT_TRUE(test_server_.Start()); |
399 | 376 |
400 CertNetFetcherImpl fetcher(&context_); | 377 auto fetcher = CreateFetcher(); |
401 | 378 |
402 GURL url("https://foopy/foo.crt"); | 379 GURL url("https://foopy/foo.crt"); |
403 TestFetchCallback callback; | |
404 std::unique_ptr<CertNetFetcher::Request> request = | 380 std::unique_ptr<CertNetFetcher::Request> request = |
405 StartRequest(&fetcher, url, callback); | 381 StartRequest(fetcher.get(), url); |
406 | 382 |
407 // Cancel the request. | 383 // Cancel the request (May or may not have started yet, as the request is |
| 384 // running on another thread). |
408 request.reset(); | 385 request.reset(); |
409 | |
410 // Spin the message loop to increase chance of catching a bug. | |
411 base::RunLoop().RunUntilIdle(); | |
412 | |
413 // Should NOT complete synchronously despite being a test that could be done | |
414 // immediately. | |
415 EXPECT_FALSE(callback.HasResult()); | |
416 | |
417 EXPECT_EQ(0, network_delegate_.created_requests()); | |
418 } | 386 } |
419 | 387 |
420 // Flaky on Android. See http://crbug.com/646147. | 388 // Flaky on Android. See http://crbug.com/646147. |
421 #if defined(OS_ANDROID) | 389 #if defined(OS_ANDROID) |
422 #define MAYBE_CancelBeforeRunningMessageLoop \ | 390 #define MAYBE_CancelBeforeRunningMessageLoop \ |
423 DISABLED_CancelBeforeRunningMessageLoop | 391 DISABLED_CancelBeforeRunningMessageLoop |
424 #else | 392 #else |
425 #define MAYBE_CancelBeforeRunningMessageLoop CancelBeforeRunningMessageLoop | 393 #define MAYBE_CancelBeforeRunningMessageLoop CancelBeforeRunningMessageLoop |
426 #endif | 394 #endif |
427 // Start a few requests, and cancel one of them before running the message loop | 395 // Start a few requests, and cancel one of them before running the message loop |
428 // again. | 396 // again. |
429 TEST_F(CertNetFetcherImplTest, MAYBE_CancelBeforeRunningMessageLoop) { | 397 TEST_F(CertNetFetcherImplTest, MAYBE_CancelBeforeRunningMessageLoop) { |
430 ASSERT_TRUE(test_server_.Start()); | 398 ASSERT_TRUE(test_server_.Start()); |
431 | 399 |
432 CertNetFetcherImpl fetcher(&context_); | 400 auto fetcher = CreateFetcher(); |
433 TestFetchCallback callback1; | |
434 TestFetchCallback callback2; | |
435 TestFetchCallback callback3; | |
436 | 401 |
437 GURL url1 = test_server_.GetURL("/cert.crt"); | 402 GURL url1 = test_server_.GetURL("/cert.crt"); |
438 std::unique_ptr<CertNetFetcher::Request> request1 = | 403 std::unique_ptr<CertNetFetcher::Request> request1 = |
439 StartRequest(&fetcher, url1, callback1); | 404 StartRequest(fetcher.get(), url1); |
440 | 405 |
441 GURL url2 = test_server_.GetURL("/root.crl"); | 406 GURL url2 = test_server_.GetURL("/root.crl"); |
442 std::unique_ptr<CertNetFetcher::Request> request2 = | 407 std::unique_ptr<CertNetFetcher::Request> request2 = |
443 StartRequest(&fetcher, url2, callback2); | 408 StartRequest(fetcher.get(), url2); |
444 | 409 |
445 GURL url3 = test_server_.GetURL("/certs.p7c"); | 410 GURL url3 = test_server_.GetURL("/certs.p7c"); |
446 | 411 |
447 std::unique_ptr<CertNetFetcher::Request> request3 = | 412 std::unique_ptr<CertNetFetcher::Request> request3 = |
448 StartRequest(&fetcher, url3, callback3); | 413 StartRequest(fetcher.get(), url3); |
449 | |
450 EXPECT_EQ(3, network_delegate_.created_requests()); | |
451 EXPECT_FALSE(callback1.HasResult()); | |
452 EXPECT_FALSE(callback2.HasResult()); | |
453 EXPECT_FALSE(callback3.HasResult()); | |
454 | 414 |
455 // Cancel the second request. | 415 // Cancel the second request. |
456 request2.reset(); | 416 request2.reset(); |
457 | 417 |
458 // Wait for the non-cancelled requests to complete. | 418 // Wait for the non-cancelled requests to complete, and verify the fetch |
459 std::unique_ptr<FetchResult> result1 = callback1.WaitForResult(); | 419 // results. |
460 std::unique_ptr<FetchResult> result3 = callback3.WaitForResult(); | 420 VerifySuccess("-cert.crt-\n", request1.get()); |
461 | 421 VerifySuccess("-certs.p7c-\n", request3.get()); |
462 // Verify the fetch results. | |
463 result1->VerifySuccess("-cert.crt-\n"); | |
464 result3->VerifySuccess("-certs.p7c-\n"); | |
465 | |
466 EXPECT_FALSE(callback2.HasResult()); | |
467 } | 422 } |
468 | 423 |
469 // Start several requests, and cancel one of them after the first has completed. | 424 // Start several requests, and cancel one of them after the first has completed. |
470 // NOTE: The python test server is single threaded and can only service one | 425 // NOTE: The python test server is single threaded and can only service one |
471 // request at a time. After a socket is opened by the server it waits for it to | 426 // request at a time. After a socket is opened by the server it waits for it to |
472 // be completed, and any subsequent request will hang until the first socket is | 427 // be completed, and any subsequent request will hang until the first socket is |
473 // closed. | 428 // closed. |
474 // Cancelling the first request can therefore be problematic, since if | 429 // Cancelling the first request can therefore be problematic, since if |
475 // cancellation is done after the socket is opened but before reading/writing, | 430 // cancellation is done after the socket is opened but before reading/writing, |
476 // then the socket is re-cycled and things will be stalled until the cleanup | 431 // then the socket is re-cycled and things will be stalled until the cleanup |
477 // timer (10 seconds) closes it. | 432 // timer (10 seconds) closes it. |
478 // To work around this, the last request is cancelled, and hope that the | 433 // To work around this, the last request is cancelled, and hope that the |
479 // requests are given opened sockets in a FIFO order. | 434 // requests are given opened sockets in a FIFO order. |
480 // TODO(eroman): Make this more robust. | 435 // TODO(eroman): Make this more robust. |
| 436 // TODO(eroman): Rename this test. |
481 TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) { | 437 TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) { |
482 ASSERT_TRUE(test_server_.Start()); | 438 ASSERT_TRUE(test_server_.Start()); |
483 | 439 |
484 CertNetFetcherImpl fetcher(&context_); | 440 auto fetcher = CreateFetcher(); |
485 TestFetchCallback callback1; | |
486 TestFetchCallback callback2; | |
487 TestFetchCallback callback3; | |
488 | 441 |
489 GURL url1 = test_server_.GetURL("/cert.crt"); | 442 GURL url1 = test_server_.GetURL("/cert.crt"); |
490 | 443 |
491 std::unique_ptr<CertNetFetcher::Request> request1 = | 444 std::unique_ptr<CertNetFetcher::Request> request1 = |
492 StartRequest(&fetcher, url1, callback1); | 445 StartRequest(fetcher.get(), url1); |
493 | 446 |
494 GURL url2 = test_server_.GetURL("/certs.p7c"); | 447 GURL url2 = test_server_.GetURL("/certs.p7c"); |
495 std::unique_ptr<CertNetFetcher::Request> request2 = | 448 std::unique_ptr<CertNetFetcher::Request> request2 = |
496 StartRequest(&fetcher, url2, callback2); | 449 StartRequest(fetcher.get(), url2); |
497 | 450 |
498 GURL url3("ftp://www.not.supported.com/foo"); | 451 GURL url3("ftp://www.not.supported.com/foo"); |
499 std::unique_ptr<CertNetFetcher::Request> request3 = | 452 std::unique_ptr<CertNetFetcher::Request> request3 = |
500 StartRequest(&fetcher, url3, callback3); | 453 StartRequest(fetcher.get(), url3); |
501 | |
502 EXPECT_FALSE(callback1.HasResult()); | |
503 EXPECT_FALSE(callback2.HasResult()); | |
504 EXPECT_FALSE(callback3.HasResult()); | |
505 | 454 |
506 // Wait for the ftp request to complete (it should complete right away since | 455 // Wait for the ftp request to complete (it should complete right away since |
507 // it doesn't even try to connect to the server). | 456 // it doesn't even try to connect to the server). |
508 std::unique_ptr<FetchResult> result3 = callback3.WaitForResult(); | 457 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request3.get()); |
509 result3->VerifyFailure(ERR_DISALLOWED_URL_SCHEME); | |
510 | 458 |
511 // Cancel the second outstanding request. | 459 // Cancel the second outstanding request. |
512 request2.reset(); | 460 request2.reset(); |
513 | 461 |
514 // Wait for the first request to complete. | 462 // Wait for the first request to complete and verify the fetch result. |
515 std::unique_ptr<FetchResult> result2 = callback1.WaitForResult(); | 463 VerifySuccess("-cert.crt-\n", request1.get()); |
516 | |
517 // Verify the fetch results. | |
518 result2->VerifySuccess("-cert.crt-\n"); | |
519 } | |
520 | |
521 // Delete a CertNetFetcherImpl with outstanding requests on it. | |
522 TEST_F(CertNetFetcherImplTest, DeleteCancels) { | |
523 ASSERT_TRUE(test_server_.Start()); | |
524 | |
525 std::unique_ptr<CertNetFetcherImpl> fetcher( | |
526 new CertNetFetcherImpl(&context_)); | |
527 | |
528 GURL url(test_server_.GetURL("/slow/certs.p7c?20")); | |
529 TestFetchCallback callback; | |
530 std::unique_ptr<CertNetFetcher::Request> request = | |
531 StartRequest(fetcher.get(), url, callback); | |
532 | |
533 // Destroy the fetcher before the outstanding request. | |
534 fetcher.reset(); | |
535 } | 464 } |
536 | 465 |
537 // Flaky on Android. See http://crbug.com/646147. | 466 // Flaky on Android. See http://crbug.com/646147. |
538 #if defined(OS_ANDROID) | 467 #if defined(OS_ANDROID) |
539 #define MAYBE_ParallelFetchDuplicates DISABLED_ParallelFetchDuplicates | 468 #define MAYBE_ParallelFetchDuplicates DISABLED_ParallelFetchDuplicates |
540 #else | 469 #else |
541 #define MAYBE_ParallelFetchDuplicates ParallelFetchDuplicates | 470 #define MAYBE_ParallelFetchDuplicates ParallelFetchDuplicates |
542 #endif | 471 #endif |
543 // Fetch the same URLs in parallel and verify that only 1 request is made per | 472 // Fetch the same URLs in parallel and verify that only 1 request is made per |
544 // URL. | 473 // URL. |
545 TEST_F(CertNetFetcherImplTest, MAYBE_ParallelFetchDuplicates) { | 474 TEST_F(CertNetFetcherImplTest, MAYBE_ParallelFetchDuplicates) { |
546 ASSERT_TRUE(test_server_.Start()); | 475 ASSERT_TRUE(test_server_.Start()); |
547 | 476 |
548 CertNetFetcherImpl fetcher(&context_); | 477 auto fetcher = CreateFetcher(); |
549 | 478 |
550 GURL url1 = test_server_.GetURL("/cert.crt"); | 479 GURL url1 = test_server_.GetURL("/cert.crt"); |
551 GURL url2 = test_server_.GetURL("/root.crl"); | 480 GURL url2 = test_server_.GetURL("/root.crl"); |
552 | 481 |
553 // Issue 3 requests for url1, and 3 requests for url2 | 482 // Issue 3 requests for url1, and 3 requests for url2 |
554 TestFetchCallback callback1; | |
555 std::unique_ptr<CertNetFetcher::Request> request1 = | 483 std::unique_ptr<CertNetFetcher::Request> request1 = |
556 StartRequest(&fetcher, url1, callback1); | 484 StartRequest(fetcher.get(), url1); |
557 | 485 |
558 TestFetchCallback callback2; | |
559 std::unique_ptr<CertNetFetcher::Request> request2 = | 486 std::unique_ptr<CertNetFetcher::Request> request2 = |
560 StartRequest(&fetcher, url2, callback2); | 487 StartRequest(fetcher.get(), url2); |
561 | 488 |
562 TestFetchCallback callback3; | |
563 std::unique_ptr<CertNetFetcher::Request> request3 = | 489 std::unique_ptr<CertNetFetcher::Request> request3 = |
564 StartRequest(&fetcher, url1, callback3); | 490 StartRequest(fetcher.get(), url1); |
565 | 491 |
566 TestFetchCallback callback4; | |
567 std::unique_ptr<CertNetFetcher::Request> request4 = | 492 std::unique_ptr<CertNetFetcher::Request> request4 = |
568 StartRequest(&fetcher, url2, callback4); | 493 StartRequest(fetcher.get(), url2); |
569 | 494 |
570 TestFetchCallback callback5; | |
571 std::unique_ptr<CertNetFetcher::Request> request5 = | 495 std::unique_ptr<CertNetFetcher::Request> request5 = |
572 StartRequest(&fetcher, url2, callback5); | 496 StartRequest(fetcher.get(), url2); |
573 | 497 |
574 TestFetchCallback callback6; | |
575 std::unique_ptr<CertNetFetcher::Request> request6 = | 498 std::unique_ptr<CertNetFetcher::Request> request6 = |
576 StartRequest(&fetcher, url1, callback6); | 499 StartRequest(fetcher.get(), url1); |
577 | 500 |
578 // Cancel all but one of the requests for url1. | 501 // Cancel all but one of the requests for url1. |
579 request1.reset(); | 502 request1.reset(); |
580 request3.reset(); | 503 request3.reset(); |
581 | 504 |
582 // Wait for the remaining requests to finish. | 505 // Wait for the remaining requests to finish and verify the fetch results. |
583 std::unique_ptr<FetchResult> result2 = callback2.WaitForResult(); | 506 VerifySuccess("-root.crl-\n", request2.get()); |
584 std::unique_ptr<FetchResult> result4 = callback4.WaitForResult(); | 507 VerifySuccess("-root.crl-\n", request4.get()); |
585 std::unique_ptr<FetchResult> result5 = callback5.WaitForResult(); | 508 VerifySuccess("-root.crl-\n", request5.get()); |
586 std::unique_ptr<FetchResult> result6 = callback6.WaitForResult(); | 509 VerifySuccess("-cert.crt-\n", request6.get()); |
587 | |
588 // Verify that none of the cancelled requests for url1 completed (since they | |
589 // were cancelled). | |
590 EXPECT_FALSE(callback1.HasResult()); | |
591 EXPECT_FALSE(callback3.HasResult()); | |
592 | |
593 // Verify the fetch results. | |
594 result2->VerifySuccess("-root.crl-\n"); | |
595 result4->VerifySuccess("-root.crl-\n"); | |
596 result5->VerifySuccess("-root.crl-\n"); | |
597 result6->VerifySuccess("-cert.crt-\n"); | |
598 | 510 |
599 // Verify that only 2 URLRequests were started even though 6 requests were | 511 // Verify that only 2 URLRequests were started even though 6 requests were |
600 // issued. | 512 // issued. |
601 EXPECT_EQ(2, network_delegate_.created_requests()); | 513 EXPECT_EQ(2, NumCreatedRequests()); |
602 } | 514 } |
603 | 515 |
604 // Flaky on Android. See http://crbug.com/646147. | 516 // Flaky on Android. See http://crbug.com/646147. |
605 #if defined(OS_ANDROID) | 517 #if defined(OS_ANDROID) |
606 #define MAYBE_CancelThenStart DISABLED_CancelThenStart | 518 #define MAYBE_CancelThenStart DISABLED_CancelThenStart |
607 #else | 519 #else |
608 #define MAYBE_CancelThenStart CancelThenStart | 520 #define MAYBE_CancelThenStart CancelThenStart |
609 #endif | 521 #endif |
610 // Cancel a request and then start another one for the same URL. | 522 // Cancel a request and then start another one for the same URL. |
611 TEST_F(CertNetFetcherImplTest, MAYBE_CancelThenStart) { | 523 TEST_F(CertNetFetcherImplTest, MAYBE_CancelThenStart) { |
612 ASSERT_TRUE(test_server_.Start()); | 524 ASSERT_TRUE(test_server_.Start()); |
613 | 525 |
614 CertNetFetcherImpl fetcher(&context_); | 526 auto fetcher = CreateFetcher(); |
615 TestFetchCallback callback1; | |
616 TestFetchCallback callback2; | |
617 TestFetchCallback callback3; | |
618 | 527 |
619 GURL url = test_server_.GetURL("/cert.crt"); | 528 GURL url = test_server_.GetURL("/cert.crt"); |
620 | 529 |
621 std::unique_ptr<CertNetFetcher::Request> request1 = | 530 std::unique_ptr<CertNetFetcher::Request> request1 = |
622 StartRequest(&fetcher, url, callback1); | 531 StartRequest(fetcher.get(), url); |
623 request1.reset(); | 532 request1.reset(); |
624 | 533 |
625 std::unique_ptr<CertNetFetcher::Request> request2 = | 534 std::unique_ptr<CertNetFetcher::Request> request2 = |
626 StartRequest(&fetcher, url, callback2); | 535 StartRequest(fetcher.get(), url); |
627 | 536 |
628 std::unique_ptr<CertNetFetcher::Request> request3 = | 537 std::unique_ptr<CertNetFetcher::Request> request3 = |
629 StartRequest(&fetcher, url, callback3); | 538 StartRequest(fetcher.get(), url); |
630 request3.reset(); | 539 request3.reset(); |
631 | 540 |
632 // All but |request2| were canceled. | 541 // All but |request2| were canceled. |
633 std::unique_ptr<FetchResult> result = callback2.WaitForResult(); | 542 VerifySuccess("-cert.crt-\n", request2.get()); |
634 | |
635 result->VerifySuccess("-cert.crt-\n"); | |
636 | |
637 EXPECT_FALSE(callback1.HasResult()); | |
638 EXPECT_FALSE(callback3.HasResult()); | |
639 | |
640 // One URLRequest that was cancelled, then another right afterwards. | |
641 EXPECT_EQ(2, network_delegate_.created_requests()); | |
642 } | 543 } |
643 | 544 |
644 // Start duplicate requests and then cancel all of them. | 545 // Start duplicate requests and then cancel all of them. |
645 TEST_F(CertNetFetcherImplTest, CancelAll) { | 546 TEST_F(CertNetFetcherImplTest, CancelAll) { |
646 ASSERT_TRUE(test_server_.Start()); | 547 ASSERT_TRUE(test_server_.Start()); |
647 | 548 |
648 CertNetFetcherImpl fetcher(&context_); | 549 auto fetcher = CreateFetcher(); |
649 TestFetchCallback callback[3]; | |
650 std::unique_ptr<CertNetFetcher::Request> request[3]; | 550 std::unique_ptr<CertNetFetcher::Request> request[3]; |
651 | 551 |
652 GURL url = test_server_.GetURL("/cert.crt"); | 552 GURL url = test_server_.GetURL("/cert.crt"); |
653 | 553 |
654 for (size_t i = 0; i < arraysize(callback); ++i) { | 554 for (size_t i = 0; i < arraysize(request); ++i) { |
655 request[i] = StartRequest(&fetcher, url, callback[i]); | 555 request[i] = StartRequest(fetcher.get(), url); |
656 } | 556 } |
657 | 557 |
658 // Cancel all the requests. | 558 // Cancel all the requests. |
659 for (size_t i = 0; i < arraysize(request); ++i) | 559 for (size_t i = 0; i < arraysize(request); ++i) |
660 request[i].reset(); | 560 request[i].reset(); |
661 | 561 |
662 EXPECT_EQ(1, network_delegate_.created_requests()); | 562 EXPECT_EQ(1, NumCreatedRequests()); |
663 | |
664 for (size_t i = 0; i < arraysize(request); ++i) | |
665 EXPECT_FALSE(callback[i].HasResult()); | |
666 } | 563 } |
667 | 564 |
668 void DeleteCertNetFetcher(CertNetFetcher* fetcher) { | 565 } // namespace |
669 delete fetcher; | |
670 } | |
671 | |
672 // Delete the CertNetFetcherImpl within a request callback. | |
673 TEST_F(CertNetFetcherImplTest, DeleteWithinCallback) { | |
674 ASSERT_TRUE(test_server_.Start()); | |
675 | |
676 // Deleted by callback2. | |
677 CertNetFetcher* fetcher = new CertNetFetcherImpl(&context_); | |
678 | |
679 GURL url = test_server_.GetURL("/cert.crt"); | |
680 | |
681 TestFetchCallback callback[4]; | |
682 std::unique_ptr<CertNetFetcher::Request> reqs[4]; | |
683 callback[1].set_extra_closure(base::Bind(DeleteCertNetFetcher, fetcher)); | |
684 | |
685 for (size_t i = 0; i < arraysize(callback); ++i) | |
686 reqs[i] = StartRequest(fetcher, url, callback[i]); | |
687 | |
688 EXPECT_EQ(1, network_delegate_.created_requests()); | |
689 | |
690 callback[1].WaitForResult(); | |
691 | |
692 // Assume requests for the same URL are executed in FIFO order. | |
693 EXPECT_TRUE(callback[0].HasResult()); | |
694 EXPECT_FALSE(callback[2].HasResult()); | |
695 EXPECT_FALSE(callback[3].HasResult()); | |
696 } | |
697 | |
698 void FetchRequest(CertNetFetcher* fetcher, | |
699 const GURL& url, | |
700 TestFetchCallback* callback, | |
701 std::unique_ptr<CertNetFetcher::Request>* request) { | |
702 *request = StartRequest(fetcher, url, *callback); | |
703 } | |
704 | |
705 // Flaky on Android. See http://crbug.com/646147. | |
706 #if defined(OS_ANDROID) | |
707 #define MAYBE_FetchWithinCallback DISABLED_FetchWithinCallback | |
708 #else | |
709 #define MAYBE_FetchWithinCallback FetchWithinCallback | |
710 #endif | |
711 // Make a request during callback for the same URL. | |
712 TEST_F(CertNetFetcherImplTest, MAYBE_FetchWithinCallback) { | |
713 ASSERT_TRUE(test_server_.Start()); | |
714 | |
715 CertNetFetcherImpl fetcher(&context_); | |
716 | |
717 GURL url = test_server_.GetURL("/cert.crt"); | |
718 | |
719 TestFetchCallback callback[5]; | |
720 std::unique_ptr<CertNetFetcher::Request> req[5]; | |
721 callback[1].set_extra_closure( | |
722 base::Bind(FetchRequest, &fetcher, url, &callback[4], &req[4])); | |
723 | |
724 for (size_t i = 0; i < arraysize(callback) - 1; ++i) | |
725 req[i] = StartRequest(&fetcher, url, callback[i]); | |
726 | |
727 EXPECT_EQ(1, network_delegate_.created_requests()); | |
728 | |
729 for (size_t i = 0; i < arraysize(callback); ++i) { | |
730 std::unique_ptr<FetchResult> result = callback[i].WaitForResult(); | |
731 result->VerifySuccess("-cert.crt-\n"); | |
732 } | |
733 | |
734 // The fetch started within a callback should have started a new request | |
735 // rather than attaching to the current job. | |
736 EXPECT_EQ(2, network_delegate_.created_requests()); | |
737 } | |
738 | |
739 void CancelRequest(std::unique_ptr<CertNetFetcher::Request>* request) { | |
740 request->reset(); | |
741 } | |
742 | |
743 // Cancel a request while executing a callback for the same job. | |
744 TEST_F(CertNetFetcherImplTest, CancelWithinCallback) { | |
745 ASSERT_TRUE(test_server_.Start()); | |
746 | |
747 CertNetFetcherImpl fetcher(&context_); | |
748 | |
749 GURL url = test_server_.GetURL("/cert.crt"); | |
750 | |
751 TestFetchCallback callback[4]; | |
752 std::unique_ptr<CertNetFetcher::Request> request[4]; | |
753 | |
754 for (size_t i = 0; i < arraysize(callback); ++i) | |
755 request[i] = StartRequest(&fetcher, url, callback[i]); | |
756 | |
757 // Cancel request[2] when the callback for request[1] runs. | |
758 callback[1].set_extra_closure(base::Bind(CancelRequest, &request[2])); | |
759 | |
760 EXPECT_EQ(1, network_delegate_.created_requests()); | |
761 | |
762 for (size_t i = 0; i < arraysize(request); ++i) { | |
763 if (i == 2) | |
764 continue; | |
765 | |
766 std::unique_ptr<FetchResult> result = callback[i].WaitForResult(); | |
767 result->VerifySuccess("-cert.crt-\n"); | |
768 } | |
769 | |
770 // request[2] was cancelled. | |
771 EXPECT_FALSE(callback[2].HasResult()); | |
772 } | |
773 | |
774 // Flaky on Android. See http://crbug.com/646147. | |
775 #if defined(OS_ANDROID) | |
776 #define MAYBE_CancelLastRequestWithinCallback \ | |
777 DISABLED_CancelLastRequestWithinCallback | |
778 #else | |
779 #define MAYBE_CancelLastRequestWithinCallback CancelLastRequestWithinCallback | |
780 #endif | |
781 // Cancel the final request while executing a callback for the same job. Ensure | |
782 // that the job is not deleted twice. | |
783 TEST_F(CertNetFetcherImplTest, MAYBE_CancelLastRequestWithinCallback) { | |
784 ASSERT_TRUE(test_server_.Start()); | |
785 | |
786 CertNetFetcherImpl fetcher(&context_); | |
787 | |
788 GURL url = test_server_.GetURL("/cert.crt"); | |
789 | |
790 TestFetchCallback callback1; | |
791 std::unique_ptr<CertNetFetcher::Request> request1 = | |
792 StartRequest(&fetcher, url, callback1); | |
793 | |
794 TestFetchCallback callback2; | |
795 std::unique_ptr<CertNetFetcher::Request> request2 = | |
796 StartRequest(&fetcher, url, callback1); | |
797 | |
798 // Cancel request2 when the callback for request1 runs. | |
799 callback1.set_extra_closure(base::Bind(CancelRequest, &request2)); | |
800 | |
801 EXPECT_EQ(1, network_delegate_.created_requests()); | |
802 | |
803 std::unique_ptr<FetchResult> result = callback1.WaitForResult(); | |
804 result->VerifySuccess("-cert.crt-\n"); | |
805 | |
806 // request2 was cancelled. | |
807 EXPECT_FALSE(callback2.HasResult()); | |
808 } | |
809 | 566 |
810 } // namespace net | 567 } // namespace net |
OLD | NEW |