| 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 |