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/file_util.h" |
| 8 #include "base/message_loop/message_loop_proxy.h" |
| 9 #include "base/platform_file.h" |
7 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
8 #include "content/browser/browser_thread_impl.h" | 11 #include "content/browser/browser_thread_impl.h" |
| 12 #include "content/browser/loader/redirect_to_file_resource_handler.h" |
9 #include "content/browser/loader/resource_loader_delegate.h" | 13 #include "content/browser/loader/resource_loader_delegate.h" |
10 #include "content/public/browser/resource_request_info.h" | 14 #include "content/public/browser/resource_request_info.h" |
| 15 #include "content/public/common/resource_response.h" |
11 #include "content/public/test/mock_resource_context.h" | 16 #include "content/public/test/mock_resource_context.h" |
12 #include "content/public/test/test_browser_thread_bundle.h" | 17 #include "content/public/test/test_browser_thread_bundle.h" |
13 #include "content/test/test_content_browser_client.h" | 18 #include "content/test/test_content_browser_client.h" |
| 19 #include "net/base/mock_file_stream.h" |
14 #include "net/base/request_priority.h" | 20 #include "net/base/request_priority.h" |
15 #include "net/cert/x509_certificate.h" | 21 #include "net/cert/x509_certificate.h" |
16 #include "net/ssl/client_cert_store.h" | 22 #include "net/ssl/client_cert_store.h" |
17 #include "net/ssl/ssl_cert_request_info.h" | 23 #include "net/ssl/ssl_cert_request_info.h" |
18 #include "net/url_request/url_request.h" | 24 #include "net/url_request/url_request.h" |
| 25 #include "net/url_request/url_request_job_factory_impl.h" |
| 26 #include "net/url_request/url_request_test_job.h" |
19 #include "net/url_request/url_request_test_util.h" | 27 #include "net/url_request/url_request_test_util.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 29 #include "webkit/common/blob/shareable_file_reference.h" |
| 30 |
| 31 using webkit_blob::ShareableFileReference; |
21 | 32 |
22 namespace content { | 33 namespace content { |
23 namespace { | 34 namespace { |
24 | 35 |
25 // Stub client certificate store that returns a preset list of certificates for | 36 // 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 | 37 // each request and records the arguments of the most recent request for later |
27 // inspection. | 38 // inspection. |
28 class ClientCertStoreStub : public net::ClientCertStore { | 39 class ClientCertStoreStub : public net::ClientCertStore { |
29 public: | 40 public: |
30 ClientCertStoreStub(const net::CertificateList& certs) | 41 ClientCertStoreStub(const net::CertificateList& certs) |
(...skipping 30 matching lines...) Expand all Loading... |
61 private: | 72 private: |
62 const net::CertificateList response_; | 73 const net::CertificateList response_; |
63 int request_count_; | 74 int request_count_; |
64 std::vector<std::string> requested_authorities_; | 75 std::vector<std::string> requested_authorities_; |
65 }; | 76 }; |
66 | 77 |
67 // Dummy implementation of ResourceHandler, instance of which is needed to | 78 // Dummy implementation of ResourceHandler, instance of which is needed to |
68 // initialize ResourceLoader. | 79 // initialize ResourceLoader. |
69 class ResourceHandlerStub : public ResourceHandler { | 80 class ResourceHandlerStub : public ResourceHandler { |
70 public: | 81 public: |
71 ResourceHandlerStub() : ResourceHandler(NULL) {} | 82 explicit ResourceHandlerStub(net::URLRequest* request) |
| 83 : ResourceHandler(request), |
| 84 defer_start_(false), |
| 85 received_response_completed_(false), |
| 86 total_bytes_downloaded_(0) { |
| 87 } |
72 | 88 |
| 89 void set_defer_start(bool defer_start) { defer_start_ = defer_start; } |
| 90 |
| 91 const GURL& start_url() const { return start_url_; } |
| 92 ResourceResponse* response() const { return response_.get(); } |
| 93 bool received_response_completed() const { |
| 94 return received_response_completed_; |
| 95 } |
| 96 const net::URLRequestStatus& status() const { return status_; } |
| 97 int total_bytes_downloaded() const { return total_bytes_downloaded_; } |
| 98 |
| 99 void Resume() { |
| 100 controller()->Resume(); |
| 101 } |
| 102 |
| 103 // ResourceHandler implementation: |
73 virtual bool OnUploadProgress(int request_id, | 104 virtual bool OnUploadProgress(int request_id, |
74 uint64 position, | 105 uint64 position, |
75 uint64 size) OVERRIDE { | 106 uint64 size) OVERRIDE { |
| 107 NOTREACHED(); |
76 return true; | 108 return true; |
77 } | 109 } |
78 | 110 |
79 virtual bool OnRequestRedirected(int request_id, | 111 virtual bool OnRequestRedirected(int request_id, |
80 const GURL& url, | 112 const GURL& url, |
81 ResourceResponse* response, | 113 ResourceResponse* response, |
82 bool* defer) OVERRIDE { | 114 bool* defer) OVERRIDE { |
| 115 NOTREACHED(); |
83 return true; | 116 return true; |
84 } | 117 } |
85 | 118 |
86 virtual bool OnResponseStarted(int request_id, | 119 virtual bool OnResponseStarted(int request_id, |
87 ResourceResponse* response, | 120 ResourceResponse* response, |
88 bool* defer) OVERRIDE { return true; } | 121 bool* defer) OVERRIDE { |
| 122 EXPECT_FALSE(response_); |
| 123 response_ = response; |
| 124 return true; |
| 125 } |
89 | 126 |
90 virtual bool OnWillStart(int request_id, | 127 virtual bool OnWillStart(int request_id, |
91 const GURL& url, | 128 const GURL& url, |
92 bool* defer) OVERRIDE { | 129 bool* defer) OVERRIDE { |
| 130 EXPECT_TRUE(start_url_.is_empty()); |
| 131 start_url_ = url; |
| 132 *defer = defer_start_; |
93 return true; | 133 return true; |
94 } | 134 } |
95 | 135 |
96 virtual bool OnWillRead(int request_id, | 136 virtual bool OnWillRead(int request_id, |
97 scoped_refptr<net::IOBuffer>* buf, | 137 scoped_refptr<net::IOBuffer>* buf, |
98 int* buf_size, | 138 int* buf_size, |
99 int min_size) OVERRIDE { | 139 int min_size) OVERRIDE { |
100 return true; | 140 NOTREACHED(); |
| 141 return false; |
101 } | 142 } |
102 | 143 |
103 virtual bool OnReadCompleted(int request_id, | 144 virtual bool OnReadCompleted(int request_id, |
104 int bytes_read, | 145 int bytes_read, |
105 bool* defer) OVERRIDE { | 146 bool* defer) OVERRIDE { |
106 return true; | 147 NOTREACHED(); |
| 148 return false; |
107 } | 149 } |
108 | 150 |
109 virtual void OnResponseCompleted(int request_id, | 151 virtual void OnResponseCompleted(int request_id, |
110 const net::URLRequestStatus& status, | 152 const net::URLRequestStatus& status, |
111 const std::string& security_info, | 153 const std::string& security_info, |
112 bool* defer) OVERRIDE { | 154 bool* defer) OVERRIDE { |
| 155 // TODO(davidben): This DCHECK currently fires everywhere. Fix the places in |
| 156 // ResourceLoader where OnResponseCompleted is signaled twice. |
| 157 // DCHECK(!received_response_completed_); |
| 158 received_response_completed_ = true; |
| 159 status_ = status; |
113 } | 160 } |
114 | 161 |
115 virtual void OnDataDownloaded(int request_id, | 162 virtual void OnDataDownloaded(int request_id, |
116 int bytes_downloaded) OVERRIDE {} | 163 int bytes_downloaded) OVERRIDE { |
| 164 total_bytes_downloaded_ += bytes_downloaded; |
| 165 } |
| 166 |
| 167 private: |
| 168 bool defer_start_; |
| 169 GURL start_url_; |
| 170 scoped_refptr<ResourceResponse> response_; |
| 171 bool received_response_completed_; |
| 172 net::URLRequestStatus status_; |
| 173 int total_bytes_downloaded_; |
117 }; | 174 }; |
118 | 175 |
119 // Test browser client that captures calls to SelectClientCertificates and | 176 // Test browser client that captures calls to SelectClientCertificates and |
120 // records the arguments of the most recent call for later inspection. | 177 // records the arguments of the most recent call for later inspection. |
121 class SelectCertificateBrowserClient : public TestContentBrowserClient { | 178 class SelectCertificateBrowserClient : public TestContentBrowserClient { |
122 public: | 179 public: |
123 SelectCertificateBrowserClient() : call_count_(0) {} | 180 SelectCertificateBrowserClient() : call_count_(0) {} |
124 | 181 |
125 virtual void SelectClientCertificate( | 182 virtual void SelectClientCertificate( |
126 int render_process_id, | 183 int render_process_id, |
(...skipping 28 matching lines...) Expand all Loading... |
155 } | 212 } |
156 | 213 |
157 void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) { | 214 void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) { |
158 dummy_cert_store_ = store.Pass(); | 215 dummy_cert_store_ = store.Pass(); |
159 } | 216 } |
160 | 217 |
161 private: | 218 private: |
162 scoped_ptr<net::ClientCertStore> dummy_cert_store_; | 219 scoped_ptr<net::ClientCertStore> dummy_cert_store_; |
163 }; | 220 }; |
164 | 221 |
| 222 class MockTemporaryFileManager |
| 223 : public RedirectToFileResourceHandler::Delegate { |
| 224 public: |
| 225 MockTemporaryFileManager() : error_(base::PLATFORM_FILE_OK) { |
| 226 CreateNextTemporary(); |
| 227 } |
| 228 |
| 229 net::testing::MockFileStream* next_file_stream() const { |
| 230 return next_file_stream_.get(); |
| 231 } |
| 232 ShareableFileReference* next_deletable_file() const { |
| 233 return next_deletable_file_.get(); |
| 234 } |
| 235 |
| 236 void set_next_error(base::PlatformFileError error) { |
| 237 DCHECK_EQ(base::PLATFORM_FILE_OK, error_); |
| 238 error_ = error; |
| 239 } |
| 240 |
| 241 // RedirectToFileResourceHandler::Delegate implementation: |
| 242 virtual void CreateTemporary( |
| 243 int child_id, |
| 244 int request_id, |
| 245 base::WeakPtr<RedirectToFileResourceHandler> handler) OVERRIDE { |
| 246 base::MessageLoop::current()->PostTask( |
| 247 FROM_HERE, |
| 248 base::Bind(&MockTemporaryFileManager::DoCallback, |
| 249 base::Unretained(this), handler)); |
| 250 } |
| 251 |
| 252 private: |
| 253 void CreateNextTemporary() { |
| 254 DCHECK(!next_file_stream_); |
| 255 |
| 256 base::FilePath file_path; |
| 257 ASSERT_TRUE(base::CreateTemporaryFile(&file_path)); |
| 258 base::PlatformFile platform_file = |
| 259 base::CreatePlatformFile(file_path, |
| 260 base::PLATFORM_FILE_WRITE | |
| 261 base::PLATFORM_FILE_TEMPORARY | |
| 262 base::PLATFORM_FILE_CREATE_ALWAYS | |
| 263 base::PLATFORM_FILE_ASYNC, |
| 264 NULL, NULL); |
| 265 ASSERT_NE(base::kInvalidPlatformFileValue, platform_file); |
| 266 next_file_stream_.reset( |
| 267 new net::testing::MockFileStream( |
| 268 platform_file, |
| 269 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC, |
| 270 NULL, base::MessageLoopProxy::current())); |
| 271 next_deletable_file_ = |
| 272 ShareableFileReference::GetOrCreate( |
| 273 file_path, |
| 274 ShareableFileReference::DELETE_ON_FINAL_RELEASE, |
| 275 BrowserThread::GetMessageLoopProxyForThread( |
| 276 BrowserThread::FILE).get()); |
| 277 } |
| 278 |
| 279 void DoCallback(base::WeakPtr<RedirectToFileResourceHandler> handler) { |
| 280 if (!handler) |
| 281 return; |
| 282 |
| 283 if (error_ != base::PLATFORM_FILE_OK) { |
| 284 handler->DidCreateTemporaryFile( |
| 285 error_, scoped_ptr<net::FileStream>(), NULL); |
| 286 error_ = base::PLATFORM_FILE_OK; |
| 287 } else { |
| 288 DCHECK(next_file_stream_); |
| 289 handler->DidCreateTemporaryFile( |
| 290 base::PLATFORM_FILE_OK, |
| 291 next_file_stream_.PassAs<net::FileStream>(), |
| 292 next_deletable_file_.get()); |
| 293 next_deletable_file_ = NULL; |
| 294 } |
| 295 } |
| 296 |
| 297 base::PlatformFileError error_; |
| 298 scoped_ptr<net::testing::MockFileStream> next_file_stream_; |
| 299 scoped_refptr<ShareableFileReference> next_deletable_file_; |
| 300 }; |
| 301 |
165 } // namespace | 302 } // namespace |
166 | 303 |
167 class ResourceLoaderTest : public testing::Test, | 304 class ResourceLoaderTest : public testing::Test, |
168 public ResourceLoaderDelegate { | 305 public ResourceLoaderDelegate { |
169 protected: | 306 protected: |
170 ResourceLoaderTest() | 307 ResourceLoaderTest() |
171 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | 308 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
172 resource_context_(&test_url_request_context_) { | 309 resource_context_(&test_url_request_context_) { |
| 310 job_factory_.SetProtocolHandler( |
| 311 "test", net::URLRequestTestJob::CreateProtocolHandler()); |
| 312 test_url_request_context_.set_job_factory(&job_factory_); |
| 313 } |
| 314 |
| 315 scoped_ptr<net::URLRequest> CreateTestRequest(const GURL& url) { |
| 316 const int kRenderProcessId = 1; |
| 317 const int kRenderViewId = 2; |
| 318 |
| 319 scoped_ptr<net::URLRequest> request( |
| 320 new net::URLRequest(url, net::DEFAULT_PRIORITY, NULL, |
| 321 resource_context_.GetRequestContext())); |
| 322 ResourceRequestInfo::AllocateForTesting(request.get(), |
| 323 ResourceType::MAIN_FRAME, |
| 324 &resource_context_, |
| 325 kRenderProcessId, |
| 326 kRenderViewId, |
| 327 false); |
| 328 return request.Pass(); |
173 } | 329 } |
174 | 330 |
175 // ResourceLoaderDelegate: | 331 // ResourceLoaderDelegate: |
176 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( | 332 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( |
177 ResourceLoader* loader, | 333 ResourceLoader* loader, |
178 net::AuthChallengeInfo* auth_info) OVERRIDE { | 334 net::AuthChallengeInfo* auth_info) OVERRIDE { |
179 return NULL; | 335 return NULL; |
180 } | 336 } |
181 virtual bool AcceptAuthRequest( | 337 virtual bool AcceptAuthRequest( |
182 ResourceLoader* loader, | 338 ResourceLoader* loader, |
(...skipping 10 matching lines...) Expand all Loading... |
193 return false; | 349 return false; |
194 } | 350 } |
195 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {} | 351 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {} |
196 virtual void DidReceiveRedirect(ResourceLoader* loader, | 352 virtual void DidReceiveRedirect(ResourceLoader* loader, |
197 const GURL& new_url) OVERRIDE {} | 353 const GURL& new_url) OVERRIDE {} |
198 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {} | 354 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {} |
199 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {} | 355 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {} |
200 | 356 |
201 content::TestBrowserThreadBundle thread_bundle_; | 357 content::TestBrowserThreadBundle thread_bundle_; |
202 | 358 |
| 359 net::URLRequestJobFactoryImpl job_factory_; |
203 net::TestURLRequestContext test_url_request_context_; | 360 net::TestURLRequestContext test_url_request_context_; |
204 ResourceContextStub resource_context_; | 361 ResourceContextStub resource_context_; |
205 }; | 362 }; |
206 | 363 |
207 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested() | 364 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested() |
208 // causes client cert store to be queried for certificates and if the returned | 365 // causes client cert store to be queried for certificates and if the returned |
209 // certificates are correctly passed to the content browser client for | 366 // certificates are correctly passed to the content browser client for |
210 // selection. | 367 // selection. |
211 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) { | 368 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) { |
212 const int kRenderProcessId = 1; | 369 scoped_ptr<net::URLRequest> request = CreateTestRequest(GURL("dummy")); |
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 | 370 |
227 // Set up the test client cert store. | 371 // Set up the test client cert store. |
228 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( | 372 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( |
229 new net::X509Certificate("test", "test", base::Time(), base::Time()))); | 373 new net::X509Certificate("test", "test", base::Time(), base::Time()))); |
230 scoped_ptr<ClientCertStoreStub> test_store( | 374 scoped_ptr<ClientCertStoreStub> test_store( |
231 new ClientCertStoreStub(dummy_certs)); | 375 new ClientCertStoreStub(dummy_certs)); |
232 EXPECT_EQ(0, test_store->request_count()); | 376 EXPECT_EQ(0, test_store->request_count()); |
233 | 377 |
234 // Ownership of the |request| and |test_store| is about to be turned over to | 378 // 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 | 379 // ResourceLoader. We need to keep raw pointer copies to access these objects |
236 // later. | 380 // later. |
237 net::URLRequest* raw_ptr_to_request = request.get(); | 381 net::URLRequest* raw_ptr_to_request = request.get(); |
238 ClientCertStoreStub* raw_ptr_to_store = test_store.get(); | 382 ClientCertStoreStub* raw_ptr_to_store = test_store.get(); |
239 resource_context_.SetClientCertStore( | 383 resource_context_.SetClientCertStore( |
240 test_store.PassAs<net::ClientCertStore>()); | 384 test_store.PassAs<net::ClientCertStore>()); |
241 | 385 |
242 scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub()); | 386 scoped_ptr<ResourceHandler> resource_handler( |
| 387 new ResourceHandlerStub(request.get())); |
243 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this); | 388 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this); |
244 | 389 |
245 // Prepare a dummy certificate request. | 390 // Prepare a dummy certificate request. |
246 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | 391 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( |
247 new net::SSLCertRequestInfo()); | 392 new net::SSLCertRequestInfo()); |
248 std::vector<std::string> dummy_authority(1, "dummy"); | 393 std::vector<std::string> dummy_authority(1, "dummy"); |
249 cert_request_info->cert_authorities = dummy_authority; | 394 cert_request_info->cert_authorities = dummy_authority; |
250 | 395 |
251 // Plug in test content browser client. | 396 // Plug in test content browser client. |
252 SelectCertificateBrowserClient test_client; | 397 SelectCertificateBrowserClient test_client; |
(...skipping 14 matching lines...) Expand all Loading... |
267 // Check if the retrieved certificates were passed to the content browser | 412 // Check if the retrieved certificates were passed to the content browser |
268 // client. | 413 // client. |
269 EXPECT_EQ(1, test_client.call_count()); | 414 EXPECT_EQ(1, test_client.call_count()); |
270 EXPECT_EQ(dummy_certs, test_client.passed_certs()); | 415 EXPECT_EQ(dummy_certs, test_client.passed_certs()); |
271 } | 416 } |
272 | 417 |
273 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested() | 418 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested() |
274 // on a platform with a NULL client cert store still calls the content browser | 419 // on a platform with a NULL client cert store still calls the content browser |
275 // client for selection. | 420 // client for selection. |
276 TEST_F(ResourceLoaderTest, ClientCertStoreNull) { | 421 TEST_F(ResourceLoaderTest, ClientCertStoreNull) { |
277 const int kRenderProcessId = 1; | 422 scoped_ptr<net::URLRequest> request = CreateTestRequest(GURL("dummy")); |
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 | 423 |
292 // Ownership of the |request| is about to be turned over to ResourceLoader. We | 424 // 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. | 425 // need to keep a raw pointer copy to access this object later. |
294 net::URLRequest* raw_ptr_to_request = request.get(); | 426 net::URLRequest* raw_ptr_to_request = request.get(); |
295 | 427 |
296 scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub()); | 428 scoped_ptr<ResourceHandler> resource_handler( |
| 429 new ResourceHandlerStub(request.get())); |
297 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this); | 430 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this); |
298 | 431 |
299 // Prepare a dummy certificate request. | 432 // Prepare a dummy certificate request. |
300 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | 433 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( |
301 new net::SSLCertRequestInfo()); | 434 new net::SSLCertRequestInfo()); |
302 std::vector<std::string> dummy_authority(1, "dummy"); | 435 std::vector<std::string> dummy_authority(1, "dummy"); |
303 cert_request_info->cert_authorities = dummy_authority; | 436 cert_request_info->cert_authorities = dummy_authority; |
304 | 437 |
305 // Plug in test content browser client. | 438 // Plug in test content browser client. |
306 SelectCertificateBrowserClient test_client; | 439 SelectCertificateBrowserClient test_client; |
307 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); | 440 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); |
308 | 441 |
309 // Everything is set up. Trigger the resource loader certificate request event | 442 // Everything is set up. Trigger the resource loader certificate request event |
310 // and run the message loop. | 443 // and run the message loop. |
311 loader.OnCertificateRequested(raw_ptr_to_request, cert_request_info.get()); | 444 loader.OnCertificateRequested(raw_ptr_to_request, cert_request_info.get()); |
312 base::RunLoop().RunUntilIdle(); | 445 base::RunLoop().RunUntilIdle(); |
313 | 446 |
314 // Restore the original content browser client. | 447 // Restore the original content browser client. |
315 SetBrowserClientForTesting(old_client); | 448 SetBrowserClientForTesting(old_client); |
316 | 449 |
317 // Check if the SelectClientCertificate was called on the content browser | 450 // Check if the SelectClientCertificate was called on the content browser |
318 // client. | 451 // client. |
319 EXPECT_EQ(1, test_client.call_count()); | 452 EXPECT_EQ(1, test_client.call_count()); |
320 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); | 453 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); |
321 } | 454 } |
322 | 455 |
| 456 // Tests that a RedirectToFileResourceHandler works and forwards everything |
| 457 // downstream. |
| 458 TEST_F(ResourceLoaderTest, RedirectToFile) { |
| 459 MockTemporaryFileManager temporary_file_manager; |
| 460 base::FilePath temp_path = |
| 461 temporary_file_manager.next_deletable_file()->path(); |
| 462 |
| 463 // Set up the request. |
| 464 scoped_ptr<net::URLRequest> request = CreateTestRequest( |
| 465 net::URLRequestTestJob::test_url_1()); |
| 466 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get()); |
| 467 scoped_ptr<ResourceHandler> resource_handler(leaf_handler); |
| 468 resource_handler.reset( |
| 469 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(), |
| 470 &temporary_file_manager)); |
| 471 scoped_ptr<ResourceLoader> loader(new ResourceLoader( |
| 472 request.Pass(), resource_handler.Pass(), this)); |
| 473 |
| 474 // Run it to completion. |
| 475 loader->StartRequest(); |
| 476 base::RunLoop().RunUntilIdle(); |
| 477 |
| 478 // Check that the handler forwarded all information to the downstream handler. |
| 479 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path); |
| 480 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url()); |
| 481 EXPECT_TRUE(leaf_handler->received_response_completed()); |
| 482 EXPECT_EQ(net::URLRequestStatus::SUCCESS, leaf_handler->status().status()); |
| 483 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), |
| 484 static_cast<size_t>(leaf_handler->total_bytes_downloaded())); |
| 485 |
| 486 // Check that the data was written to the file. |
| 487 std::string contents; |
| 488 ASSERT_TRUE(base::ReadFileToString(temp_path, &contents)); |
| 489 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents); |
| 490 |
| 491 // Release the loader. The file should be gone now. |
| 492 loader.reset(); |
| 493 base::RunLoop().RunUntilIdle(); |
| 494 EXPECT_FALSE(base::PathExists(temp_path)); |
| 495 } |
| 496 |
| 497 // Tests that RedirectToFileResourceHandler handles errors in creating the |
| 498 // temporary file. |
| 499 TEST_F(ResourceLoaderTest, RedirectToFileCreateTemporaryError) { |
| 500 MockTemporaryFileManager temporary_file_manager; |
| 501 temporary_file_manager.set_next_error(base::PLATFORM_FILE_ERROR_FAILED); |
| 502 |
| 503 // Set up the request. |
| 504 scoped_ptr<net::URLRequest> request = CreateTestRequest( |
| 505 net::URLRequestTestJob::test_url_1()); |
| 506 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get()); |
| 507 scoped_ptr<ResourceHandler> resource_handler(leaf_handler); |
| 508 resource_handler.reset( |
| 509 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(), |
| 510 &temporary_file_manager)); |
| 511 scoped_ptr<ResourceLoader> loader(new ResourceLoader( |
| 512 request.Pass(), resource_handler.Pass(), this)); |
| 513 |
| 514 // Run it to completion. |
| 515 loader->StartRequest(); |
| 516 base::RunLoop().RunUntilIdle(); |
| 517 |
| 518 // To downstream, the request was canceled. |
| 519 EXPECT_TRUE(leaf_handler->received_response_completed()); |
| 520 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status()); |
| 521 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded()); |
| 522 } |
| 523 |
| 524 // Tests that RedirectToFileResourceHandler handles synchronous write errors. |
| 525 TEST_F(ResourceLoaderTest, RedirectToFileWriteError) { |
| 526 MockTemporaryFileManager temporary_file_manager; |
| 527 base::FilePath temp_path = |
| 528 temporary_file_manager.next_deletable_file()->path(); |
| 529 net::testing::MockFileStream* mock_file_stream = |
| 530 temporary_file_manager.next_file_stream(); |
| 531 mock_file_stream->set_forced_error(net::ERR_FAILED); |
| 532 |
| 533 // Set up the request. |
| 534 scoped_ptr<net::URLRequest> request = CreateTestRequest( |
| 535 net::URLRequestTestJob::test_url_1()); |
| 536 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get()); |
| 537 scoped_ptr<ResourceHandler> resource_handler(leaf_handler); |
| 538 resource_handler.reset( |
| 539 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(), |
| 540 &temporary_file_manager)); |
| 541 scoped_ptr<ResourceLoader> loader(new ResourceLoader( |
| 542 request.Pass(), resource_handler.Pass(), this)); |
| 543 |
| 544 // Run it to completion. |
| 545 loader->StartRequest(); |
| 546 base::RunLoop().RunUntilIdle(); |
| 547 |
| 548 // To downstream, the request was canceled sometime after it started, but |
| 549 // before any data was written. |
| 550 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path); |
| 551 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url()); |
| 552 EXPECT_TRUE(leaf_handler->received_response_completed()); |
| 553 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status()); |
| 554 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded()); |
| 555 } |
| 556 |
| 557 // Tests that RedirectToFileResourceHandler handles asynchronous write errors. |
| 558 TEST_F(ResourceLoaderTest, RedirectToFileWriteErrorAsync) { |
| 559 MockTemporaryFileManager temporary_file_manager; |
| 560 base::FilePath temp_path = |
| 561 temporary_file_manager.next_deletable_file()->path(); |
| 562 net::testing::MockFileStream* mock_file_stream = |
| 563 temporary_file_manager.next_file_stream(); |
| 564 mock_file_stream->set_forced_error_async(net::ERR_FAILED); |
| 565 |
| 566 // Set up the request. |
| 567 scoped_ptr<net::URLRequest> request = CreateTestRequest( |
| 568 net::URLRequestTestJob::test_url_1()); |
| 569 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get()); |
| 570 scoped_ptr<ResourceHandler> resource_handler(leaf_handler); |
| 571 resource_handler.reset( |
| 572 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(), |
| 573 &temporary_file_manager)); |
| 574 scoped_ptr<ResourceLoader> loader(new ResourceLoader( |
| 575 request.Pass(), resource_handler.Pass(), this)); |
| 576 |
| 577 // Run it to completion. |
| 578 loader->StartRequest(); |
| 579 base::RunLoop().RunUntilIdle(); |
| 580 |
| 581 // To downstream, the request was canceled sometime after it started, but |
| 582 // before any data was written. |
| 583 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path); |
| 584 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url()); |
| 585 EXPECT_TRUE(leaf_handler->received_response_completed()); |
| 586 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status()); |
| 587 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded()); |
| 588 } |
| 589 |
| 590 // Tests that RedirectToFileHandler defers completion if there are outstanding |
| 591 // writes and accounts for errors which occur in that time. |
| 592 TEST_F(ResourceLoaderTest, RedirectToFileDeferCompletion) { |
| 593 // Program the MockFileStream to error asynchronously, but throttle the |
| 594 // callback. |
| 595 MockTemporaryFileManager temporary_file_manager; |
| 596 base::FilePath temp_path = |
| 597 temporary_file_manager.next_deletable_file()->path(); |
| 598 net::testing::MockFileStream* mock_file_stream = |
| 599 temporary_file_manager.next_file_stream(); |
| 600 mock_file_stream->set_forced_error_async(net::ERR_FAILED); |
| 601 mock_file_stream->ThrottleCallbacks(); |
| 602 |
| 603 // Set up the request. |
| 604 scoped_ptr<net::URLRequest> request = CreateTestRequest( |
| 605 net::URLRequestTestJob::test_url_1()); |
| 606 net::URLRequest* raw_ptr_to_request = request.get(); |
| 607 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get()); |
| 608 scoped_ptr<ResourceHandler> resource_handler(leaf_handler); |
| 609 resource_handler.reset( |
| 610 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(), |
| 611 &temporary_file_manager)); |
| 612 scoped_ptr<ResourceLoader> loader(new ResourceLoader( |
| 613 request.Pass(), resource_handler.Pass(), this)); |
| 614 |
| 615 // Run it as far as it will go. |
| 616 loader->StartRequest(); |
| 617 base::RunLoop().RunUntilIdle(); |
| 618 |
| 619 // At this point, the request should have completed. |
| 620 EXPECT_EQ(net::URLRequestStatus::SUCCESS, |
| 621 raw_ptr_to_request->status().status()); |
| 622 |
| 623 // However, the resource loader stack is stuck somewhere after receiving the |
| 624 // response. |
| 625 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path); |
| 626 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url()); |
| 627 EXPECT_FALSE(leaf_handler->received_response_completed()); |
| 628 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded()); |
| 629 |
| 630 // Now, release the floodgates. |
| 631 mock_file_stream->ReleaseCallbacks(); |
| 632 base::RunLoop().RunUntilIdle(); |
| 633 |
| 634 // Although the URLRequest was successful, the leaf handler sees a failure |
| 635 // because the write never completed. |
| 636 EXPECT_TRUE(leaf_handler->received_response_completed()); |
| 637 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status()); |
| 638 } |
| 639 |
| 640 // Tests that a RedirectToFileResourceHandler behaves properly when the |
| 641 // downstream handler defers OnWillStart. |
| 642 TEST_F(ResourceLoaderTest, RedirectToFileDownstreamDeferStart) { |
| 643 MockTemporaryFileManager temporary_file_manager; |
| 644 base::FilePath temp_path = |
| 645 temporary_file_manager.next_deletable_file()->path(); |
| 646 |
| 647 // Set up the request. |
| 648 scoped_ptr<net::URLRequest> request = CreateTestRequest( |
| 649 net::URLRequestTestJob::test_url_1()); |
| 650 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get()); |
| 651 scoped_ptr<ResourceHandler> resource_handler(leaf_handler); |
| 652 resource_handler.reset( |
| 653 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(), |
| 654 &temporary_file_manager)); |
| 655 scoped_ptr<ResourceLoader> loader(new ResourceLoader( |
| 656 request.Pass(), resource_handler.Pass(), this)); |
| 657 |
| 658 // Defer OnWillStart. |
| 659 leaf_handler->set_defer_start(true); |
| 660 |
| 661 // Run as far as we'll go. |
| 662 loader->StartRequest(); |
| 663 base::RunLoop().RunUntilIdle(); |
| 664 |
| 665 // The request should have stopped at OnWillStart. |
| 666 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url()); |
| 667 EXPECT_FALSE(leaf_handler->response()); |
| 668 EXPECT_FALSE(leaf_handler->received_response_completed()); |
| 669 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded()); |
| 670 |
| 671 // Now resume the request. Now we complete. |
| 672 leaf_handler->Resume(); |
| 673 base::RunLoop().RunUntilIdle(); |
| 674 |
| 675 // Check that the handler forwarded all information to the downstream handler. |
| 676 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path); |
| 677 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url()); |
| 678 EXPECT_TRUE(leaf_handler->received_response_completed()); |
| 679 EXPECT_EQ(net::URLRequestStatus::SUCCESS, leaf_handler->status().status()); |
| 680 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), |
| 681 static_cast<size_t>(leaf_handler->total_bytes_downloaded())); |
| 682 |
| 683 // Check that the data was written to the file. |
| 684 std::string contents; |
| 685 ASSERT_TRUE(base::ReadFileToString(temp_path, &contents)); |
| 686 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents); |
| 687 |
| 688 // Release the loader. The file should be gone now. |
| 689 loader.reset(); |
| 690 base::RunLoop().RunUntilIdle(); |
| 691 EXPECT_FALSE(base::PathExists(temp_path)); |
| 692 } |
| 693 |
323 } // namespace content | 694 } // namespace content |
OLD | NEW |