- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / loader / resource_loader_unittest.cc
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
3 // found in the LICENSE file.
4
5 #include "content/browser/loader/resource_loader.h"
6
7 #include "base/run_loop.h"
8 #include "content/browser/browser_thread_impl.h"
9 #include "content/browser/loader/resource_loader_delegate.h"
10 #include "content/public/browser/resource_request_info.h"
11 #include "content/public/test/mock_resource_context.h"
12 #include "content/public/test/test_browser_thread_bundle.h"
13 #include "content/test/test_content_browser_client.h"
14 #include "net/base/request_priority.h"
15 #include "net/cert/x509_certificate.h"
16 #include "net/ssl/client_cert_store.h"
17 #include "net/ssl/ssl_cert_request_info.h"
18 #include "net/url_request/url_request.h"
19 #include "net/url_request/url_request_test_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace content {
23 namespace {
24
25 // Stub client certificate store that returns a preset list of certificates for
26 // each request and records the arguments of the most recent request for later
27 // inspection.
28 class ClientCertStoreStub : public net::ClientCertStore {
29  public:
30   ClientCertStoreStub(const net::CertificateList& certs)
31       : response_(certs),
32         request_count_(0) {}
33
34   virtual ~ClientCertStoreStub() {}
35
36   // Returns |cert_authorities| field of the certificate request passed in the
37   // most recent call to GetClientCerts().
38   // TODO(ppi): Make the stub independent from the internal representation of
39   // SSLCertRequestInfo. For now it seems that we cannot neither save the
40   // scoped_refptr<> (since it is never passed to us) nor copy the entire
41   // CertificateRequestInfo (since there is no copy constructor).
42   std::vector<std::string> requested_authorities() {
43     return requested_authorities_;
44   }
45
46   // Returns the number of calls to GetClientCerts().
47   int request_count() {
48     return request_count_;
49   }
50
51   // net::ClientCertStore:
52   virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
53                               net::CertificateList* selected_certs,
54                               const base::Closure& callback) OVERRIDE {
55     ++request_count_;
56     requested_authorities_ = cert_request_info.cert_authorities;
57     *selected_certs = response_;
58     callback.Run();
59   }
60
61  private:
62   const net::CertificateList response_;
63   int request_count_;
64   std::vector<std::string> requested_authorities_;
65 };
66
67 // Dummy implementation of ResourceHandler, instance of which is needed to
68 // initialize ResourceLoader.
69 class ResourceHandlerStub : public ResourceHandler {
70  public:
71   ResourceHandlerStub() : ResourceHandler(NULL) {}
72
73   virtual bool OnUploadProgress(int request_id,
74                                 uint64 position,
75                                 uint64 size) OVERRIDE {
76     return true;
77   }
78
79   virtual bool OnRequestRedirected(int request_id,
80                                    const GURL& url,
81                                    ResourceResponse* response,
82                                    bool* defer) OVERRIDE {
83     return true;
84   }
85
86   virtual bool OnResponseStarted(int request_id,
87                                  ResourceResponse* response,
88                                  bool* defer) OVERRIDE { return true; }
89
90   virtual bool OnWillStart(int request_id,
91                            const GURL& url,
92                            bool* defer) OVERRIDE {
93     return true;
94   }
95
96   virtual bool OnWillRead(int request_id,
97                           scoped_refptr<net::IOBuffer>* buf,
98                           int* buf_size,
99                           int min_size) OVERRIDE {
100     return true;
101   }
102
103   virtual bool OnReadCompleted(int request_id,
104                                int bytes_read,
105                                bool* defer) OVERRIDE {
106     return true;
107   }
108
109   virtual bool OnResponseCompleted(int request_id,
110                                    const net::URLRequestStatus& status,
111                                    const std::string& security_info) OVERRIDE {
112     return true;
113   }
114
115   virtual void OnDataDownloaded(int request_id,
116                                 int bytes_downloaded) OVERRIDE {}
117 };
118
119 // Test browser client that captures calls to SelectClientCertificates and
120 // records the arguments of the most recent call for later inspection.
121 class SelectCertificateBrowserClient : public TestContentBrowserClient {
122  public:
123   SelectCertificateBrowserClient() : call_count_(0) {}
124
125   virtual void SelectClientCertificate(
126       int render_process_id,
127       int render_view_id,
128       const net::HttpNetworkSession* network_session,
129       net::SSLCertRequestInfo* cert_request_info,
130       const base::Callback<void(net::X509Certificate*)>& callback) OVERRIDE {
131     ++call_count_;
132     passed_certs_ = cert_request_info->client_certs;
133   }
134
135   int call_count() {
136     return call_count_;
137   }
138
139   net::CertificateList passed_certs() {
140     return passed_certs_;
141   }
142
143  private:
144   net::CertificateList passed_certs_;
145   int call_count_;
146 };
147
148 class ResourceContextStub : public MockResourceContext {
149  public:
150   explicit ResourceContextStub(net::URLRequestContext* test_request_context)
151       : MockResourceContext(test_request_context) {}
152
153   virtual scoped_ptr<net::ClientCertStore> CreateClientCertStore() OVERRIDE {
154     return dummy_cert_store_.Pass();
155   }
156
157   void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) {
158     dummy_cert_store_ = store.Pass();
159   }
160
161  private:
162   scoped_ptr<net::ClientCertStore> dummy_cert_store_;
163 };
164
165 }  // namespace
166
167 class ResourceLoaderTest : public testing::Test,
168                            public ResourceLoaderDelegate {
169  protected:
170   ResourceLoaderTest()
171     : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
172       resource_context_(&test_url_request_context_) {
173   }
174
175   // ResourceLoaderDelegate:
176   virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
177       ResourceLoader* loader,
178       net::AuthChallengeInfo* auth_info) OVERRIDE {
179     return NULL;
180   }
181   virtual bool AcceptAuthRequest(
182       ResourceLoader* loader,
183       net::AuthChallengeInfo* auth_info) OVERRIDE {
184     return false;
185   };
186   virtual bool AcceptSSLClientCertificateRequest(
187       ResourceLoader* loader,
188       net::SSLCertRequestInfo* cert_info) OVERRIDE {
189     return true;
190   }
191   virtual bool HandleExternalProtocol(ResourceLoader* loader,
192                                       const GURL& url) OVERRIDE {
193     return false;
194   }
195   virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {}
196   virtual void DidReceiveRedirect(ResourceLoader* loader,
197                                   const GURL& new_url) OVERRIDE {}
198   virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {}
199   virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {}
200
201   content::TestBrowserThreadBundle thread_bundle_;
202
203   net::TestURLRequestContext test_url_request_context_;
204   ResourceContextStub resource_context_;
205 };
206
207 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested()
208 // causes client cert store to be queried for certificates and if the returned
209 // certificates are correctly passed to the content browser client for
210 // selection.
211 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) {
212   const int kRenderProcessId = 1;
213   const int kRenderViewId = 2;
214
215   scoped_ptr<net::URLRequest> request(
216       new net::URLRequest(GURL("dummy"),
217                           net::DEFAULT_PRIORITY,
218                           NULL,
219                           resource_context_.GetRequestContext()));
220   ResourceRequestInfo::AllocateForTesting(request.get(),
221                                           ResourceType::MAIN_FRAME,
222                                           &resource_context_,
223                                           kRenderProcessId,
224                                           kRenderViewId,
225                                           false);
226
227   // Set up the test client cert store.
228   net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>(
229       new net::X509Certificate("test", "test", base::Time(), base::Time())));
230   scoped_ptr<ClientCertStoreStub> test_store(
231       new ClientCertStoreStub(dummy_certs));
232   EXPECT_EQ(0, test_store->request_count());
233
234   // Ownership of the |request| and |test_store| is about to be turned over to
235   // ResourceLoader. We need to keep raw pointer copies to access these objects
236   // later.
237   net::URLRequest* raw_ptr_to_request = request.get();
238   ClientCertStoreStub* raw_ptr_to_store = test_store.get();
239   resource_context_.SetClientCertStore(
240       test_store.PassAs<net::ClientCertStore>());
241
242   scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub());
243   ResourceLoader loader(request.Pass(), resource_handler.Pass(), this);
244
245   // Prepare a dummy certificate request.
246   scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
247       new net::SSLCertRequestInfo());
248   std::vector<std::string> dummy_authority(1, "dummy");
249   cert_request_info->cert_authorities = dummy_authority;
250
251   // Plug in test content browser client.
252   SelectCertificateBrowserClient test_client;
253   ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client);
254
255   // Everything is set up. Trigger the resource loader certificate request event
256   // and run the message loop.
257   loader.OnCertificateRequested(raw_ptr_to_request, cert_request_info.get());
258   base::RunLoop().RunUntilIdle();
259
260   // Restore the original content browser client.
261   SetBrowserClientForTesting(old_client);
262
263   // Check if the test store was queried against correct |cert_authorities|.
264   EXPECT_EQ(1, raw_ptr_to_store->request_count());
265   EXPECT_EQ(dummy_authority, raw_ptr_to_store->requested_authorities());
266
267   // Check if the retrieved certificates were passed to the content browser
268   // client.
269   EXPECT_EQ(1, test_client.call_count());
270   EXPECT_EQ(dummy_certs, test_client.passed_certs());
271 }
272
273 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested()
274 // on a platform with a NULL client cert store still calls the content browser
275 // client for selection.
276 TEST_F(ResourceLoaderTest, ClientCertStoreNull) {
277   const int kRenderProcessId = 1;
278   const int kRenderViewId = 2;
279
280   scoped_ptr<net::URLRequest> request(
281       new net::URLRequest(GURL("dummy"),
282                           net::DEFAULT_PRIORITY,
283                           NULL,
284                           resource_context_.GetRequestContext()));
285   ResourceRequestInfo::AllocateForTesting(request.get(),
286                                           ResourceType::MAIN_FRAME,
287                                           &resource_context_,
288                                           kRenderProcessId,
289                                           kRenderViewId,
290                                           false);
291
292   // Ownership of the |request| is about to be turned over to ResourceLoader. We
293   // need to keep a raw pointer copy to access this object later.
294   net::URLRequest* raw_ptr_to_request = request.get();
295
296   scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub());
297   ResourceLoader loader(request.Pass(), resource_handler.Pass(), this);
298
299   // Prepare a dummy certificate request.
300   scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
301       new net::SSLCertRequestInfo());
302   std::vector<std::string> dummy_authority(1, "dummy");
303   cert_request_info->cert_authorities = dummy_authority;
304
305   // Plug in test content browser client.
306   SelectCertificateBrowserClient test_client;
307   ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client);
308
309   // Everything is set up. Trigger the resource loader certificate request event
310   // and run the message loop.
311   loader.OnCertificateRequested(raw_ptr_to_request, cert_request_info.get());
312   base::RunLoop().RunUntilIdle();
313
314   // Restore the original content browser client.
315   SetBrowserClientForTesting(old_client);
316
317   // Check if the SelectClientCertificate was called on the content browser
318   // client.
319   EXPECT_EQ(1, test_client.call_count());
320   EXPECT_EQ(net::CertificateList(), test_client.passed_certs());
321 }
322
323 }  // namespace content