Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "content/browser/loader/resource_loader.h" | 5 #include "content/browser/loader/resource_loader.h" |
| 6 | 6 |
| 7 #include "base/files/file.h" | 7 #include "base/files/file.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/macros.h" | |
| 9 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
| 10 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 11 #include "content/browser/browser_thread_impl.h" | 12 #include "content/browser/browser_thread_impl.h" |
| 12 #include "content/browser/loader/redirect_to_file_resource_handler.h" | 13 #include "content/browser/loader/redirect_to_file_resource_handler.h" |
| 13 #include "content/browser/loader/resource_loader_delegate.h" | 14 #include "content/browser/loader/resource_loader_delegate.h" |
| 15 #include "content/public/browser/client_certificate_delegate.h" | |
| 14 #include "content/public/browser/resource_request_info.h" | 16 #include "content/public/browser/resource_request_info.h" |
| 15 #include "content/public/common/resource_response.h" | 17 #include "content/public/common/resource_response.h" |
| 16 #include "content/public/test/mock_resource_context.h" | 18 #include "content/public/test/mock_resource_context.h" |
| 19 #include "content/public/test/test_browser_context.h" | |
| 17 #include "content/public/test/test_browser_thread_bundle.h" | 20 #include "content/public/test/test_browser_thread_bundle.h" |
| 21 #include "content/public/test/test_renderer_host.h" | |
| 18 #include "content/test/test_content_browser_client.h" | 22 #include "content/test/test_content_browser_client.h" |
| 23 #include "content/test/test_web_contents.h" | |
| 19 #include "ipc/ipc_message.h" | 24 #include "ipc/ipc_message.h" |
| 20 #include "net/base/io_buffer.h" | 25 #include "net/base/io_buffer.h" |
| 21 #include "net/base/mock_file_stream.h" | 26 #include "net/base/mock_file_stream.h" |
| 27 #include "net/base/net_errors.h" | |
| 22 #include "net/base/request_priority.h" | 28 #include "net/base/request_priority.h" |
| 23 #include "net/cert/x509_certificate.h" | 29 #include "net/cert/x509_certificate.h" |
| 24 #include "net/ssl/client_cert_store.h" | 30 #include "net/ssl/client_cert_store.h" |
| 25 #include "net/ssl/ssl_cert_request_info.h" | 31 #include "net/ssl/ssl_cert_request_info.h" |
| 26 #include "net/url_request/url_request.h" | 32 #include "net/url_request/url_request.h" |
| 33 #include "net/url_request/url_request_job_factory.h" | |
| 27 #include "net/url_request/url_request_job_factory_impl.h" | 34 #include "net/url_request/url_request_job_factory_impl.h" |
| 28 #include "net/url_request/url_request_test_job.h" | 35 #include "net/url_request/url_request_test_job.h" |
| 29 #include "net/url_request/url_request_test_util.h" | 36 #include "net/url_request/url_request_test_util.h" |
| 30 #include "storage/browser/blob/shareable_file_reference.h" | 37 #include "storage/browser/blob/shareable_file_reference.h" |
| 31 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
| 32 | 39 |
| 33 using storage::ShareableFileReference; | 40 using storage::ShareableFileReference; |
| 34 | 41 |
| 35 namespace content { | 42 namespace content { |
| 36 namespace { | 43 namespace { |
| 37 | 44 |
| 38 // Stub client certificate store that returns a preset list of certificates for | 45 // Stub client certificate store that returns a preset list of certificates for |
| 39 // each request and records the arguments of the most recent request for later | 46 // each request and records the arguments of the most recent request for later |
| 40 // inspection. | 47 // inspection. |
| 41 class ClientCertStoreStub : public net::ClientCertStore { | 48 class ClientCertStoreStub : public net::ClientCertStore { |
| 42 public: | 49 public: |
| 43 // Creates a new ClientCertStoreStub that returns |response| on query. It | 50 // Creates a new ClientCertStoreStub that returns |response| on query. It |
| 44 // saves the number of requests and most recently certificate authorities list | 51 // saves the number of requests and most recently certificate authorities list |
| 45 // in |requested_authorities| and |request_count|, respectively. The caller is | 52 // in |requested_authorities| and |request_count|, respectively. The caller is |
| 46 // responsible for ensuring those pointers outlive the ClientCertStoreStub. | 53 // responsible for ensuring those pointers outlive the ClientCertStoreStub. |
| 47 // | 54 // |
| 48 // TODO(ppi): Make the stub independent from the internal representation of | 55 // TODO(ppi): Make the stub independent from the internal representation of |
| 49 // SSLCertRequestInfo. For now it seems that we can neither save the | 56 // SSLCertRequestInfo. For now it seems that we can neither save the |
| 50 // scoped_refptr<> (since it is never passed to us) nor copy the entire | 57 // scoped_refptr<> (since it is never passed to us) nor copy the entire |
| 51 // CertificateRequestInfo (since there is no copy constructor). | 58 // CertificateRequestInfo (since there is no copy constructor). |
| 52 ClientCertStoreStub(const net::CertificateList& response, | 59 ClientCertStoreStub(const net::CertificateList& response, |
| 53 int* request_count, | 60 int* request_count, |
| 54 std::vector<std::string>* requested_authorities) | 61 std::vector<std::string>* requested_authorities) |
| 55 : response_(response), | 62 : response_(response), |
| 56 async_(false), | |
| 57 requested_authorities_(requested_authorities), | 63 requested_authorities_(requested_authorities), |
| 58 request_count_(request_count) { | 64 request_count_(request_count) { |
| 59 requested_authorities_->clear(); | 65 requested_authorities_->clear(); |
| 60 *request_count_ = 0; | 66 *request_count_ = 0; |
| 61 } | 67 } |
| 62 | 68 |
| 63 ~ClientCertStoreStub() override {} | 69 ~ClientCertStoreStub() override {} |
| 64 | 70 |
| 65 // Configures whether the certificates are returned asynchronously or not. | |
| 66 void set_async(bool async) { async_ = async; } | |
| 67 | |
| 68 // net::ClientCertStore: | 71 // net::ClientCertStore: |
| 69 void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, | 72 void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, |
| 70 net::CertificateList* selected_certs, | 73 net::CertificateList* selected_certs, |
| 71 const base::Closure& callback) override { | 74 const base::Closure& callback) override { |
| 72 *requested_authorities_ = cert_request_info.cert_authorities; | 75 *requested_authorities_ = cert_request_info.cert_authorities; |
| 73 ++(*request_count_); | 76 ++(*request_count_); |
| 74 | 77 |
| 75 *selected_certs = response_; | 78 *selected_certs = response_; |
| 76 if (async_) { | 79 callback.Run(); |
| 77 base::MessageLoop::current()->PostTask(FROM_HERE, callback); | |
| 78 } else { | |
| 79 callback.Run(); | |
| 80 } | |
| 81 } | 80 } |
| 82 | 81 |
| 83 private: | 82 private: |
| 84 const net::CertificateList response_; | 83 const net::CertificateList response_; |
| 85 bool async_; | |
| 86 std::vector<std::string>* requested_authorities_; | 84 std::vector<std::string>* requested_authorities_; |
| 87 int* request_count_; | 85 int* request_count_; |
| 88 }; | 86 }; |
| 89 | 87 |
| 88 // Client certificate store which destroys its resource loader before the | |
| 89 // asynchronous GetClientCerts callback is called. | |
| 90 class CancelingClientCertStore : public net::ClientCertStore { | |
|
mmenke
2015/02/13 19:35:53
"CancelingClientCertStore" seems a bit confusing..
davidben
2015/02/13 22:04:11
Done.
| |
| 91 public: | |
| 92 // Creates a client certificate store which, when looked up, posts a task to | |
| 93 // reset |loader| and then call the callback. The caller is responsible for | |
| 94 // ensuring the pointers remain valid until the process is complete. | |
| 95 explicit CancelingClientCertStore(scoped_ptr<ResourceLoader>* loader) | |
| 96 : loader_(loader) {} | |
| 97 | |
| 98 // net::ClientCertStore: | |
| 99 void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, | |
| 100 net::CertificateList* selected_certs, | |
| 101 const base::Closure& callback) override { | |
| 102 // Don't destroy |loader_| while it's on the stack. | |
| 103 base::MessageLoop::current()->PostTask( | |
| 104 FROM_HERE, base::Bind(&CancelingClientCertStore::DoCallback, | |
| 105 base::Unretained(loader_), callback)); | |
| 106 } | |
| 107 | |
| 108 private: | |
| 109 static void DoCallback(scoped_ptr<ResourceLoader>* loader, | |
| 110 const base::Closure& callback) { | |
| 111 loader->reset(); | |
| 112 callback.Run(); | |
| 113 } | |
| 114 | |
| 115 scoped_ptr<ResourceLoader>* loader_; | |
| 116 }; | |
| 117 | |
| 118 // A mock URLRequestJob which simulates an SSL client auth request. | |
| 119 class MockClientCertURLRequestJob : public net::URLRequestTestJob { | |
| 120 public: | |
| 121 MockClientCertURLRequestJob(net::URLRequest* request, | |
| 122 net::NetworkDelegate* network_delegate) | |
| 123 : net::URLRequestTestJob(request, network_delegate) {} | |
| 124 | |
| 125 static std::vector<std::string> test_authorities() { | |
| 126 return std::vector<std::string>(1, "dummy"); | |
| 127 } | |
| 128 | |
|
mmenke
2015/02/13 19:35:53
// net::URLRequestTestJob:
davidben
2015/02/13 22:04:11
Done.
| |
| 129 void Start() override { | |
| 130 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | |
| 131 new net::SSLCertRequestInfo); | |
| 132 cert_request_info->cert_authorities = test_authorities(); | |
| 133 base::MessageLoop::current()->PostTask( | |
| 134 FROM_HERE, | |
| 135 base::Bind(&MockClientCertURLRequestJob::NotifyCertificateRequested, | |
| 136 this, cert_request_info)); | |
| 137 } | |
| 138 | |
| 139 void ContinueWithCertificate(net::X509Certificate* cert) override { | |
| 140 net::URLRequestTestJob::Start(); | |
| 141 } | |
| 142 | |
| 143 private: | |
| 144 ~MockClientCertURLRequestJob() override {} | |
| 145 | |
| 146 DISALLOW_COPY_AND_ASSIGN(MockClientCertURLRequestJob); | |
| 147 }; | |
| 148 | |
| 149 class MockClientCertJobProtocolHandler | |
| 150 : public net::URLRequestJobFactory::ProtocolHandler { | |
| 151 public: | |
| 152 // URLRequestJobFactory::ProtocolHandler implementation: | |
| 153 net::URLRequestJob* MaybeCreateJob( | |
| 154 net::URLRequest* request, | |
| 155 net::NetworkDelegate* network_delegate) const override { | |
| 156 return new MockClientCertURLRequestJob(request, network_delegate); | |
| 157 } | |
| 158 }; | |
| 159 | |
| 90 // Arbitrary read buffer size. | 160 // Arbitrary read buffer size. |
| 91 const int kReadBufSize = 1024; | 161 const int kReadBufSize = 1024; |
| 92 | 162 |
| 93 // Dummy implementation of ResourceHandler, instance of which is needed to | 163 // Dummy implementation of ResourceHandler, instance of which is needed to |
| 94 // initialize ResourceLoader. | 164 // initialize ResourceLoader. |
| 95 class ResourceHandlerStub : public ResourceHandler { | 165 class ResourceHandlerStub : public ResourceHandler { |
| 96 public: | 166 public: |
| 97 explicit ResourceHandlerStub(net::URLRequest* request) | 167 explicit ResourceHandlerStub(net::URLRequest* request) |
| 98 : ResourceHandler(request), | 168 : ResourceHandler(request), |
| 99 read_buffer_(new net::IOBuffer(kReadBufSize)), | 169 read_buffer_(new net::IOBuffer(kReadBufSize)), |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 int total_bytes_downloaded_; | 302 int total_bytes_downloaded_; |
| 233 }; | 303 }; |
| 234 | 304 |
| 235 // Test browser client that captures calls to SelectClientCertificates and | 305 // Test browser client that captures calls to SelectClientCertificates and |
| 236 // records the arguments of the most recent call for later inspection. | 306 // records the arguments of the most recent call for later inspection. |
| 237 class SelectCertificateBrowserClient : public TestContentBrowserClient { | 307 class SelectCertificateBrowserClient : public TestContentBrowserClient { |
| 238 public: | 308 public: |
| 239 SelectCertificateBrowserClient() : call_count_(0) {} | 309 SelectCertificateBrowserClient() : call_count_(0) {} |
| 240 | 310 |
| 241 void SelectClientCertificate( | 311 void SelectClientCertificate( |
| 242 int render_process_id, | 312 WebContents* web_contents, |
| 243 int render_view_id, | |
| 244 net::SSLCertRequestInfo* cert_request_info, | 313 net::SSLCertRequestInfo* cert_request_info, |
| 245 const base::Callback<void(net::X509Certificate*)>& callback) override { | 314 scoped_ptr<ClientCertificateDelegate> delegate) override { |
| 246 ++call_count_; | 315 ++call_count_; |
| 247 passed_certs_ = cert_request_info->client_certs; | 316 passed_certs_ = cert_request_info->client_certs; |
| 317 delegate_ = delegate.Pass(); | |
| 248 } | 318 } |
| 249 | 319 |
| 250 int call_count() { | 320 int call_count() { return call_count_; } |
| 251 return call_count_; | 321 net::CertificateList passed_certs() { return passed_certs_; } |
| 252 } | 322 ClientCertificateDelegate* delegate() { return delegate_.get(); } |
| 253 | |
| 254 net::CertificateList passed_certs() { | |
| 255 return passed_certs_; | |
| 256 } | |
| 257 | 323 |
| 258 private: | 324 private: |
| 259 net::CertificateList passed_certs_; | 325 net::CertificateList passed_certs_; |
| 260 int call_count_; | 326 int call_count_; |
| 327 scoped_ptr<ClientCertificateDelegate> delegate_; | |
| 261 }; | 328 }; |
| 262 | 329 |
| 263 class ResourceContextStub : public MockResourceContext { | 330 class ResourceContextStub : public MockResourceContext { |
| 264 public: | 331 public: |
| 265 explicit ResourceContextStub(net::URLRequestContext* test_request_context) | 332 explicit ResourceContextStub(net::URLRequestContext* test_request_context) |
| 266 : MockResourceContext(test_request_context) {} | 333 : MockResourceContext(test_request_context) {} |
| 267 | 334 |
| 268 scoped_ptr<net::ClientCertStore> CreateClientCertStore() override { | 335 scoped_ptr<net::ClientCertStore> CreateClientCertStore() override { |
| 269 return dummy_cert_store_.Pass(); | 336 return dummy_cert_store_.Pass(); |
| 270 } | 337 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 290 } // namespace | 357 } // namespace |
| 291 | 358 |
| 292 class ResourceLoaderTest : public testing::Test, | 359 class ResourceLoaderTest : public testing::Test, |
| 293 public ResourceLoaderDelegate { | 360 public ResourceLoaderDelegate { |
| 294 protected: | 361 protected: |
| 295 ResourceLoaderTest() | 362 ResourceLoaderTest() |
| 296 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | 363 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
| 297 resource_context_(&test_url_request_context_), | 364 resource_context_(&test_url_request_context_), |
| 298 raw_ptr_resource_handler_(NULL), | 365 raw_ptr_resource_handler_(NULL), |
| 299 raw_ptr_to_request_(NULL) { | 366 raw_ptr_to_request_(NULL) { |
| 300 job_factory_.SetProtocolHandler( | |
| 301 "test", net::URLRequestTestJob::CreateProtocolHandler()); | |
| 302 test_url_request_context_.set_job_factory(&job_factory_); | 367 test_url_request_context_.set_job_factory(&job_factory_); |
| 303 } | 368 } |
| 304 | 369 |
| 305 GURL test_url() const { | 370 GURL test_url() const { return net::URLRequestTestJob::test_url_1(); } |
| 306 return net::URLRequestTestJob::test_url_1(); | |
| 307 } | |
| 308 | 371 |
| 309 std::string test_data() const { | 372 std::string test_data() const { |
| 310 return net::URLRequestTestJob::test_data_1(); | 373 return net::URLRequestTestJob::test_data_1(); |
| 311 } | 374 } |
| 312 | 375 |
| 376 virtual net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() { | |
| 377 return net::URLRequestTestJob::CreateProtocolHandler(); | |
| 378 } | |
| 379 | |
| 313 virtual scoped_ptr<ResourceHandler> WrapResourceHandler( | 380 virtual scoped_ptr<ResourceHandler> WrapResourceHandler( |
| 314 scoped_ptr<ResourceHandlerStub> leaf_handler, | 381 scoped_ptr<ResourceHandlerStub> leaf_handler, |
| 315 net::URLRequest* request) { | 382 net::URLRequest* request) { |
| 316 return leaf_handler.Pass(); | 383 return leaf_handler.Pass(); |
| 317 } | 384 } |
| 318 | 385 |
| 319 void SetUp() override { | 386 void SetUp() override { |
| 320 const int kRenderProcessId = 1; | 387 job_factory_.SetProtocolHandler("test", CreateProtocolHandler()); |
| 321 const int kRenderViewId = 2; | 388 |
| 389 browser_context_.reset(new TestBrowserContext()); | |
| 390 scoped_refptr<SiteInstance> site_instance = | |
| 391 SiteInstance::Create(browser_context_.get()); | |
| 392 web_contents_.reset( | |
| 393 TestWebContents::Create(browser_context_.get(), site_instance.get())); | |
| 394 RenderFrameHost* rfh = web_contents_->GetMainFrame(); | |
| 322 | 395 |
| 323 scoped_ptr<net::URLRequest> request( | 396 scoped_ptr<net::URLRequest> request( |
| 324 resource_context_.GetRequestContext()->CreateRequest( | 397 resource_context_.GetRequestContext()->CreateRequest( |
| 325 test_url(), | 398 test_url(), |
| 326 net::DEFAULT_PRIORITY, | 399 net::DEFAULT_PRIORITY, |
| 327 NULL /* delegate */, | 400 NULL /* delegate */, |
| 328 NULL /* cookie_store */)); | 401 NULL /* cookie_store */)); |
| 329 raw_ptr_to_request_ = request.get(); | 402 raw_ptr_to_request_ = request.get(); |
| 330 ResourceRequestInfo::AllocateForTesting(request.get(), | 403 ResourceRequestInfo::AllocateForTesting( |
| 331 RESOURCE_TYPE_MAIN_FRAME, | 404 request.get(), RESOURCE_TYPE_MAIN_FRAME, &resource_context_, |
| 332 &resource_context_, | 405 rfh->GetProcess()->GetID(), rfh->GetRenderViewHost()->GetRoutingID(), |
| 333 kRenderProcessId, | 406 rfh->GetRoutingID(), true /* is_main_frame */, |
| 334 kRenderViewId, | 407 false /* parent_is_main_frame */, true /* allow_download */, |
| 335 MSG_ROUTING_NONE, | 408 false /* is_async */); |
| 336 true, // is_main_frame | |
| 337 false, // parent_is_main_frame | |
| 338 true, // allow_download | |
| 339 false); // is_async | |
| 340 scoped_ptr<ResourceHandlerStub> resource_handler( | 409 scoped_ptr<ResourceHandlerStub> resource_handler( |
| 341 new ResourceHandlerStub(request.get())); | 410 new ResourceHandlerStub(request.get())); |
| 342 raw_ptr_resource_handler_ = resource_handler.get(); | 411 raw_ptr_resource_handler_ = resource_handler.get(); |
| 343 loader_.reset(new ResourceLoader( | 412 loader_.reset(new ResourceLoader( |
| 344 request.Pass(), | 413 request.Pass(), |
| 345 WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_), | 414 WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_), |
| 346 this)); | 415 this)); |
| 347 } | 416 } |
| 348 | 417 |
| 418 void TearDown() override { | |
| 419 web_contents_.reset(); | |
| 420 base::RunLoop().RunUntilIdle(); | |
|
mmenke
2015/02/13 19:35:53
Think this is worth a comment
davidben
2015/02/13 22:04:11
Added /a/ comment. I'm not actually sure what the
mmenke
2015/02/17 19:50:14
That's fine. I don't think we really care what it
| |
| 421 } | |
| 422 | |
| 349 // ResourceLoaderDelegate: | 423 // ResourceLoaderDelegate: |
| 350 ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( | 424 ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( |
| 351 ResourceLoader* loader, | 425 ResourceLoader* loader, |
| 352 net::AuthChallengeInfo* auth_info) override { | 426 net::AuthChallengeInfo* auth_info) override { |
| 353 return NULL; | 427 return NULL; |
| 354 } | 428 } |
| 355 bool HandleExternalProtocol(ResourceLoader* loader, | 429 bool HandleExternalProtocol(ResourceLoader* loader, |
| 356 const GURL& url) override { | 430 const GURL& url) override { |
| 357 return false; | 431 return false; |
| 358 } | 432 } |
| 359 void DidStartRequest(ResourceLoader* loader) override {} | 433 void DidStartRequest(ResourceLoader* loader) override {} |
| 360 void DidReceiveRedirect(ResourceLoader* loader, | 434 void DidReceiveRedirect(ResourceLoader* loader, |
| 361 const GURL& new_url) override {} | 435 const GURL& new_url) override {} |
| 362 void DidReceiveResponse(ResourceLoader* loader) override {} | 436 void DidReceiveResponse(ResourceLoader* loader) override {} |
| 363 void DidFinishLoading(ResourceLoader* loader) override {} | 437 void DidFinishLoading(ResourceLoader* loader) override {} |
| 364 | 438 |
| 365 content::TestBrowserThreadBundle thread_bundle_; | 439 TestBrowserThreadBundle thread_bundle_; |
| 440 RenderViewHostTestEnabler rvh_test_enabler_; | |
| 366 | 441 |
| 367 net::URLRequestJobFactoryImpl job_factory_; | 442 net::URLRequestJobFactoryImpl job_factory_; |
| 368 net::TestURLRequestContext test_url_request_context_; | 443 net::TestURLRequestContext test_url_request_context_; |
| 369 ResourceContextStub resource_context_; | 444 ResourceContextStub resource_context_; |
| 445 scoped_ptr<TestBrowserContext> browser_context_; | |
| 446 scoped_ptr<TestWebContents> web_contents_; | |
| 370 | 447 |
| 371 // The ResourceLoader owns the URLRequest and the ResourceHandler. | 448 // The ResourceLoader owns the URLRequest and the ResourceHandler. |
| 372 ResourceHandlerStub* raw_ptr_resource_handler_; | 449 ResourceHandlerStub* raw_ptr_resource_handler_; |
| 373 net::URLRequest* raw_ptr_to_request_; | 450 net::URLRequest* raw_ptr_to_request_; |
| 374 scoped_ptr<ResourceLoader> loader_; | 451 scoped_ptr<ResourceLoader> loader_; |
| 375 }; | 452 }; |
| 376 | 453 |
| 377 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested() | 454 class ClientCertResourceLoaderTest : public ResourceLoaderTest { |
| 378 // causes client cert store to be queried for certificates and if the returned | 455 protected: |
| 379 // certificates are correctly passed to the content browser client for | 456 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override { |
| 380 // selection. | 457 return new MockClientCertJobProtocolHandler; |
| 381 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) { | 458 } |
| 459 }; | |
| 460 | |
| 461 // Tests that client certificates are requested with ClientCertStore lookup. | |
| 462 TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { | |
| 382 // Set up the test client cert store. | 463 // Set up the test client cert store. |
| 383 int store_request_count; | 464 int store_request_count; |
| 384 std::vector<std::string> store_requested_authorities; | 465 std::vector<std::string> store_requested_authorities; |
| 385 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( | 466 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( |
| 386 new net::X509Certificate("test", "test", base::Time(), base::Time()))); | 467 new net::X509Certificate("test", "test", base::Time(), base::Time()))); |
| 387 scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( | 468 scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( |
| 388 dummy_certs, &store_request_count, &store_requested_authorities)); | 469 dummy_certs, &store_request_count, &store_requested_authorities)); |
| 389 resource_context_.SetClientCertStore(test_store.Pass()); | 470 resource_context_.SetClientCertStore(test_store.Pass()); |
| 390 | 471 |
| 391 // Prepare a dummy certificate request. | |
| 392 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | |
| 393 new net::SSLCertRequestInfo()); | |
| 394 std::vector<std::string> dummy_authority(1, "dummy"); | |
| 395 cert_request_info->cert_authorities = dummy_authority; | |
| 396 | |
| 397 // Plug in test content browser client. | 472 // Plug in test content browser client. |
| 398 SelectCertificateBrowserClient test_client; | 473 SelectCertificateBrowserClient test_client; |
| 399 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 474 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |
| 400 | 475 |
| 401 // Everything is set up. Trigger the resource loader certificate request event | 476 // Start the request and wait for it to pause. |
| 402 // and run the message loop. | 477 loader_->StartRequest(); |
| 403 loader_->OnCertificateRequested(raw_ptr_to_request_, cert_request_info.get()); | |
| 404 base::RunLoop().RunUntilIdle(); | 478 base::RunLoop().RunUntilIdle(); |
| 405 | 479 |
| 406 // Restore the original content browser client. | 480 EXPECT_FALSE(raw_ptr_resource_handler_->received_response_completed()); |
| 407 SetBrowserClientForTesting(old_client); | |
| 408 | 481 |
| 409 // Check if the test store was queried against correct |cert_authorities|. | 482 // Check if the test store was queried against correct |cert_authorities|. |
| 410 EXPECT_EQ(1, store_request_count); | 483 EXPECT_EQ(1, store_request_count); |
| 411 EXPECT_EQ(dummy_authority, store_requested_authorities); | 484 EXPECT_EQ(MockClientCertURLRequestJob::test_authorities(), |
| 485 store_requested_authorities); | |
| 412 | 486 |
| 413 // Check if the retrieved certificates were passed to the content browser | 487 // Check if the retrieved certificates were passed to the content browser |
| 414 // client. | 488 // client. |
| 415 EXPECT_EQ(1, test_client.call_count()); | 489 EXPECT_EQ(1, test_client.call_count()); |
| 416 EXPECT_EQ(dummy_certs, test_client.passed_certs()); | 490 EXPECT_EQ(dummy_certs, test_client.passed_certs()); |
| 491 | |
| 492 // Continue the request. | |
| 493 test_client.delegate()->ContinueWithCertificate(dummy_certs[0].get()); | |
| 494 base::RunLoop().RunUntilIdle(); | |
| 495 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | |
| 496 EXPECT_EQ(net::OK, raw_ptr_resource_handler_->status().error()); | |
| 497 | |
| 498 // Restore the original content browser client. | |
| 499 SetBrowserClientForTesting(old_client); | |
| 417 } | 500 } |
| 418 | 501 |
| 419 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested() | 502 // Tests that client certificates are requested on a platform with NULL |
| 420 // on a platform with a NULL client cert store still calls the content browser | 503 // ClientCertStore. |
| 421 // client for selection. | 504 TEST_F(ClientCertResourceLoaderTest, WithNullStore) { |
| 422 TEST_F(ResourceLoaderTest, ClientCertStoreNull) { | 505 // Plug in test content browser client. |
| 423 // Prepare a dummy certificate request. | 506 SelectCertificateBrowserClient test_client; |
| 424 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | 507 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |
| 425 new net::SSLCertRequestInfo()); | 508 |
| 426 std::vector<std::string> dummy_authority(1, "dummy"); | 509 // Start the request and wait for it to pause. |
| 427 cert_request_info->cert_authorities = dummy_authority; | 510 loader_->StartRequest(); |
| 511 base::RunLoop().RunUntilIdle(); | |
| 512 | |
| 513 // Check if the SelectClientCertificate was called on the content browser | |
| 514 // client. | |
| 515 EXPECT_EQ(1, test_client.call_count()); | |
| 516 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); | |
| 517 | |
| 518 // Continue the request. | |
| 519 scoped_refptr<net::X509Certificate> cert( | |
| 520 new net::X509Certificate("test", "test", base::Time(), base::Time())); | |
| 521 test_client.delegate()->ContinueWithCertificate(cert.get()); | |
| 522 base::RunLoop().RunUntilIdle(); | |
| 523 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | |
| 524 EXPECT_EQ(net::OK, raw_ptr_resource_handler_->status().error()); | |
| 525 | |
| 526 // Restore the original content browser client. | |
| 527 SetBrowserClientForTesting(old_client); | |
| 528 } | |
| 529 | |
| 530 // Tests that the ContentBrowserClient may cancel a certificate request. | |
| 531 TEST_F(ClientCertResourceLoaderTest, CancelSelection) { | |
| 532 // Plug in test content browser client. | |
| 533 SelectCertificateBrowserClient test_client; | |
| 534 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | |
| 535 | |
| 536 // Start the request and wait for it to pause. | |
| 537 loader_->StartRequest(); | |
| 538 base::RunLoop().RunUntilIdle(); | |
| 539 | |
| 540 // Check if the SelectClientCertificate was called on the content browser | |
| 541 // client. | |
| 542 EXPECT_EQ(1, test_client.call_count()); | |
| 543 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); | |
| 544 | |
| 545 // Cancel the request. | |
| 546 test_client.delegate()->CancelCertificateSelection(); | |
| 547 base::RunLoop().RunUntilIdle(); | |
| 548 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | |
| 549 EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, | |
| 550 raw_ptr_resource_handler_->status().error()); | |
| 551 | |
| 552 // Restore the original content browser client. | |
| 553 SetBrowserClientForTesting(old_client); | |
| 554 } | |
| 555 | |
| 556 // Verifies that requests without WebContents attached abort. | |
| 557 TEST_F(ClientCertResourceLoaderTest, NoWebContents) { | |
| 558 // Destroy the WebContents before starting the request. | |
| 559 web_contents_.reset(); | |
| 428 | 560 |
| 429 // Plug in test content browser client. | 561 // Plug in test content browser client. |
| 430 SelectCertificateBrowserClient test_client; | 562 SelectCertificateBrowserClient test_client; |
| 431 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 563 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |
| 432 | 564 |
| 433 // Everything is set up. Trigger the resource loader certificate request event | 565 // Start the request and wait for it to pause. |
| 434 // and run the message loop. | 566 loader_->StartRequest(); |
| 435 loader_->OnCertificateRequested(raw_ptr_to_request_, cert_request_info.get()); | |
| 436 base::RunLoop().RunUntilIdle(); | 567 base::RunLoop().RunUntilIdle(); |
| 437 | 568 |
| 569 // Check that SelectClientCertificate wasn't called and the request aborted. | |
| 570 EXPECT_EQ(0, test_client.call_count()); | |
| 571 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | |
| 572 EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, | |
| 573 raw_ptr_resource_handler_->status().error()); | |
| 574 | |
| 438 // Restore the original content browser client. | 575 // Restore the original content browser client. |
| 439 SetBrowserClientForTesting(old_client); | 576 SetBrowserClientForTesting(old_client); |
| 440 | |
| 441 // Check if the SelectClientCertificate was called on the content browser | |
| 442 // client. | |
| 443 EXPECT_EQ(1, test_client.call_count()); | |
| 444 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); | |
| 445 } | 577 } |
| 446 | 578 |
| 447 TEST_F(ResourceLoaderTest, ClientCertStoreAsyncCancel) { | 579 // Verifies that ClientCertStore's callback doesn't crash if called after the |
| 448 // Set up the test client cert store. | 580 // loader is destroyed. |
| 449 int store_request_count; | 581 TEST_F(ClientCertResourceLoaderTest, StoreAsyncCancel) { |
| 450 std::vector<std::string> store_requested_authorities; | 582 scoped_ptr<CancelingClientCertStore> test_store( |
| 451 scoped_ptr<ClientCertStoreStub> test_store( | 583 new CancelingClientCertStore(&loader_)); |
|
mmenke
2015/02/13 19:35:53
Can we just keep a raw pointer to the loader ourse
davidben
2015/02/13 22:04:11
Hrm. We could, although I dunno if I'd be able to
mmenke
2015/02/17 19:50:14
Ahh...right, good point.
| |
| 452 new ClientCertStoreStub(net::CertificateList(), &store_request_count, | |
| 453 &store_requested_authorities)); | |
| 454 test_store->set_async(true); | |
| 455 EXPECT_EQ(0, store_request_count); | |
| 456 resource_context_.SetClientCertStore(test_store.Pass()); | 584 resource_context_.SetClientCertStore(test_store.Pass()); |
| 457 | 585 |
| 458 // Prepare a dummy certificate request. | 586 loader_->StartRequest(); |
| 459 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | 587 base::RunLoop().RunUntilIdle(); |
| 460 new net::SSLCertRequestInfo()); | 588 EXPECT_FALSE(loader_); |
| 461 std::vector<std::string> dummy_authority(1, "dummy"); | |
| 462 cert_request_info->cert_authorities = dummy_authority; | |
| 463 | 589 |
| 464 // Everything is set up. Trigger the resource loader certificate request | 590 // Pump the event loop to ensure nothing asynchronous crashes either. |
| 465 // event. | |
| 466 loader_->OnCertificateRequested(raw_ptr_to_request_, cert_request_info.get()); | |
| 467 | |
| 468 // Check if the test store was queried against correct |cert_authorities|. | |
| 469 EXPECT_EQ(1, store_request_count); | |
| 470 EXPECT_EQ(dummy_authority, store_requested_authorities); | |
| 471 | |
| 472 // Cancel the request before the store calls the callback. | |
| 473 loader_.reset(); | |
| 474 | |
| 475 // Pump the event loop. There shouldn't be a crash when the callback is run. | |
| 476 base::RunLoop().RunUntilIdle(); | 591 base::RunLoop().RunUntilIdle(); |
| 477 } | 592 } |
| 478 | 593 |
| 479 TEST_F(ResourceLoaderTest, ResumeCancelledRequest) { | 594 TEST_F(ResourceLoaderTest, ResumeCancelledRequest) { |
| 480 raw_ptr_resource_handler_->set_defer_request_on_will_start(true); | 595 raw_ptr_resource_handler_->set_defer_request_on_will_start(true); |
| 481 | 596 |
| 482 loader_->StartRequest(); | 597 loader_->StartRequest(); |
| 483 loader_->CancelRequest(true); | 598 loader_->CancelRequest(true); |
| 484 static_cast<ResourceController*>(loader_.get())->Resume(); | 599 static_cast<ResourceController*>(loader_.get())->Resume(); |
| 485 } | 600 } |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 760 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); | 875 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); |
| 761 EXPECT_EQ(test_data(), contents); | 876 EXPECT_EQ(test_data(), contents); |
| 762 | 877 |
| 763 // Release the loader. The file should be gone now. | 878 // Release the loader. The file should be gone now. |
| 764 ReleaseLoader(); | 879 ReleaseLoader(); |
| 765 base::RunLoop().RunUntilIdle(); | 880 base::RunLoop().RunUntilIdle(); |
| 766 EXPECT_FALSE(base::PathExists(temp_path())); | 881 EXPECT_FALSE(base::PathExists(temp_path())); |
| 767 } | 882 } |
| 768 | 883 |
| 769 } // namespace content | 884 } // namespace content |
| OLD | NEW |