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