| 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 LoaderDestroyingCertStore : public net::ClientCertStore { | 
 |   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 LoaderDestroyingCertStore(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(&LoaderDestroyingCertStore::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  | 
 |  129   // net::URLRequestTestJob: | 
 |  130   void Start() override { | 
 |  131     scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | 
 |  132         new net::SSLCertRequestInfo); | 
 |  133     cert_request_info->cert_authorities = test_authorities(); | 
 |  134     base::MessageLoop::current()->PostTask( | 
 |  135         FROM_HERE, | 
 |  136         base::Bind(&MockClientCertURLRequestJob::NotifyCertificateRequested, | 
 |  137                    this, cert_request_info)); | 
 |  138   } | 
 |  139  | 
 |  140   void ContinueWithCertificate(net::X509Certificate* cert) override { | 
 |  141     net::URLRequestTestJob::Start(); | 
 |  142   } | 
 |  143  | 
 |  144  private: | 
 |  145   ~MockClientCertURLRequestJob() override {} | 
 |  146  | 
 |  147   DISALLOW_COPY_AND_ASSIGN(MockClientCertURLRequestJob); | 
 |  148 }; | 
 |  149  | 
 |  150 class MockClientCertJobProtocolHandler | 
 |  151     : public net::URLRequestJobFactory::ProtocolHandler { | 
 |  152  public: | 
 |  153   // URLRequestJobFactory::ProtocolHandler implementation: | 
 |  154   net::URLRequestJob* MaybeCreateJob( | 
 |  155       net::URLRequest* request, | 
 |  156       net::NetworkDelegate* network_delegate) const override { | 
 |  157     return new MockClientCertURLRequestJob(request, network_delegate); | 
 |  158   } | 
 |  159 }; | 
 |  160  | 
|   90 // Arbitrary read buffer size. |  161 // Arbitrary read buffer size. | 
|   91 const int kReadBufSize = 1024; |  162 const int kReadBufSize = 1024; | 
|   92  |  163  | 
|   93 // Dummy implementation of ResourceHandler, instance of which is needed to |  164 // Dummy implementation of ResourceHandler, instance of which is needed to | 
|   94 // initialize ResourceLoader. |  165 // initialize ResourceLoader. | 
|   95 class ResourceHandlerStub : public ResourceHandler { |  166 class ResourceHandlerStub : public ResourceHandler { | 
|   96  public: |  167  public: | 
|   97   explicit ResourceHandlerStub(net::URLRequest* request) |  168   explicit ResourceHandlerStub(net::URLRequest* request) | 
|   98       : ResourceHandler(request), |  169       : ResourceHandler(request), | 
|   99         read_buffer_(new net::IOBuffer(kReadBufSize)), |  170         read_buffer_(new net::IOBuffer(kReadBufSize)), | 
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  232   int total_bytes_downloaded_; |  303   int total_bytes_downloaded_; | 
|  233 }; |  304 }; | 
|  234  |  305  | 
|  235 // Test browser client that captures calls to SelectClientCertificates and |  306 // Test browser client that captures calls to SelectClientCertificates and | 
|  236 // records the arguments of the most recent call for later inspection. |  307 // records the arguments of the most recent call for later inspection. | 
|  237 class SelectCertificateBrowserClient : public TestContentBrowserClient { |  308 class SelectCertificateBrowserClient : public TestContentBrowserClient { | 
|  238  public: |  309  public: | 
|  239   SelectCertificateBrowserClient() : call_count_(0) {} |  310   SelectCertificateBrowserClient() : call_count_(0) {} | 
|  240  |  311  | 
|  241   void SelectClientCertificate( |  312   void SelectClientCertificate( | 
|  242       int render_process_id, |  313       WebContents* web_contents, | 
|  243       int render_view_id, |  | 
|  244       net::SSLCertRequestInfo* cert_request_info, |  314       net::SSLCertRequestInfo* cert_request_info, | 
|  245       const base::Callback<void(net::X509Certificate*)>& callback) override { |  315       scoped_ptr<ClientCertificateDelegate> delegate) override { | 
|  246     ++call_count_; |  316     ++call_count_; | 
|  247     passed_certs_ = cert_request_info->client_certs; |  317     passed_certs_ = cert_request_info->client_certs; | 
 |  318     delegate_ = delegate.Pass(); | 
|  248   } |  319   } | 
|  249  |  320  | 
|  250   int call_count() { |  321   int call_count() { return call_count_; } | 
|  251     return call_count_; |  322   net::CertificateList passed_certs() { return passed_certs_; } | 
 |  323  | 
 |  324   void ContinueWithCertificate(net::X509Certificate* cert) { | 
 |  325     delegate_->ContinueWithCertificate(cert); | 
 |  326     delegate_.reset(); | 
|  252   } |  327   } | 
|  253  |  328  | 
|  254   net::CertificateList passed_certs() { |  329   void CancelCertificateSelection() { delegate_.reset(); } | 
|  255     return passed_certs_; |  | 
|  256   } |  | 
|  257  |  330  | 
|  258  private: |  331  private: | 
|  259   net::CertificateList passed_certs_; |  332   net::CertificateList passed_certs_; | 
|  260   int call_count_; |  333   int call_count_; | 
 |  334   scoped_ptr<ClientCertificateDelegate> delegate_; | 
|  261 }; |  335 }; | 
|  262  |  336  | 
|  263 class ResourceContextStub : public MockResourceContext { |  337 class ResourceContextStub : public MockResourceContext { | 
|  264  public: |  338  public: | 
|  265   explicit ResourceContextStub(net::URLRequestContext* test_request_context) |  339   explicit ResourceContextStub(net::URLRequestContext* test_request_context) | 
|  266       : MockResourceContext(test_request_context) {} |  340       : MockResourceContext(test_request_context) {} | 
|  267  |  341  | 
|  268   scoped_ptr<net::ClientCertStore> CreateClientCertStore() override { |  342   scoped_ptr<net::ClientCertStore> CreateClientCertStore() override { | 
|  269     return dummy_cert_store_.Pass(); |  343     return dummy_cert_store_.Pass(); | 
|  270   } |  344   } | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  290 }  // namespace |  364 }  // namespace | 
|  291  |  365  | 
|  292 class ResourceLoaderTest : public testing::Test, |  366 class ResourceLoaderTest : public testing::Test, | 
|  293                            public ResourceLoaderDelegate { |  367                            public ResourceLoaderDelegate { | 
|  294  protected: |  368  protected: | 
|  295   ResourceLoaderTest() |  369   ResourceLoaderTest() | 
|  296     : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |  370     : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | 
|  297       resource_context_(&test_url_request_context_), |  371       resource_context_(&test_url_request_context_), | 
|  298       raw_ptr_resource_handler_(NULL), |  372       raw_ptr_resource_handler_(NULL), | 
|  299       raw_ptr_to_request_(NULL) { |  373       raw_ptr_to_request_(NULL) { | 
|  300     job_factory_.SetProtocolHandler( |  | 
|  301         "test", net::URLRequestTestJob::CreateProtocolHandler()); |  | 
|  302     test_url_request_context_.set_job_factory(&job_factory_); |  374     test_url_request_context_.set_job_factory(&job_factory_); | 
|  303   } |  375   } | 
|  304  |  376  | 
|  305   GURL test_url() const { |  377   GURL test_url() const { return net::URLRequestTestJob::test_url_1(); } | 
|  306     return net::URLRequestTestJob::test_url_1(); |  | 
|  307   } |  | 
|  308  |  378  | 
|  309   std::string test_data() const { |  379   std::string test_data() const { | 
|  310     return net::URLRequestTestJob::test_data_1(); |  380     return net::URLRequestTestJob::test_data_1(); | 
|  311   } |  381   } | 
|  312  |  382  | 
 |  383   virtual net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() { | 
 |  384     return net::URLRequestTestJob::CreateProtocolHandler(); | 
 |  385   } | 
 |  386  | 
|  313   virtual scoped_ptr<ResourceHandler> WrapResourceHandler( |  387   virtual scoped_ptr<ResourceHandler> WrapResourceHandler( | 
|  314       scoped_ptr<ResourceHandlerStub> leaf_handler, |  388       scoped_ptr<ResourceHandlerStub> leaf_handler, | 
|  315       net::URLRequest* request) { |  389       net::URLRequest* request) { | 
|  316     return leaf_handler.Pass(); |  390     return leaf_handler.Pass(); | 
|  317   } |  391   } | 
|  318  |  392  | 
|  319   void SetUp() override { |  393   void SetUp() override { | 
|  320     const int kRenderProcessId = 1; |  394     job_factory_.SetProtocolHandler("test", CreateProtocolHandler()); | 
|  321     const int kRenderViewId = 2; |  395  | 
 |  396     browser_context_.reset(new TestBrowserContext()); | 
 |  397     scoped_refptr<SiteInstance> site_instance = | 
 |  398         SiteInstance::Create(browser_context_.get()); | 
 |  399     web_contents_.reset( | 
 |  400         TestWebContents::Create(browser_context_.get(), site_instance.get())); | 
 |  401     RenderFrameHost* rfh = web_contents_->GetMainFrame(); | 
|  322  |  402  | 
|  323     scoped_ptr<net::URLRequest> request( |  403     scoped_ptr<net::URLRequest> request( | 
|  324         resource_context_.GetRequestContext()->CreateRequest( |  404         resource_context_.GetRequestContext()->CreateRequest( | 
|  325             test_url(), |  405             test_url(), | 
|  326             net::DEFAULT_PRIORITY, |  406             net::DEFAULT_PRIORITY, | 
|  327             NULL /* delegate */, |  407             NULL /* delegate */, | 
|  328             NULL /* cookie_store */)); |  408             NULL /* cookie_store */)); | 
|  329     raw_ptr_to_request_ = request.get(); |  409     raw_ptr_to_request_ = request.get(); | 
|  330     ResourceRequestInfo::AllocateForTesting(request.get(), |  410     ResourceRequestInfo::AllocateForTesting( | 
|  331                                             RESOURCE_TYPE_MAIN_FRAME, |  411         request.get(), RESOURCE_TYPE_MAIN_FRAME, &resource_context_, | 
|  332                                             &resource_context_, |  412         rfh->GetProcess()->GetID(), rfh->GetRenderViewHost()->GetRoutingID(), | 
|  333                                             kRenderProcessId, |  413         rfh->GetRoutingID(), true /* is_main_frame */, | 
|  334                                             kRenderViewId, |  414         false /* parent_is_main_frame */, true /* allow_download */, | 
|  335                                             MSG_ROUTING_NONE, |  415         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( |  416     scoped_ptr<ResourceHandlerStub> resource_handler( | 
|  341         new ResourceHandlerStub(request.get())); |  417         new ResourceHandlerStub(request.get())); | 
|  342     raw_ptr_resource_handler_ = resource_handler.get(); |  418     raw_ptr_resource_handler_ = resource_handler.get(); | 
|  343     loader_.reset(new ResourceLoader( |  419     loader_.reset(new ResourceLoader( | 
|  344         request.Pass(), |  420         request.Pass(), | 
|  345         WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_), |  421         WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_), | 
|  346         this)); |  422         this)); | 
|  347   } |  423   } | 
|  348  |  424  | 
 |  425   void TearDown() override { | 
 |  426     // Destroy the WebContents and pump the event loop before destroying | 
 |  427     // |rvh_test_enabler_| and |thread_bundle_|. This lets asynchronous cleanup | 
 |  428     // tasks complete. | 
 |  429     web_contents_.reset(); | 
 |  430     base::RunLoop().RunUntilIdle(); | 
 |  431   } | 
 |  432  | 
|  349   // ResourceLoaderDelegate: |  433   // ResourceLoaderDelegate: | 
|  350   ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( |  434   ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( | 
|  351       ResourceLoader* loader, |  435       ResourceLoader* loader, | 
|  352       net::AuthChallengeInfo* auth_info) override { |  436       net::AuthChallengeInfo* auth_info) override { | 
|  353     return NULL; |  437     return NULL; | 
|  354   } |  438   } | 
|  355   bool HandleExternalProtocol(ResourceLoader* loader, |  439   bool HandleExternalProtocol(ResourceLoader* loader, | 
|  356                               const GURL& url) override { |  440                               const GURL& url) override { | 
|  357     return false; |  441     return false; | 
|  358   } |  442   } | 
|  359   void DidStartRequest(ResourceLoader* loader) override {} |  443   void DidStartRequest(ResourceLoader* loader) override {} | 
|  360   void DidReceiveRedirect(ResourceLoader* loader, |  444   void DidReceiveRedirect(ResourceLoader* loader, | 
|  361                           const GURL& new_url) override {} |  445                           const GURL& new_url) override {} | 
|  362   void DidReceiveResponse(ResourceLoader* loader) override {} |  446   void DidReceiveResponse(ResourceLoader* loader) override {} | 
|  363   void DidFinishLoading(ResourceLoader* loader) override {} |  447   void DidFinishLoading(ResourceLoader* loader) override {} | 
|  364  |  448  | 
|  365   content::TestBrowserThreadBundle thread_bundle_; |  449   TestBrowserThreadBundle thread_bundle_; | 
 |  450   RenderViewHostTestEnabler rvh_test_enabler_; | 
|  366  |  451  | 
|  367   net::URLRequestJobFactoryImpl job_factory_; |  452   net::URLRequestJobFactoryImpl job_factory_; | 
|  368   net::TestURLRequestContext test_url_request_context_; |  453   net::TestURLRequestContext test_url_request_context_; | 
|  369   ResourceContextStub resource_context_; |  454   ResourceContextStub resource_context_; | 
 |  455   scoped_ptr<TestBrowserContext> browser_context_; | 
 |  456   scoped_ptr<TestWebContents> web_contents_; | 
|  370  |  457  | 
|  371   // The ResourceLoader owns the URLRequest and the ResourceHandler. |  458   // The ResourceLoader owns the URLRequest and the ResourceHandler. | 
|  372   ResourceHandlerStub* raw_ptr_resource_handler_; |  459   ResourceHandlerStub* raw_ptr_resource_handler_; | 
|  373   net::URLRequest* raw_ptr_to_request_; |  460   net::URLRequest* raw_ptr_to_request_; | 
|  374   scoped_ptr<ResourceLoader> loader_; |  461   scoped_ptr<ResourceLoader> loader_; | 
|  375 }; |  462 }; | 
|  376  |  463  | 
|  377 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested() |  464 class ClientCertResourceLoaderTest : public ResourceLoaderTest { | 
|  378 // causes client cert store to be queried for certificates and if the returned |  465  protected: | 
|  379 // certificates are correctly passed to the content browser client for |  466   net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override { | 
|  380 // selection. |  467     return new MockClientCertJobProtocolHandler; | 
|  381 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) { |  468   } | 
 |  469 }; | 
 |  470  | 
 |  471 // Tests that client certificates are requested with ClientCertStore lookup. | 
 |  472 TEST_F(ClientCertResourceLoaderTest, WithStoreLookup) { | 
|  382   // Set up the test client cert store. |  473   // Set up the test client cert store. | 
|  383   int store_request_count; |  474   int store_request_count; | 
|  384   std::vector<std::string> store_requested_authorities; |  475   std::vector<std::string> store_requested_authorities; | 
|  385   net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( |  476   net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( | 
|  386       new net::X509Certificate("test", "test", base::Time(), base::Time()))); |  477       new net::X509Certificate("test", "test", base::Time(), base::Time()))); | 
|  387   scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( |  478   scoped_ptr<ClientCertStoreStub> test_store(new ClientCertStoreStub( | 
|  388       dummy_certs, &store_request_count, &store_requested_authorities)); |  479       dummy_certs, &store_request_count, &store_requested_authorities)); | 
|  389   resource_context_.SetClientCertStore(test_store.Pass()); |  480   resource_context_.SetClientCertStore(test_store.Pass()); | 
|  390  |  481  | 
|  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. |  482   // Plug in test content browser client. | 
|  398   SelectCertificateBrowserClient test_client; |  483   SelectCertificateBrowserClient test_client; | 
|  399   ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |  484   ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 
|  400  |  485  | 
|  401   // Everything is set up. Trigger the resource loader certificate request event |  486   // Start the request and wait for it to pause. | 
|  402   // and run the message loop. |  487   loader_->StartRequest(); | 
|  403   loader_->OnCertificateRequested(raw_ptr_to_request_, cert_request_info.get()); |  | 
|  404   base::RunLoop().RunUntilIdle(); |  488   base::RunLoop().RunUntilIdle(); | 
|  405  |  489  | 
|  406   // Restore the original content browser client. |  490   EXPECT_FALSE(raw_ptr_resource_handler_->received_response_completed()); | 
|  407   SetBrowserClientForTesting(old_client); |  | 
|  408  |  491  | 
|  409   // Check if the test store was queried against correct |cert_authorities|. |  492   // Check if the test store was queried against correct |cert_authorities|. | 
|  410   EXPECT_EQ(1, store_request_count); |  493   EXPECT_EQ(1, store_request_count); | 
|  411   EXPECT_EQ(dummy_authority, store_requested_authorities); |  494   EXPECT_EQ(MockClientCertURLRequestJob::test_authorities(), | 
 |  495             store_requested_authorities); | 
|  412  |  496  | 
|  413   // Check if the retrieved certificates were passed to the content browser |  497   // Check if the retrieved certificates were passed to the content browser | 
|  414   // client. |  498   // client. | 
|  415   EXPECT_EQ(1, test_client.call_count()); |  499   EXPECT_EQ(1, test_client.call_count()); | 
|  416   EXPECT_EQ(dummy_certs, test_client.passed_certs()); |  500   EXPECT_EQ(dummy_certs, test_client.passed_certs()); | 
 |  501  | 
 |  502   // Continue the request. | 
 |  503   test_client.ContinueWithCertificate(dummy_certs[0].get()); | 
 |  504   base::RunLoop().RunUntilIdle(); | 
 |  505   EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | 
 |  506   EXPECT_EQ(net::OK, raw_ptr_resource_handler_->status().error()); | 
 |  507  | 
 |  508   // Restore the original content browser client. | 
 |  509   SetBrowserClientForTesting(old_client); | 
|  417 } |  510 } | 
|  418  |  511  | 
|  419 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested() |  512 // 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 |  513 // ClientCertStore. | 
|  421 // client for selection. |  514 TEST_F(ClientCertResourceLoaderTest, WithNullStore) { | 
|  422 TEST_F(ResourceLoaderTest, ClientCertStoreNull) { |  515   // Plug in test content browser client. | 
|  423   // Prepare a dummy certificate request. |  516   SelectCertificateBrowserClient test_client; | 
|  424   scoped_refptr<net::SSLCertRequestInfo> cert_request_info( |  517   ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 
|  425       new net::SSLCertRequestInfo()); |  518  | 
|  426   std::vector<std::string> dummy_authority(1, "dummy"); |  519   // Start the request and wait for it to pause. | 
|  427   cert_request_info->cert_authorities = dummy_authority; |  520   loader_->StartRequest(); | 
 |  521   base::RunLoop().RunUntilIdle(); | 
 |  522  | 
 |  523   // Check if the SelectClientCertificate was called on the content browser | 
 |  524   // client. | 
 |  525   EXPECT_EQ(1, test_client.call_count()); | 
 |  526   EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); | 
 |  527  | 
 |  528   // Continue the request. | 
 |  529   scoped_refptr<net::X509Certificate> cert( | 
 |  530       new net::X509Certificate("test", "test", base::Time(), base::Time())); | 
 |  531   test_client.ContinueWithCertificate(cert.get()); | 
 |  532   base::RunLoop().RunUntilIdle(); | 
 |  533   EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | 
 |  534   EXPECT_EQ(net::OK, raw_ptr_resource_handler_->status().error()); | 
 |  535  | 
 |  536   // Restore the original content browser client. | 
 |  537   SetBrowserClientForTesting(old_client); | 
 |  538 } | 
 |  539  | 
 |  540 // Tests that the ContentBrowserClient may cancel a certificate request. | 
 |  541 TEST_F(ClientCertResourceLoaderTest, CancelSelection) { | 
 |  542   // Plug in test content browser client. | 
 |  543   SelectCertificateBrowserClient test_client; | 
 |  544   ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 
 |  545  | 
 |  546   // Start the request and wait for it to pause. | 
 |  547   loader_->StartRequest(); | 
 |  548   base::RunLoop().RunUntilIdle(); | 
 |  549  | 
 |  550   // Check if the SelectClientCertificate was called on the content browser | 
 |  551   // client. | 
 |  552   EXPECT_EQ(1, test_client.call_count()); | 
 |  553   EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); | 
 |  554  | 
 |  555   // Cancel the request. | 
 |  556   test_client.CancelCertificateSelection(); | 
 |  557   base::RunLoop().RunUntilIdle(); | 
 |  558   EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | 
 |  559   EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, | 
 |  560             raw_ptr_resource_handler_->status().error()); | 
 |  561  | 
 |  562   // Restore the original content browser client. | 
 |  563   SetBrowserClientForTesting(old_client); | 
 |  564 } | 
 |  565  | 
 |  566 // Verifies that requests without WebContents attached abort. | 
 |  567 TEST_F(ClientCertResourceLoaderTest, NoWebContents) { | 
 |  568   // Destroy the WebContents before starting the request. | 
 |  569   web_contents_.reset(); | 
|  428  |  570  | 
|  429   // Plug in test content browser client. |  571   // Plug in test content browser client. | 
|  430   SelectCertificateBrowserClient test_client; |  572   SelectCertificateBrowserClient test_client; | 
|  431   ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |  573   ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 
|  432  |  574  | 
|  433   // Everything is set up. Trigger the resource loader certificate request event |  575   // Start the request and wait for it to pause. | 
|  434   // and run the message loop. |  576   loader_->StartRequest(); | 
|  435   loader_->OnCertificateRequested(raw_ptr_to_request_, cert_request_info.get()); |  | 
|  436   base::RunLoop().RunUntilIdle(); |  577   base::RunLoop().RunUntilIdle(); | 
|  437  |  578  | 
 |  579   // Check that SelectClientCertificate wasn't called and the request aborted. | 
 |  580   EXPECT_EQ(0, test_client.call_count()); | 
 |  581   EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); | 
 |  582   EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, | 
 |  583             raw_ptr_resource_handler_->status().error()); | 
 |  584  | 
|  438   // Restore the original content browser client. |  585   // Restore the original content browser client. | 
|  439   SetBrowserClientForTesting(old_client); |  586   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 } |  587 } | 
|  446  |  588  | 
|  447 TEST_F(ResourceLoaderTest, ClientCertStoreAsyncCancel) { |  589 // Verifies that ClientCertStore's callback doesn't crash if called after the | 
|  448   // Set up the test client cert store. |  590 // loader is destroyed. | 
|  449   int store_request_count; |  591 TEST_F(ClientCertResourceLoaderTest, StoreAsyncCancel) { | 
|  450   std::vector<std::string> store_requested_authorities; |  592   scoped_ptr<LoaderDestroyingCertStore> test_store( | 
|  451   scoped_ptr<ClientCertStoreStub> test_store( |  593       new LoaderDestroyingCertStore(&loader_)); | 
|  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()); |  594   resource_context_.SetClientCertStore(test_store.Pass()); | 
|  457  |  595  | 
|  458   // Prepare a dummy certificate request. |  596   loader_->StartRequest(); | 
|  459   scoped_refptr<net::SSLCertRequestInfo> cert_request_info( |  597   base::RunLoop().RunUntilIdle(); | 
|  460       new net::SSLCertRequestInfo()); |  598   EXPECT_FALSE(loader_); | 
|  461   std::vector<std::string> dummy_authority(1, "dummy"); |  | 
|  462   cert_request_info->cert_authorities = dummy_authority; |  | 
|  463  |  599  | 
|  464   // Everything is set up. Trigger the resource loader certificate request |  600   // 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(); |  601   base::RunLoop().RunUntilIdle(); | 
|  477 } |  602 } | 
|  478  |  603  | 
|  479 TEST_F(ResourceLoaderTest, ResumeCancelledRequest) { |  604 TEST_F(ResourceLoaderTest, ResumeCancelledRequest) { | 
|  480   raw_ptr_resource_handler_->set_defer_request_on_will_start(true); |  605   raw_ptr_resource_handler_->set_defer_request_on_will_start(true); | 
|  481  |  606  | 
|  482   loader_->StartRequest(); |  607   loader_->StartRequest(); | 
|  483   loader_->CancelRequest(true); |  608   loader_->CancelRequest(true); | 
|  484   static_cast<ResourceController*>(loader_.get())->Resume(); |  609   static_cast<ResourceController*>(loader_.get())->Resume(); | 
|  485 } |  610 } | 
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  760   ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); |  885   ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); | 
|  761   EXPECT_EQ(test_data(), contents); |  886   EXPECT_EQ(test_data(), contents); | 
|  762  |  887  | 
|  763   // Release the loader. The file should be gone now. |  888   // Release the loader. The file should be gone now. | 
|  764   ReleaseLoader(); |  889   ReleaseLoader(); | 
|  765   base::RunLoop().RunUntilIdle(); |  890   base::RunLoop().RunUntilIdle(); | 
|  766   EXPECT_FALSE(base::PathExists(temp_path())); |  891   EXPECT_FALSE(base::PathExists(temp_path())); | 
|  767 } |  892 } | 
|  768  |  893  | 
|  769 }  // namespace content |  894 }  // namespace content | 
| OLD | NEW |