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

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: Comment 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_) {
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698