Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: content/browser/loader/resource_loader_unittest.cc

Issue 82273002: Fix various issues in RedirectToFileResourceHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Various Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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_) {
173 } 310 }
174 311
312 virtual void SetUp() OVERRIDE {
313 job_factory_.SetProtocolHandler(
314 "test", net::URLRequestTestJob::CreateProtocolHandler());
315 test_url_request_context_.set_job_factory(&job_factory_);
mmenke 2013/12/05 21:34:03 Optional: Can't we just do this in the constructo
davidben 2013/12/05 22:43:20 Done.
316 }
317
318 virtual void TearDown() OVERRIDE {
319 }
mmenke 2013/12/05 21:34:03 Don't think we need this.
davidben 2013/12/05 22:43:20 Done.
320
321 scoped_ptr<net::URLRequest> CreateTestRequest(const GURL& url) {
322 const int kRenderProcessId = 1;
323 const int kRenderViewId = 2;
324
325 scoped_ptr<net::URLRequest> request(
326 new net::URLRequest(url, net::DEFAULT_PRIORITY, NULL,
327 resource_context_.GetRequestContext()));
328 ResourceRequestInfo::AllocateForTesting(request.get(),
329 ResourceType::MAIN_FRAME,
330 &resource_context_,
331 kRenderProcessId,
332 kRenderViewId,
333 false);
334 return request.Pass();
335 }
336
175 // ResourceLoaderDelegate: 337 // ResourceLoaderDelegate:
176 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( 338 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
177 ResourceLoader* loader, 339 ResourceLoader* loader,
178 net::AuthChallengeInfo* auth_info) OVERRIDE { 340 net::AuthChallengeInfo* auth_info) OVERRIDE {
179 return NULL; 341 return NULL;
180 } 342 }
181 virtual bool AcceptAuthRequest( 343 virtual bool AcceptAuthRequest(
182 ResourceLoader* loader, 344 ResourceLoader* loader,
183 net::AuthChallengeInfo* auth_info) OVERRIDE { 345 net::AuthChallengeInfo* auth_info) OVERRIDE {
184 return false; 346 return false;
185 }; 347 };
186 virtual bool AcceptSSLClientCertificateRequest( 348 virtual bool AcceptSSLClientCertificateRequest(
187 ResourceLoader* loader, 349 ResourceLoader* loader,
188 net::SSLCertRequestInfo* cert_info) OVERRIDE { 350 net::SSLCertRequestInfo* cert_info) OVERRIDE {
189 return true; 351 return true;
190 } 352 }
191 virtual bool HandleExternalProtocol(ResourceLoader* loader, 353 virtual bool HandleExternalProtocol(ResourceLoader* loader,
192 const GURL& url) OVERRIDE { 354 const GURL& url) OVERRIDE {
193 return false; 355 return false;
194 } 356 }
195 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {} 357 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {}
196 virtual void DidReceiveRedirect(ResourceLoader* loader, 358 virtual void DidReceiveRedirect(ResourceLoader* loader,
197 const GURL& new_url) OVERRIDE {} 359 const GURL& new_url) OVERRIDE {}
198 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {} 360 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {}
199 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {} 361 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {}
200 362
201 content::TestBrowserThreadBundle thread_bundle_; 363 content::TestBrowserThreadBundle thread_bundle_;
202 364
365 net::URLRequestJobFactoryImpl job_factory_;
203 net::TestURLRequestContext test_url_request_context_; 366 net::TestURLRequestContext test_url_request_context_;
204 ResourceContextStub resource_context_; 367 ResourceContextStub resource_context_;
205 }; 368 };
206 369
207 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested() 370 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested()
208 // causes client cert store to be queried for certificates and if the returned 371 // causes client cert store to be queried for certificates and if the returned
209 // certificates are correctly passed to the content browser client for 372 // certificates are correctly passed to the content browser client for
210 // selection. 373 // selection.
211 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) { 374 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) {
212 const int kRenderProcessId = 1; 375 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 376
227 // Set up the test client cert store. 377 // Set up the test client cert store.
228 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( 378 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>(
229 new net::X509Certificate("test", "test", base::Time(), base::Time()))); 379 new net::X509Certificate("test", "test", base::Time(), base::Time())));
230 scoped_ptr<ClientCertStoreStub> test_store( 380 scoped_ptr<ClientCertStoreStub> test_store(
231 new ClientCertStoreStub(dummy_certs)); 381 new ClientCertStoreStub(dummy_certs));
232 EXPECT_EQ(0, test_store->request_count()); 382 EXPECT_EQ(0, test_store->request_count());
233 383
234 // Ownership of the |request| and |test_store| is about to be turned over to 384 // 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 385 // ResourceLoader. We need to keep raw pointer copies to access these objects
236 // later. 386 // later.
237 net::URLRequest* raw_ptr_to_request = request.get(); 387 net::URLRequest* raw_ptr_to_request = request.get();
238 ClientCertStoreStub* raw_ptr_to_store = test_store.get(); 388 ClientCertStoreStub* raw_ptr_to_store = test_store.get();
239 resource_context_.SetClientCertStore( 389 resource_context_.SetClientCertStore(
240 test_store.PassAs<net::ClientCertStore>()); 390 test_store.PassAs<net::ClientCertStore>());
241 391
242 scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub()); 392 scoped_ptr<ResourceHandler> resource_handler(
393 new ResourceHandlerStub(request.get()));
243 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this); 394 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this);
244 395
245 // Prepare a dummy certificate request. 396 // Prepare a dummy certificate request.
246 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( 397 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
247 new net::SSLCertRequestInfo()); 398 new net::SSLCertRequestInfo());
248 std::vector<std::string> dummy_authority(1, "dummy"); 399 std::vector<std::string> dummy_authority(1, "dummy");
249 cert_request_info->cert_authorities = dummy_authority; 400 cert_request_info->cert_authorities = dummy_authority;
250 401
251 // Plug in test content browser client. 402 // Plug in test content browser client.
252 SelectCertificateBrowserClient test_client; 403 SelectCertificateBrowserClient test_client;
(...skipping 14 matching lines...) Expand all
267 // Check if the retrieved certificates were passed to the content browser 418 // Check if the retrieved certificates were passed to the content browser
268 // client. 419 // client.
269 EXPECT_EQ(1, test_client.call_count()); 420 EXPECT_EQ(1, test_client.call_count());
270 EXPECT_EQ(dummy_certs, test_client.passed_certs()); 421 EXPECT_EQ(dummy_certs, test_client.passed_certs());
271 } 422 }
272 423
273 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested() 424 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested()
274 // on a platform with a NULL client cert store still calls the content browser 425 // on a platform with a NULL client cert store still calls the content browser
275 // client for selection. 426 // client for selection.
276 TEST_F(ResourceLoaderTest, ClientCertStoreNull) { 427 TEST_F(ResourceLoaderTest, ClientCertStoreNull) {
277 const int kRenderProcessId = 1; 428 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 429
292 // Ownership of the |request| is about to be turned over to ResourceLoader. We 430 // 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. 431 // need to keep a raw pointer copy to access this object later.
294 net::URLRequest* raw_ptr_to_request = request.get(); 432 net::URLRequest* raw_ptr_to_request = request.get();
295 433
296 scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub()); 434 scoped_ptr<ResourceHandler> resource_handler(
435 new ResourceHandlerStub(request.get()));
297 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this); 436 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this);
298 437
299 // Prepare a dummy certificate request. 438 // Prepare a dummy certificate request.
300 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( 439 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
301 new net::SSLCertRequestInfo()); 440 new net::SSLCertRequestInfo());
302 std::vector<std::string> dummy_authority(1, "dummy"); 441 std::vector<std::string> dummy_authority(1, "dummy");
303 cert_request_info->cert_authorities = dummy_authority; 442 cert_request_info->cert_authorities = dummy_authority;
304 443
305 // Plug in test content browser client. 444 // Plug in test content browser client.
306 SelectCertificateBrowserClient test_client; 445 SelectCertificateBrowserClient test_client;
307 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); 446 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client);
308 447
309 // Everything is set up. Trigger the resource loader certificate request event 448 // Everything is set up. Trigger the resource loader certificate request event
310 // and run the message loop. 449 // and run the message loop.
311 loader.OnCertificateRequested(raw_ptr_to_request, cert_request_info.get()); 450 loader.OnCertificateRequested(raw_ptr_to_request, cert_request_info.get());
312 base::RunLoop().RunUntilIdle(); 451 base::RunLoop().RunUntilIdle();
313 452
314 // Restore the original content browser client. 453 // Restore the original content browser client.
315 SetBrowserClientForTesting(old_client); 454 SetBrowserClientForTesting(old_client);
316 455
317 // Check if the SelectClientCertificate was called on the content browser 456 // Check if the SelectClientCertificate was called on the content browser
318 // client. 457 // client.
319 EXPECT_EQ(1, test_client.call_count()); 458 EXPECT_EQ(1, test_client.call_count());
320 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); 459 EXPECT_EQ(net::CertificateList(), test_client.passed_certs());
321 } 460 }
322 461
462 // Tests that a RedirectToFileResourceHandler works and forwards everything
463 // downstream.
464 TEST_F(ResourceLoaderTest, RedirectToFile) {
465 MockTemporaryFileManager temporary_file_manager;
466 base::FilePath temp_path =
467 temporary_file_manager.next_deletable_file()->path();
468
469 // Setup the request.
470 scoped_ptr<net::URLRequest> request = CreateTestRequest(
471 net::URLRequestTestJob::test_url_1());
472 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
473 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
474 resource_handler.reset(
475 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(),
476 &temporary_file_manager));
477 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
478 request.Pass(), resource_handler.Pass(), this));
479
480 // Run it to completion.
481 loader->StartRequest();
482 base::RunLoop().RunUntilIdle();
483
484 // Check that the handler forwarded all information to the downstream handler.
485 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
486 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
487 EXPECT_TRUE(leaf_handler->received_response_completed());
488 EXPECT_EQ(net::URLRequestStatus::SUCCESS, leaf_handler->status().status());
489 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(),
490 static_cast<size_t>(leaf_handler->total_bytes_downloaded()));
491
492 // Check that the data was written to the file.
493 std::string contents;
494 ASSERT_TRUE(base::ReadFileToString(temp_path, &contents));
495 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
496
497 // Release the loader. The file should be gone now.
498 loader.reset();
499 base::RunLoop().RunUntilIdle();
500 EXPECT_FALSE(base::PathExists(temp_path));
mmenke 2013/12/05 21:34:03 Still a bit concerned about testing cleanup, and w
davidben 2013/12/05 22:43:20 Hrm? Do you mean you'd rather not assert on base::
mmenke 2013/12/05 23:00:13 No, I'm fine with that. I mean I'm not sure asser
davidben 2013/12/05 23:21:00 Ah. Yeah, it's not a terribly good test there. It
501 }
502
503 // Tests that RedirectToFileResourceHandler handles errors in creating the
504 // temporary file.
505 TEST_F(ResourceLoaderTest, RedirectToFileCreateTemporaryError) {
506 MockTemporaryFileManager temporary_file_manager;
507 temporary_file_manager.set_next_error(base::PLATFORM_FILE_ERROR_FAILED);
508
509 // Setup the request.
510 scoped_ptr<net::URLRequest> request = CreateTestRequest(
511 net::URLRequestTestJob::test_url_1());
512 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
513 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
514 resource_handler.reset(
515 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(),
516 &temporary_file_manager));
517 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
518 request.Pass(), resource_handler.Pass(), this));
519
520 // Run it to completion.
521 loader->StartRequest();
522 base::RunLoop().RunUntilIdle();
523
524 // To downstream, the request was canceled.
525 EXPECT_TRUE(leaf_handler->received_response_completed());
526 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status());
527 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
528 }
529
530 // Tests that RedirectToFileResourceHandler handles synchronous write errors.
531 TEST_F(ResourceLoaderTest, RedirectToFileWriteError) {
532 MockTemporaryFileManager temporary_file_manager;
533 base::FilePath temp_path =
534 temporary_file_manager.next_deletable_file()->path();
535 net::testing::MockFileStream* mock_file_stream =
536 temporary_file_manager.next_file_stream();
537 mock_file_stream->set_forced_error(net::ERR_FAILED);
538
539 // Setup the request.
mmenke 2013/12/05 21:34:03 nit: "setup" is a noun, "set up" is a verb.
davidben 2013/12/05 22:43:20 Done.
540 scoped_ptr<net::URLRequest> request = CreateTestRequest(
541 net::URLRequestTestJob::test_url_1());
542 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
543 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
544 resource_handler.reset(
545 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(),
546 &temporary_file_manager));
547 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
548 request.Pass(), resource_handler.Pass(), this));
549
550 // Run it to completion.
551 loader->StartRequest();
552 base::RunLoop().RunUntilIdle();
553
554 // To downstream, the request was canceled sometime after it started, but
555 // before any data was written.
556 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
557 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
558 EXPECT_TRUE(leaf_handler->received_response_completed());
559 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status());
560 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
561 }
562
563 // Tests that RedirectToFileResourceHandler handles asynchronous write errors.
564 TEST_F(ResourceLoaderTest, RedirectToFileWriteErrorAsync) {
565 MockTemporaryFileManager temporary_file_manager;
566 base::FilePath temp_path =
567 temporary_file_manager.next_deletable_file()->path();
568 net::testing::MockFileStream* mock_file_stream =
569 temporary_file_manager.next_file_stream();
570 mock_file_stream->set_forced_error_async(net::ERR_FAILED);
571
572 // Setup the request.
573 scoped_ptr<net::URLRequest> request = CreateTestRequest(
574 net::URLRequestTestJob::test_url_1());
575 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
576 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
577 resource_handler.reset(
578 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(),
579 &temporary_file_manager));
580 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
581 request.Pass(), resource_handler.Pass(), this));
582
583 // Run it to completion.
584 loader->StartRequest();
585 base::RunLoop().RunUntilIdle();
586
587 // To downstream, the request was canceled sometime after it started, but
588 // before any data was written.
589 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
590 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
591 EXPECT_TRUE(leaf_handler->received_response_completed());
592 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status());
593 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
594 }
595
596 // Tests that RedirectToFileHandler defers completion if there are outstanding
597 // writes and accounts for errors which occur in that time.
598 TEST_F(ResourceLoaderTest, RedirectToFileDeferCompletion) {
599 // Program the MockFileStream to error asynchronously, but throttle the
600 // callback.
601 MockTemporaryFileManager temporary_file_manager;
602 base::FilePath temp_path =
603 temporary_file_manager.next_deletable_file()->path();
604 net::testing::MockFileStream* mock_file_stream =
605 temporary_file_manager.next_file_stream();
606 mock_file_stream->set_forced_error_async(net::ERR_FAILED);
607 mock_file_stream->ThrottleCallbacks();
608
609 // Setup the request.
610 scoped_ptr<net::URLRequest> request = CreateTestRequest(
611 net::URLRequestTestJob::test_url_1());
612 net::URLRequest* raw_ptr_to_request = request.get();
613 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
614 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
615 resource_handler.reset(
616 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(),
617 &temporary_file_manager));
618 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
619 request.Pass(), resource_handler.Pass(), this));
620
621 // Run it as far as it will go.
622 loader->StartRequest();
623 base::RunLoop().RunUntilIdle();
624
625 // At this point, the request should have completed.
626 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
627 raw_ptr_to_request->status().status());
628
629 // However, the resource loader stack is stuck somewhere after receiving the
630 // response.
631 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
632 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
633 EXPECT_FALSE(leaf_handler->received_response_completed());
634 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
635
636 // Now, release the floodgates.
637 mock_file_stream->ReleaseCallbacks();
638 base::RunLoop().RunUntilIdle();
639
640 // Although the URLRequest was successful, the leaf handler sees a failure
641 // because the write never completed.
642 EXPECT_TRUE(leaf_handler->received_response_completed());
643 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status());
644 }
645
646 // Tests that a RedirectToFileResourceHandler behaves properly when the
647 // downstream handler defers OnWillStart.
648 TEST_F(ResourceLoaderTest, RedirectToFileDownstreamDeferStart) {
649 MockTemporaryFileManager temporary_file_manager;
650 base::FilePath temp_path =
651 temporary_file_manager.next_deletable_file()->path();
652
653 // Setup the request.
654 scoped_ptr<net::URLRequest> request = CreateTestRequest(
655 net::URLRequestTestJob::test_url_1());
656 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
657 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
658 resource_handler.reset(
659 new RedirectToFileResourceHandler(resource_handler.Pass(), request.get(),
660 &temporary_file_manager));
661 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
662 request.Pass(), resource_handler.Pass(), this));
663
664 // Defer OnWillStart.
665 leaf_handler->set_defer_start(true);
666
667 // Run as far as we'll go.
668 loader->StartRequest();
669 base::RunLoop().RunUntilIdle();
670
671 // The request should have stopped at OnWillStart.
672 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
673 EXPECT_FALSE(leaf_handler->response());
674 EXPECT_FALSE(leaf_handler->received_response_completed());
675 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
676
677 // Now resume the request. Now we complete.
678 leaf_handler->Resume();
679 base::RunLoop().RunUntilIdle();
680
681 // Check that the handler forwarded all information to the downstream handler.
682 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
683 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
684 EXPECT_TRUE(leaf_handler->received_response_completed());
685 EXPECT_EQ(net::URLRequestStatus::SUCCESS, leaf_handler->status().status());
686 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(),
687 static_cast<size_t>(leaf_handler->total_bytes_downloaded()));
688
689 // Check that the data was written to the file.
690 std::string contents;
691 ASSERT_TRUE(base::ReadFileToString(temp_path, &contents));
692 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
693
694 // Release the loader. The file should be gone now.
695 loader.reset();
696 base::RunLoop().RunUntilIdle();
697 EXPECT_FALSE(base::PathExists(temp_path));
698 }
699
323 } // namespace content 700 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698