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

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

Powered by Google App Engine
This is Rietveld 408576698