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

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

Powered by Google App Engine
This is Rietveld 408576698