Chromium Code Reviews| 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" | 13 #include "base/synchronization/lock.h" |
| 14 #include "net/cert/cert_net_fetcher.h" | 14 #include "net/cert/cert_net_fetcher.h" |
| 15 #include "net/cert/ct_policy_enforcer.h" | 15 #include "net/cert/ct_policy_enforcer.h" |
| 16 #include "net/cert/mock_cert_verifier.h" | 16 #include "net/cert/mock_cert_verifier.h" |
| 17 #include "net/cert/multi_log_ct_verifier.h" | 17 #include "net/cert/multi_log_ct_verifier.h" |
| 18 #include "net/dns/mock_host_resolver.h" | 18 #include "net/dns/mock_host_resolver.h" |
| 19 #include "net/http/http_server_properties_impl.h" | 19 #include "net/http/http_server_properties_impl.h" |
| 20 #include "net/test/embedded_test_server/embedded_test_server.h" | 20 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 21 #include "net/test/gtest_util.h" | 21 #include "net/test/gtest_util.h" |
| 22 #include "net/test/url_request/url_request_hanging_read_job.h" | |
| 22 #include "net/url_request/url_request_job_factory_impl.h" | 23 #include "net/url_request/url_request_job_factory_impl.h" |
| 23 #include "net/url_request/url_request_test_util.h" | 24 #include "net/url_request/url_request_test_util.h" |
| 24 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 26 #include "testing/platform_test.h" | 27 #include "testing/platform_test.h" |
| 27 | 28 |
| 28 using net::test::IsOk; | 29 using net::test::IsOk; |
| 29 | 30 |
| 30 // TODO(eroman): Test that cookies aren't sent. | 31 // TODO(eroman): Test that cookies aren't sent. |
| 31 | 32 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 }; | 107 }; |
| 107 | 108 |
| 108 class CertNetFetcherImplTest : public PlatformTest { | 109 class CertNetFetcherImplTest : public PlatformTest { |
| 109 public: | 110 public: |
| 110 CertNetFetcherImplTest() { | 111 CertNetFetcherImplTest() { |
| 111 test_server_.AddDefaultHandlers(base::FilePath(kDocRoot)); | 112 test_server_.AddDefaultHandlers(base::FilePath(kDocRoot)); |
| 112 StartNetworkThread(); | 113 StartNetworkThread(); |
| 113 } | 114 } |
| 114 | 115 |
| 115 ~CertNetFetcherImplTest() override { | 116 ~CertNetFetcherImplTest() override { |
| 117 if (!network_thread_) | |
| 118 return; | |
| 116 network_thread_->task_runner()->PostTask( | 119 network_thread_->task_runner()->PostTask( |
| 117 FROM_HERE, base::Bind(&CertNetFetcherImplTest::TeardownOnNetworkThread, | 120 FROM_HERE, base::Bind(&CertNetFetcherImplTest::TeardownOnNetworkThread, |
| 118 base::Unretained(this))); | 121 base::Unretained(this))); |
| 119 network_thread_->Stop(); | 122 network_thread_->Stop(); |
| 120 } | 123 } |
| 121 | 124 |
| 122 protected: | 125 protected: |
| 123 std::unique_ptr<CertNetFetcher> CreateFetcher() { | 126 CertNetFetcher* fetcher() const { return fetcher_.get(); } |
| 124 scoped_refptr<TrivialURLRequestContextGetter> context_getter( | 127 |
| 125 new TrivialURLRequestContextGetter(&state_->context, | 128 void CreateFetcherOnNetworkThread(base::WaitableEvent* done) { |
| 126 network_thread_->task_runner())); | 129 fetcher_ = CreateCertNetFetcher(&state_->context); |
| 127 return CreateCertNetFetcher(context_getter.get()); | 130 done->Signal(); |
| 131 } | |
| 132 | |
| 133 void CreateFetcher() { | |
| 134 base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, | |
| 135 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
| 136 network_thread_->task_runner()->PostTask( | |
| 137 FROM_HERE, | |
| 138 base::Bind(&CertNetFetcherImplTest::CreateFetcherOnNetworkThread, | |
| 139 base::Unretained(this), &done)); | |
| 140 done.Wait(); | |
| 141 } | |
| 142 | |
| 143 void ShutDownFetcherOnNetworkThread(base::WaitableEvent* done) { | |
| 144 fetcher_->Shutdown(); | |
| 145 done->Signal(); | |
| 146 } | |
| 147 | |
| 148 void ShutDownFetcher() { | |
| 149 base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, | |
| 150 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
| 151 network_thread_->task_runner()->PostTask( | |
| 152 FROM_HERE, | |
| 153 base::Bind(&CertNetFetcherImplTest::ShutDownFetcherOnNetworkThread, | |
| 154 base::Unretained(this), &done)); | |
| 155 done.Wait(); | |
| 128 } | 156 } |
| 129 | 157 |
| 130 int NumCreatedRequests() { | 158 int NumCreatedRequests() { |
| 131 int count = 0; | 159 int count = 0; |
| 132 base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, | 160 base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, |
| 133 base::WaitableEvent::InitialState::NOT_SIGNALED); | 161 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 134 network_thread_->task_runner()->PostTask( | 162 network_thread_->task_runner()->PostTask( |
| 135 FROM_HERE, base::Bind(&CertNetFetcherImplTest::CountCreatedRequests, | 163 FROM_HERE, base::Bind(&CertNetFetcherImplTest::CountCreatedRequests, |
| 136 base::Unretained(this), &count, &done)); | 164 base::Unretained(this), &count, &done)); |
| 137 done.Wait(); | 165 done.Wait(); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 152 base::Unretained(this), &done)); | 180 base::Unretained(this), &done)); |
| 153 done.Wait(); | 181 done.Wait(); |
| 154 } | 182 } |
| 155 | 183 |
| 156 void InitOnNetworkThread(base::WaitableEvent* done) { | 184 void InitOnNetworkThread(base::WaitableEvent* done) { |
| 157 state_.reset(new NetworkThreadState); | 185 state_.reset(new NetworkThreadState); |
| 158 state_->context.set_network_delegate(&state_->network_delegate); | 186 state_->context.set_network_delegate(&state_->network_delegate); |
| 159 done->Signal(); | 187 done->Signal(); |
| 160 } | 188 } |
| 161 | 189 |
| 162 void TeardownOnNetworkThread() { state_.reset(); } | 190 void ResetStateOnNetworkThread(base::WaitableEvent* done) { |
| 191 state_.reset(); | |
| 192 done->Signal(); | |
| 193 } | |
| 194 | |
| 195 void ResetState() { | |
| 196 base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, | |
| 197 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
| 198 network_thread_->task_runner()->PostTask( | |
| 199 FROM_HERE, | |
| 200 base::Bind(&CertNetFetcherImplTest::ResetStateOnNetworkThread, | |
| 201 base::Unretained(this), &done)); | |
| 202 done.Wait(); | |
| 203 } | |
| 204 | |
| 205 void TeardownOnNetworkThread() { | |
| 206 state_.reset(); | |
| 207 fetcher_ = nullptr; | |
| 208 } | |
| 163 | 209 |
| 164 void CountCreatedRequests(int* count, base::WaitableEvent* done) { | 210 void CountCreatedRequests(int* count, base::WaitableEvent* done) { |
| 165 *count = state_->network_delegate.created_requests(); | 211 *count = state_->network_delegate.created_requests(); |
| 166 done->Signal(); | 212 done->Signal(); |
| 167 } | 213 } |
| 168 | 214 |
| 169 EmbeddedTestServer test_server_; | 215 EmbeddedTestServer test_server_; |
| 170 std::unique_ptr<base::Thread> network_thread_; | 216 std::unique_ptr<base::Thread> network_thread_; |
| 217 scoped_refptr<CertNetFetcher> fetcher_; | |
| 171 | 218 |
| 172 std::unique_ptr<NetworkThreadState> state_; | 219 std::unique_ptr<NetworkThreadState> state_; |
| 173 }; | 220 }; |
| 174 | 221 |
| 175 // Helper to start an AIA fetch using default parameters. | 222 // Helper to start an AIA fetch using default parameters. |
| 176 WARN_UNUSED_RESULT std::unique_ptr<CertNetFetcher::Request> StartRequest( | 223 WARN_UNUSED_RESULT std::unique_ptr<CertNetFetcher::Request> StartRequest( |
| 177 CertNetFetcher* fetcher, | 224 CertNetFetcher* fetcher, |
| 178 const GURL& url) { | 225 const GURL& url) { |
| 179 return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, | 226 return fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, |
| 180 CertNetFetcher::DEFAULT); | 227 CertNetFetcher::DEFAULT); |
| 181 } | 228 } |
| 182 | 229 |
| 183 // Fetch a few unique URLs using GET in parallel. Each URL has a different body | 230 // Fetch a few unique URLs using GET in parallel. Each URL has a different body |
| 184 // and Content-Type. | 231 // and Content-Type. |
| 185 TEST_F(CertNetFetcherImplTest, ParallelFetchNoDuplicates) { | 232 TEST_F(CertNetFetcherImplTest, ParallelFetchNoDuplicates) { |
| 186 ASSERT_TRUE(test_server_.Start()); | 233 ASSERT_TRUE(test_server_.Start()); |
| 187 | 234 CreateFetcher(); |
| 188 auto fetcher = CreateFetcher(); | |
| 189 | 235 |
| 190 // Request a URL with Content-Type "application/pkix-cert" | 236 // Request a URL with Content-Type "application/pkix-cert" |
| 191 GURL url1 = test_server_.GetURL("/cert.crt"); | 237 GURL url1 = test_server_.GetURL("/cert.crt"); |
| 192 std::unique_ptr<CertNetFetcher::Request> request1 = | 238 std::unique_ptr<CertNetFetcher::Request> request1 = |
| 193 StartRequest(fetcher.get(), url1); | 239 StartRequest(fetcher(), url1); |
| 194 | 240 |
| 195 // Request a URL with Content-Type "application/pkix-crl" | 241 // Request a URL with Content-Type "application/pkix-crl" |
| 196 GURL url2 = test_server_.GetURL("/root.crl"); | 242 GURL url2 = test_server_.GetURL("/root.crl"); |
| 197 std::unique_ptr<CertNetFetcher::Request> request2 = | 243 std::unique_ptr<CertNetFetcher::Request> request2 = |
| 198 StartRequest(fetcher.get(), url2); | 244 StartRequest(fetcher(), url2); |
| 199 | 245 |
| 200 // Request a URL with Content-Type "application/pkcs7-mime" | 246 // Request a URL with Content-Type "application/pkcs7-mime" |
| 201 GURL url3 = test_server_.GetURL("/certs.p7c"); | 247 GURL url3 = test_server_.GetURL("/certs.p7c"); |
| 202 std::unique_ptr<CertNetFetcher::Request> request3 = | 248 std::unique_ptr<CertNetFetcher::Request> request3 = |
| 203 StartRequest(fetcher.get(), url3); | 249 StartRequest(fetcher(), url3); |
| 204 | 250 |
| 205 // Wait for all of the requests to complete and verify the fetch results. | 251 // Wait for all of the requests to complete and verify the fetch results. |
| 206 VerifySuccess("-cert.crt-\n", request1.get()); | 252 VerifySuccess("-cert.crt-\n", request1.get()); |
| 207 VerifySuccess("-root.crl-\n", request2.get()); | 253 VerifySuccess("-root.crl-\n", request2.get()); |
| 208 VerifySuccess("-certs.p7c-\n", request3.get()); | 254 VerifySuccess("-certs.p7c-\n", request3.get()); |
| 209 | 255 |
| 210 EXPECT_EQ(3, NumCreatedRequests()); | 256 EXPECT_EQ(3, NumCreatedRequests()); |
| 211 } | 257 } |
| 212 | 258 |
| 213 // Fetch a caIssuers URL which has an unexpected extension and Content-Type. | 259 // Fetch a caIssuers URL which has an unexpected extension and Content-Type. |
| 214 // The extension is .txt and the Content-Type is text/plain. Despite being | 260 // The extension is .txt and the Content-Type is text/plain. Despite being |
| 215 // unusual this succeeds as the extension and Content-Type are not required to | 261 // unusual this succeeds as the extension and Content-Type are not required to |
| 216 // be meaningful. | 262 // be meaningful. |
| 217 TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) { | 263 TEST_F(CertNetFetcherImplTest, ContentTypeDoesntMatter) { |
| 218 ASSERT_TRUE(test_server_.Start()); | 264 ASSERT_TRUE(test_server_.Start()); |
| 219 | 265 CreateFetcher(); |
| 220 auto fetcher = CreateFetcher(); | |
| 221 | 266 |
| 222 GURL url = test_server_.GetURL("/foo.txt"); | 267 GURL url = test_server_.GetURL("/foo.txt"); |
| 223 std::unique_ptr<CertNetFetcher::Request> request = | 268 std::unique_ptr<CertNetFetcher::Request> request = |
| 224 StartRequest(fetcher.get(), url); | 269 StartRequest(fetcher(), url); |
| 225 VerifySuccess("-foo.txt-\n", request.get()); | 270 VerifySuccess("-foo.txt-\n", request.get()); |
| 226 } | 271 } |
| 227 | 272 |
| 228 // Fetch a URLs whose HTTP response code is not 200. These are considered | 273 // Fetch a URLs whose HTTP response code is not 200. These are considered |
| 229 // failures. | 274 // failures. |
| 230 TEST_F(CertNetFetcherImplTest, HttpStatusCode) { | 275 TEST_F(CertNetFetcherImplTest, HttpStatusCode) { |
| 231 ASSERT_TRUE(test_server_.Start()); | 276 ASSERT_TRUE(test_server_.Start()); |
| 232 | 277 CreateFetcher(); |
| 233 auto fetcher = CreateFetcher(); | |
| 234 | 278 |
| 235 // Response was HTTP status 404. | 279 // Response was HTTP status 404. |
| 236 { | 280 { |
| 237 GURL url = test_server_.GetURL("/404.html"); | 281 GURL url = test_server_.GetURL("/404.html"); |
| 238 std::unique_ptr<CertNetFetcher::Request> request = | 282 std::unique_ptr<CertNetFetcher::Request> request = |
| 239 StartRequest(fetcher.get(), url); | 283 StartRequest(fetcher(), url); |
| 240 VerifyFailure(ERR_FAILED, request.get()); | 284 VerifyFailure(ERR_FAILED, request.get()); |
| 241 } | 285 } |
| 242 | 286 |
| 243 // Response was HTTP status 500. | 287 // Response was HTTP status 500. |
| 244 { | 288 { |
| 245 GURL url = test_server_.GetURL("/500.html"); | 289 GURL url = test_server_.GetURL("/500.html"); |
| 246 std::unique_ptr<CertNetFetcher::Request> request = | 290 std::unique_ptr<CertNetFetcher::Request> request = |
| 247 StartRequest(fetcher.get(), url); | 291 StartRequest(fetcher(), url); |
| 248 VerifyFailure(ERR_FAILED, request.get()); | 292 VerifyFailure(ERR_FAILED, request.get()); |
| 249 } | 293 } |
| 250 } | 294 } |
| 251 | 295 |
| 252 // Fetching a URL with a Content-Disposition header should have no effect. | 296 // Fetching a URL with a Content-Disposition header should have no effect. |
| 253 TEST_F(CertNetFetcherImplTest, ContentDisposition) { | 297 TEST_F(CertNetFetcherImplTest, ContentDisposition) { |
| 254 ASSERT_TRUE(test_server_.Start()); | 298 ASSERT_TRUE(test_server_.Start()); |
| 255 | 299 CreateFetcher(); |
| 256 auto fetcher = CreateFetcher(); | |
| 257 | 300 |
| 258 GURL url = test_server_.GetURL("/downloadable.js"); | 301 GURL url = test_server_.GetURL("/downloadable.js"); |
| 259 std::unique_ptr<CertNetFetcher::Request> request = | 302 std::unique_ptr<CertNetFetcher::Request> request = |
| 260 StartRequest(fetcher.get(), url); | 303 StartRequest(fetcher(), url); |
| 261 VerifySuccess("-downloadable.js-\n", request.get()); | 304 VerifySuccess("-downloadable.js-\n", request.get()); |
| 262 } | 305 } |
| 263 | 306 |
| 264 // Verifies that a cachable request will be served from the HTTP cache the | 307 // Verifies that a cachable request will be served from the HTTP cache the |
| 265 // second time it is requested. | 308 // second time it is requested. |
| 266 TEST_F(CertNetFetcherImplTest, Cache) { | 309 TEST_F(CertNetFetcherImplTest, Cache) { |
| 267 ASSERT_TRUE(test_server_.Start()); | 310 ASSERT_TRUE(test_server_.Start()); |
| 268 | 311 |
| 269 auto fetcher = CreateFetcher(); | 312 CreateFetcher(); |
| 270 | 313 |
| 271 // Fetch a URL whose HTTP headers make it cacheable for 1 hour. | 314 // Fetch a URL whose HTTP headers make it cacheable for 1 hour. |
| 272 GURL url(test_server_.GetURL("/cacheable_1hr.crt")); | 315 GURL url(test_server_.GetURL("/cacheable_1hr.crt")); |
| 273 { | 316 { |
| 274 std::unique_ptr<CertNetFetcher::Request> request = | 317 std::unique_ptr<CertNetFetcher::Request> request = |
| 275 StartRequest(fetcher.get(), url); | 318 StartRequest(fetcher(), url); |
| 276 VerifySuccess("-cacheable_1hr.crt-\n", request.get()); | 319 VerifySuccess("-cacheable_1hr.crt-\n", request.get()); |
| 277 } | 320 } |
| 278 | 321 |
| 279 EXPECT_EQ(1, NumCreatedRequests()); | 322 EXPECT_EQ(1, NumCreatedRequests()); |
| 280 | 323 |
| 281 // Kill the HTTP server. | 324 // Kill the HTTP server. |
| 282 ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete()); | 325 ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete()); |
| 283 | 326 |
| 284 // Fetch again -- will fail unless served from cache. | 327 // Fetch again -- will fail unless served from cache. |
| 285 { | 328 { |
| 286 std::unique_ptr<CertNetFetcher::Request> request = | 329 std::unique_ptr<CertNetFetcher::Request> request = |
| 287 StartRequest(fetcher.get(), url); | 330 StartRequest(fetcher(), url); |
| 288 VerifySuccess("-cacheable_1hr.crt-\n", request.get()); | 331 VerifySuccess("-cacheable_1hr.crt-\n", request.get()); |
| 289 } | 332 } |
| 290 | 333 |
| 291 EXPECT_EQ(2, NumCreatedRequests()); | 334 EXPECT_EQ(2, NumCreatedRequests()); |
| 292 } | 335 } |
| 293 | 336 |
| 294 // Verify that the maximum response body constraints are enforced by fetching a | 337 // Verify that the maximum response body constraints are enforced by fetching a |
| 295 // resource that is larger than the limit. | 338 // resource that is larger than the limit. |
| 296 TEST_F(CertNetFetcherImplTest, TooLarge) { | 339 TEST_F(CertNetFetcherImplTest, TooLarge) { |
| 297 ASSERT_TRUE(test_server_.Start()); | 340 ASSERT_TRUE(test_server_.Start()); |
| 298 | 341 |
| 299 auto fetcher = CreateFetcher(); | 342 CreateFetcher(); |
| 300 | 343 |
| 301 // This file has a response body 12 bytes long. So setting the maximum to 11 | 344 // This file has a response body 12 bytes long. So setting the maximum to 11 |
| 302 // bytes will cause it to fail. | 345 // bytes will cause it to fail. |
| 303 GURL url(test_server_.GetURL("/certs.p7c")); | 346 GURL url(test_server_.GetURL("/certs.p7c")); |
| 304 std::unique_ptr<CertNetFetcher::Request> request = | 347 std::unique_ptr<CertNetFetcher::Request> request = |
| 305 fetcher->FetchCaIssuers(url, CertNetFetcher::DEFAULT, 11); | 348 fetcher()->FetchCaIssuers(url, CertNetFetcher::DEFAULT, 11); |
| 306 | 349 |
| 307 VerifyFailure(ERR_FILE_TOO_BIG, request.get()); | 350 VerifyFailure(ERR_FILE_TOO_BIG, request.get()); |
| 308 } | 351 } |
| 309 | 352 |
| 310 // Set the timeout to 10 milliseconds, and try fetching a URL that takes 5 | 353 // Set the timeout to 10 milliseconds, and try fetching a URL that takes 5 |
| 311 // seconds to complete. It should fail due to a timeout. | 354 // seconds to complete. It should fail due to a timeout. |
| 312 TEST_F(CertNetFetcherImplTest, Hang) { | 355 TEST_F(CertNetFetcherImplTest, Hang) { |
| 313 ASSERT_TRUE(test_server_.Start()); | 356 ASSERT_TRUE(test_server_.Start()); |
| 314 | 357 |
| 315 auto fetcher = CreateFetcher(); | 358 CreateFetcher(); |
| 316 | 359 |
| 317 GURL url(test_server_.GetURL("/slow/certs.p7c?5")); | 360 GURL url(test_server_.GetURL("/slow/certs.p7c?5")); |
| 318 std::unique_ptr<CertNetFetcher::Request> request = | 361 std::unique_ptr<CertNetFetcher::Request> request = |
| 319 fetcher->FetchCaIssuers(url, 10, CertNetFetcher::DEFAULT); | 362 fetcher()->FetchCaIssuers(url, 10, CertNetFetcher::DEFAULT); |
| 320 VerifyFailure(ERR_TIMED_OUT, request.get()); | 363 VerifyFailure(ERR_TIMED_OUT, request.get()); |
| 321 } | 364 } |
| 322 | 365 |
| 323 // Verify that if a response is gzip-encoded it gets inflated before being | 366 // Verify that if a response is gzip-encoded it gets inflated before being |
| 324 // returned to the caller. | 367 // returned to the caller. |
| 325 TEST_F(CertNetFetcherImplTest, Gzip) { | 368 TEST_F(CertNetFetcherImplTest, Gzip) { |
| 326 ASSERT_TRUE(test_server_.Start()); | 369 ASSERT_TRUE(test_server_.Start()); |
| 327 | 370 |
| 328 auto fetcher = CreateFetcher(); | 371 CreateFetcher(); |
| 329 | 372 |
| 330 GURL url(test_server_.GetURL("/gzipped_crl")); | 373 GURL url(test_server_.GetURL("/gzipped_crl")); |
| 331 std::unique_ptr<CertNetFetcher::Request> request = | 374 std::unique_ptr<CertNetFetcher::Request> request = |
| 332 StartRequest(fetcher.get(), url); | 375 StartRequest(fetcher(), url); |
| 333 VerifySuccess("-gzipped_crl-\n", request.get()); | 376 VerifySuccess("-gzipped_crl-\n", request.get()); |
| 334 } | 377 } |
| 335 | 378 |
| 336 // Try fetching an unsupported URL scheme (https). | 379 // Try fetching an unsupported URL scheme (https). |
| 337 TEST_F(CertNetFetcherImplTest, HttpsNotAllowed) { | 380 TEST_F(CertNetFetcherImplTest, HttpsNotAllowed) { |
| 338 ASSERT_TRUE(test_server_.Start()); | 381 ASSERT_TRUE(test_server_.Start()); |
| 339 | 382 |
| 340 auto fetcher = CreateFetcher(); | 383 CreateFetcher(); |
| 341 | 384 |
| 342 GURL url("https://foopy/foo.crt"); | 385 GURL url("https://foopy/foo.crt"); |
| 343 std::unique_ptr<CertNetFetcher::Request> request = | 386 std::unique_ptr<CertNetFetcher::Request> request = |
| 344 StartRequest(fetcher.get(), url); | 387 StartRequest(fetcher(), url); |
| 345 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get()); | 388 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get()); |
| 346 | 389 |
| 347 // No request was created because the URL scheme was unsupported. | 390 // No request was created because the URL scheme was unsupported. |
| 348 EXPECT_EQ(0, NumCreatedRequests()); | 391 EXPECT_EQ(0, NumCreatedRequests()); |
| 349 } | 392 } |
| 350 | 393 |
| 351 // Try fetching a URL which redirects to https. | 394 // Try fetching a URL which redirects to https. |
| 352 TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) { | 395 TEST_F(CertNetFetcherImplTest, RedirectToHttpsNotAllowed) { |
| 353 ASSERT_TRUE(test_server_.Start()); | 396 ASSERT_TRUE(test_server_.Start()); |
| 354 | 397 |
| 355 auto fetcher = CreateFetcher(); | 398 CreateFetcher(); |
| 356 | 399 |
| 357 GURL url(test_server_.GetURL("/redirect_https")); | 400 GURL url(test_server_.GetURL("/redirect_https")); |
| 358 | 401 |
| 359 std::unique_ptr<CertNetFetcher::Request> request = | 402 std::unique_ptr<CertNetFetcher::Request> request = |
| 360 StartRequest(fetcher.get(), url); | 403 StartRequest(fetcher(), url); |
| 361 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get()); | 404 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request.get()); |
| 362 | 405 |
| 363 EXPECT_EQ(1, NumCreatedRequests()); | 406 EXPECT_EQ(1, NumCreatedRequests()); |
| 364 } | 407 } |
| 365 | 408 |
| 366 // Try fetching an unsupported URL scheme (https) and then immediately | 409 // Try fetching an unsupported URL scheme (https) and then immediately |
| 367 // cancelling. This is a bit special because this codepath needs to post a task. | 410 // cancelling. This is a bit special because this codepath needs to post a task. |
| 368 TEST_F(CertNetFetcherImplTest, CancelHttpsNotAllowed) { | 411 TEST_F(CertNetFetcherImplTest, CancelHttpsNotAllowed) { |
| 369 ASSERT_TRUE(test_server_.Start()); | 412 ASSERT_TRUE(test_server_.Start()); |
| 370 | 413 |
| 371 auto fetcher = CreateFetcher(); | 414 CreateFetcher(); |
| 372 | 415 |
| 373 GURL url("https://foopy/foo.crt"); | 416 GURL url("https://foopy/foo.crt"); |
| 374 std::unique_ptr<CertNetFetcher::Request> request = | 417 std::unique_ptr<CertNetFetcher::Request> request = |
| 375 StartRequest(fetcher.get(), url); | 418 StartRequest(fetcher(), url); |
| 376 | 419 |
| 377 // Cancel the request (May or may not have started yet, as the request is | 420 // Cancel the request (May or may not have started yet, as the request is |
| 378 // running on another thread). | 421 // running on another thread). |
| 379 request.reset(); | 422 request.reset(); |
| 380 } | 423 } |
| 381 | 424 |
| 382 // Start a few requests, and cancel one of them before running the message loop | 425 // Start a few requests, and cancel one of them before running the message loop |
| 383 // again. | 426 // again. |
| 384 TEST_F(CertNetFetcherImplTest, CancelBeforeRunningMessageLoop) { | 427 TEST_F(CertNetFetcherImplTest, CancelBeforeRunningMessageLoop) { |
| 385 ASSERT_TRUE(test_server_.Start()); | 428 ASSERT_TRUE(test_server_.Start()); |
| 386 | 429 |
| 387 auto fetcher = CreateFetcher(); | 430 CreateFetcher(); |
| 388 | 431 |
| 389 GURL url1 = test_server_.GetURL("/cert.crt"); | 432 GURL url1 = test_server_.GetURL("/cert.crt"); |
| 390 std::unique_ptr<CertNetFetcher::Request> request1 = | 433 std::unique_ptr<CertNetFetcher::Request> request1 = |
| 391 StartRequest(fetcher.get(), url1); | 434 StartRequest(fetcher(), url1); |
| 392 | 435 |
| 393 GURL url2 = test_server_.GetURL("/root.crl"); | 436 GURL url2 = test_server_.GetURL("/root.crl"); |
| 394 std::unique_ptr<CertNetFetcher::Request> request2 = | 437 std::unique_ptr<CertNetFetcher::Request> request2 = |
| 395 StartRequest(fetcher.get(), url2); | 438 StartRequest(fetcher(), url2); |
| 396 | 439 |
| 397 GURL url3 = test_server_.GetURL("/certs.p7c"); | 440 GURL url3 = test_server_.GetURL("/certs.p7c"); |
| 398 | 441 |
| 399 std::unique_ptr<CertNetFetcher::Request> request3 = | 442 std::unique_ptr<CertNetFetcher::Request> request3 = |
| 400 StartRequest(fetcher.get(), url3); | 443 StartRequest(fetcher(), url3); |
| 401 | 444 |
| 402 // Cancel the second request. | 445 // Cancel the second request. |
| 403 request2.reset(); | 446 request2.reset(); |
| 404 | 447 |
| 405 // Wait for the non-cancelled requests to complete, and verify the fetch | 448 // Wait for the non-cancelled requests to complete, and verify the fetch |
| 406 // results. | 449 // results. |
| 407 VerifySuccess("-cert.crt-\n", request1.get()); | 450 VerifySuccess("-cert.crt-\n", request1.get()); |
| 408 VerifySuccess("-certs.p7c-\n", request3.get()); | 451 VerifySuccess("-certs.p7c-\n", request3.get()); |
| 409 } | 452 } |
| 410 | 453 |
| 411 // Start several requests, and cancel one of them after the first has completed. | 454 // Start several requests, and cancel one of them after the first has completed. |
| 412 // NOTE: The python test server is single threaded and can only service one | 455 // NOTE: The python test server is single threaded and can only service one |
| 413 // request at a time. After a socket is opened by the server it waits for it to | 456 // request at a time. After a socket is opened by the server it waits for it to |
| 414 // be completed, and any subsequent request will hang until the first socket is | 457 // be completed, and any subsequent request will hang until the first socket is |
| 415 // closed. | 458 // closed. |
| 416 // Cancelling the first request can therefore be problematic, since if | 459 // Cancelling the first request can therefore be problematic, since if |
| 417 // cancellation is done after the socket is opened but before reading/writing, | 460 // cancellation is done after the socket is opened but before reading/writing, |
| 418 // then the socket is re-cycled and things will be stalled until the cleanup | 461 // then the socket is re-cycled and things will be stalled until the cleanup |
| 419 // timer (10 seconds) closes it. | 462 // timer (10 seconds) closes it. |
| 420 // To work around this, the last request is cancelled, and hope that the | 463 // To work around this, the last request is cancelled, and hope that the |
| 421 // requests are given opened sockets in a FIFO order. | 464 // requests are given opened sockets in a FIFO order. |
| 422 // TODO(eroman): Make this more robust. | 465 // TODO(eroman): Make this more robust. |
| 423 // TODO(eroman): Rename this test. | 466 // TODO(eroman): Rename this test. |
| 424 TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) { | 467 TEST_F(CertNetFetcherImplTest, CancelAfterRunningMessageLoop) { |
| 425 ASSERT_TRUE(test_server_.Start()); | 468 ASSERT_TRUE(test_server_.Start()); |
| 426 | 469 |
| 427 auto fetcher = CreateFetcher(); | 470 CreateFetcher(); |
| 428 | 471 |
| 429 GURL url1 = test_server_.GetURL("/cert.crt"); | 472 GURL url1 = test_server_.GetURL("/cert.crt"); |
| 430 | 473 |
| 431 std::unique_ptr<CertNetFetcher::Request> request1 = | 474 std::unique_ptr<CertNetFetcher::Request> request1 = |
| 432 StartRequest(fetcher.get(), url1); | 475 StartRequest(fetcher(), url1); |
| 433 | 476 |
| 434 GURL url2 = test_server_.GetURL("/certs.p7c"); | 477 GURL url2 = test_server_.GetURL("/certs.p7c"); |
| 435 std::unique_ptr<CertNetFetcher::Request> request2 = | 478 std::unique_ptr<CertNetFetcher::Request> request2 = |
| 436 StartRequest(fetcher.get(), url2); | 479 StartRequest(fetcher(), url2); |
| 437 | 480 |
| 438 GURL url3("ftp://www.not.supported.com/foo"); | 481 GURL url3("ftp://www.not.supported.com/foo"); |
| 439 std::unique_ptr<CertNetFetcher::Request> request3 = | 482 std::unique_ptr<CertNetFetcher::Request> request3 = |
| 440 StartRequest(fetcher.get(), url3); | 483 StartRequest(fetcher(), url3); |
| 441 | 484 |
| 442 // Wait for the ftp request to complete (it should complete right away since | 485 // Wait for the ftp request to complete (it should complete right away since |
| 443 // it doesn't even try to connect to the server). | 486 // it doesn't even try to connect to the server). |
| 444 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request3.get()); | 487 VerifyFailure(ERR_DISALLOWED_URL_SCHEME, request3.get()); |
| 445 | 488 |
| 446 // Cancel the second outstanding request. | 489 // Cancel the second outstanding request. |
| 447 request2.reset(); | 490 request2.reset(); |
| 448 | 491 |
| 449 // Wait for the first request to complete and verify the fetch result. | 492 // Wait for the first request to complete and verify the fetch result. |
| 450 VerifySuccess("-cert.crt-\n", request1.get()); | 493 VerifySuccess("-cert.crt-\n", request1.get()); |
| 451 } | 494 } |
| 452 | 495 |
| 453 // Fetch the same URLs in parallel and verify that only 1 request is made per | 496 // Fetch the same URLs in parallel and verify that only 1 request is made per |
| 454 // URL. | 497 // URL. |
| 455 TEST_F(CertNetFetcherImplTest, ParallelFetchDuplicates) { | 498 TEST_F(CertNetFetcherImplTest, ParallelFetchDuplicates) { |
| 456 ASSERT_TRUE(test_server_.Start()); | 499 ASSERT_TRUE(test_server_.Start()); |
| 457 | 500 |
| 458 auto fetcher = CreateFetcher(); | 501 CreateFetcher(); |
| 459 | 502 |
| 460 GURL url1 = test_server_.GetURL("/cert.crt"); | 503 GURL url1 = test_server_.GetURL("/cert.crt"); |
| 461 GURL url2 = test_server_.GetURL("/root.crl"); | 504 GURL url2 = test_server_.GetURL("/root.crl"); |
| 462 | 505 |
| 463 // Issue 3 requests for url1, and 3 requests for url2 | 506 // Issue 3 requests for url1, and 3 requests for url2 |
| 464 std::unique_ptr<CertNetFetcher::Request> request1 = | 507 std::unique_ptr<CertNetFetcher::Request> request1 = |
| 465 StartRequest(fetcher.get(), url1); | 508 StartRequest(fetcher(), url1); |
| 466 | 509 |
| 467 std::unique_ptr<CertNetFetcher::Request> request2 = | 510 std::unique_ptr<CertNetFetcher::Request> request2 = |
| 468 StartRequest(fetcher.get(), url2); | 511 StartRequest(fetcher(), url2); |
| 469 | 512 |
| 470 std::unique_ptr<CertNetFetcher::Request> request3 = | 513 std::unique_ptr<CertNetFetcher::Request> request3 = |
| 471 StartRequest(fetcher.get(), url1); | 514 StartRequest(fetcher(), url1); |
| 472 | 515 |
| 473 std::unique_ptr<CertNetFetcher::Request> request4 = | 516 std::unique_ptr<CertNetFetcher::Request> request4 = |
| 474 StartRequest(fetcher.get(), url2); | 517 StartRequest(fetcher(), url2); |
| 475 | 518 |
| 476 std::unique_ptr<CertNetFetcher::Request> request5 = | 519 std::unique_ptr<CertNetFetcher::Request> request5 = |
| 477 StartRequest(fetcher.get(), url2); | 520 StartRequest(fetcher(), url2); |
| 478 | 521 |
| 479 std::unique_ptr<CertNetFetcher::Request> request6 = | 522 std::unique_ptr<CertNetFetcher::Request> request6 = |
| 480 StartRequest(fetcher.get(), url1); | 523 StartRequest(fetcher(), url1); |
| 481 | 524 |
| 482 // Cancel all but one of the requests for url1. | 525 // Cancel all but one of the requests for url1. |
| 483 request1.reset(); | 526 request1.reset(); |
| 484 request3.reset(); | 527 request3.reset(); |
| 485 | 528 |
| 486 // Wait for the remaining requests to finish and verify the fetch results. | 529 // Wait for the remaining requests to finish and verify the fetch results. |
| 487 VerifySuccess("-root.crl-\n", request2.get()); | 530 VerifySuccess("-root.crl-\n", request2.get()); |
| 488 VerifySuccess("-root.crl-\n", request4.get()); | 531 VerifySuccess("-root.crl-\n", request4.get()); |
| 489 VerifySuccess("-root.crl-\n", request5.get()); | 532 VerifySuccess("-root.crl-\n", request5.get()); |
| 490 VerifySuccess("-cert.crt-\n", request6.get()); | 533 VerifySuccess("-cert.crt-\n", request6.get()); |
| 491 | 534 |
| 492 // Verify that only 2 URLRequests were started even though 6 requests were | 535 // Verify that only 2 URLRequests were started even though 6 requests were |
| 493 // issued. | 536 // issued. |
| 494 EXPECT_EQ(2, NumCreatedRequests()); | 537 EXPECT_EQ(2, NumCreatedRequests()); |
| 495 } | 538 } |
| 496 | 539 |
| 497 // Cancel a request and then start another one for the same URL. | 540 // Cancel a request and then start another one for the same URL. |
| 498 TEST_F(CertNetFetcherImplTest, CancelThenStart) { | 541 TEST_F(CertNetFetcherImplTest, CancelThenStart) { |
| 499 ASSERT_TRUE(test_server_.Start()); | 542 ASSERT_TRUE(test_server_.Start()); |
| 500 | 543 |
| 501 auto fetcher = CreateFetcher(); | 544 CreateFetcher(); |
| 502 | 545 |
| 503 GURL url = test_server_.GetURL("/cert.crt"); | 546 GURL url = test_server_.GetURL("/cert.crt"); |
| 504 | 547 |
| 505 std::unique_ptr<CertNetFetcher::Request> request1 = | 548 std::unique_ptr<CertNetFetcher::Request> request1 = |
| 506 StartRequest(fetcher.get(), url); | 549 StartRequest(fetcher(), url); |
| 507 request1.reset(); | 550 request1.reset(); |
| 508 | 551 |
| 509 std::unique_ptr<CertNetFetcher::Request> request2 = | 552 std::unique_ptr<CertNetFetcher::Request> request2 = |
| 510 StartRequest(fetcher.get(), url); | 553 StartRequest(fetcher(), url); |
| 511 | 554 |
| 512 std::unique_ptr<CertNetFetcher::Request> request3 = | 555 std::unique_ptr<CertNetFetcher::Request> request3 = |
| 513 StartRequest(fetcher.get(), url); | 556 StartRequest(fetcher(), url); |
| 514 request3.reset(); | 557 request3.reset(); |
| 515 | 558 |
| 516 // All but |request2| were canceled. | 559 // All but |request2| were canceled. |
| 517 VerifySuccess("-cert.crt-\n", request2.get()); | 560 VerifySuccess("-cert.crt-\n", request2.get()); |
| 518 } | 561 } |
| 519 | 562 |
| 520 // Start duplicate requests and then cancel all of them. | 563 // Start duplicate requests and then cancel all of them. |
| 521 TEST_F(CertNetFetcherImplTest, CancelAll) { | 564 TEST_F(CertNetFetcherImplTest, CancelAll) { |
| 522 ASSERT_TRUE(test_server_.Start()); | 565 ASSERT_TRUE(test_server_.Start()); |
| 523 | 566 |
| 524 auto fetcher = CreateFetcher(); | 567 CreateFetcher(); |
| 525 std::unique_ptr<CertNetFetcher::Request> request[3]; | 568 std::unique_ptr<CertNetFetcher::Request> request[3]; |
| 526 | 569 |
| 527 GURL url = test_server_.GetURL("/cert.crt"); | 570 GURL url = test_server_.GetURL("/cert.crt"); |
| 528 | 571 |
| 529 for (size_t i = 0; i < arraysize(request); ++i) { | 572 for (size_t i = 0; i < arraysize(request); ++i) { |
| 530 request[i] = StartRequest(fetcher.get(), url); | 573 request[i] = StartRequest(fetcher(), url); |
| 531 } | 574 } |
| 532 | 575 |
| 533 // Cancel all the requests. | 576 // Cancel all the requests. |
| 534 for (size_t i = 0; i < arraysize(request); ++i) | 577 for (size_t i = 0; i < arraysize(request); ++i) |
| 535 request[i].reset(); | 578 request[i].reset(); |
| 536 | 579 |
| 537 EXPECT_EQ(1, NumCreatedRequests()); | 580 EXPECT_EQ(1, NumCreatedRequests()); |
| 538 } | 581 } |
| 539 | 582 |
| 583 // Tests that Requests are signalled for completion even if they are | |
| 584 // created after the CertNetFetcher has been shutdown. | |
| 585 TEST_F(CertNetFetcherImplTest, RequestsAfterShutdown) { | |
| 586 ASSERT_TRUE(test_server_.Start()); | |
| 587 CreateFetcher(); | |
| 588 ShutDownFetcher(); | |
| 589 | |
| 590 GURL url = test_server_.GetURL("/cert.crt"); | |
| 591 std::unique_ptr<CertNetFetcher::Request> request = | |
| 592 StartRequest(fetcher(), url); | |
| 593 VerifyFailure(ERR_ABORTED, request.get()); | |
| 594 EXPECT_EQ(0, NumCreatedRequests()); | |
| 595 } | |
| 596 | |
| 597 // Tests that outstanding Requests are cancelled when Shutdown is called. | |
| 598 TEST_F(CertNetFetcherImplTest, ShutdownCancelsRequests) { | |
| 599 URLRequestHangingReadJob::AddUrlHandler(); | |
|
eroman
2017/01/11 01:57:00
Is there any other code that uses this?
Won't thi
estark
2017/01/12 01:06:31
Changed to remove handlers in teardown.
| |
| 600 CreateFetcher(); | |
| 601 | |
| 602 GURL url = URLRequestHangingReadJob::GetMockHttpUrl(); | |
| 603 std::unique_ptr<CertNetFetcher::Request> request = | |
| 604 StartRequest(fetcher(), url); | |
| 605 | |
| 606 ShutDownFetcher(); | |
| 607 VerifyFailure(ERR_ABORTED, request.get()); | |
| 608 } | |
| 609 | |
| 610 // Tests that Requests are signalled even if they are created after the network | |
| 611 // thread is gone. | |
| 612 TEST_F(CertNetFetcherImplTest, RequestsAfterNetworkThreadDead) { | |
| 613 ASSERT_TRUE(test_server_.Start()); | |
| 614 CreateFetcher(); | |
| 615 ResetState(); | |
| 616 network_thread_.reset(); | |
| 617 | |
| 618 GURL url = test_server_.GetURL("/cert.crt"); | |
| 619 std::unique_ptr<CertNetFetcher::Request> request = | |
| 620 StartRequest(fetcher(), url); | |
| 621 VerifyFailure(ERR_ABORTED, request.get()); | |
| 622 } | |
| 623 | |
| 540 } // namespace | 624 } // namespace |
| 541 | 625 |
| 542 } // namespace net | 626 } // namespace net |
| OLD | NEW |