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

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 scoped_ptr<net::FileStream> null_stream;
235 base::MessageLoop::current()->PostTask(
236 FROM_HERE,
237 base::Bind(callback, error, base::Passed(&null_stream),
mmenke 2014/03/03 21:10:11 Doesn't really matter, but can you just use "scope
davidben 2014/03/03 23:20:18 Done. I thought that didn't work, but apparently y
238 scoped_refptr<ShareableFileReference>()));
239 }
240
241 // Glue code to mock up a RedirectToFileResourceHandler with a MockFileStream
242 // and a pre-created temporary file.
243 class RedirectToFileMock {
244 public:
245 RedirectToFileMock() {
246 base::FilePath file_path;
247 CHECK(base::CreateTemporaryFile(&file_path));
248 base::PlatformFile platform_file =
249 base::CreatePlatformFile(file_path,
250 base::PLATFORM_FILE_WRITE |
251 base::PLATFORM_FILE_TEMPORARY |
252 base::PLATFORM_FILE_CREATE_ALWAYS |
253 base::PLATFORM_FILE_ASYNC,
254 NULL, NULL);
255 CHECK_NE(base::kInvalidPlatformFileValue, platform_file);
256 file_stream_.reset(
257 new net::testing::MockFileStream(
258 platform_file,
259 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC,
260 NULL, base::MessageLoopProxy::current()));
261 deletable_file_ =
262 ShareableFileReference::GetOrCreate(
263 file_path,
264 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
265 BrowserThread::GetMessageLoopProxyForThread(
266 BrowserThread::FILE).get());
267 }
268
269 net::testing::MockFileStream* file_stream() const {
270 return file_stream_.get();
271 }
272 ShareableFileReference* deletable_file() const {
mmenke 2014/03/03 21:10:11 As-is, these only work before PostCallback is call
davidben 2014/03/03 23:20:18 Done.
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 DCHECK(file_stream_);
290 DCHECK(deletable_file_);
mmenke 2014/03/03 21:10:11 Weird to mix CHECKs (Higher up in this CL) and DCH
davidben 2014/03/03 23:20:18 Done.
291 scoped_ptr<net::FileStream> file_stream =
292 file_stream_.PassAs<net::FileStream>();
mmenke 2014/03/03 21:10:11 Can you just inline "file_stream_.PassAs<net::File
davidben 2014/03/03 23:20:18 Done. base::Passed is still needed, but apparently
293 base::MessageLoop::current()->PostTask(
294 FROM_HERE,
295 base::Bind(callback, base::File::FILE_OK,
296 base::Passed(&file_stream), deletable_file_));
297 deletable_file_ = NULL;
298 }
299
300 scoped_ptr<net::testing::MockFileStream> file_stream_;
301 scoped_refptr<ShareableFileReference> deletable_file_;
mmenke 2014/03/03 21:10:11 DISALLOW_COPY_AND_ASSIGN? Not copyable anyways, w
davidben 2014/03/03 23:20:18 Done.
302 };
303
172 } // namespace 304 } // namespace
173 305
174 class ResourceLoaderTest : public testing::Test, 306 class ResourceLoaderTest : public testing::Test,
175 public ResourceLoaderDelegate { 307 public ResourceLoaderDelegate {
176 protected: 308 protected:
177 ResourceLoaderTest() 309 ResourceLoaderTest()
178 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 310 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
179 resource_context_(&test_url_request_context_) { 311 resource_context_(&test_url_request_context_) {
312 job_factory_.SetProtocolHandler(
313 "test", net::URLRequestTestJob::CreateProtocolHandler());
314 test_url_request_context_.set_job_factory(&job_factory_);
315 }
316
317 scoped_ptr<net::URLRequest> CreateTestRequest(const GURL& url) {
318 const int kRenderProcessId = 1;
319 const int kRenderViewId = 2;
320
321 scoped_ptr<net::URLRequest> request(
322 new net::URLRequest(url, net::DEFAULT_PRIORITY, NULL,
323 resource_context_.GetRequestContext()));
324 ResourceRequestInfo::AllocateForTesting(request.get(),
325 ResourceType::MAIN_FRAME,
326 &resource_context_,
327 kRenderProcessId,
328 kRenderViewId,
329 MSG_ROUTING_NONE,
330 false);
331 return request.Pass();
180 } 332 }
181 333
182 // ResourceLoaderDelegate: 334 // ResourceLoaderDelegate:
183 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( 335 virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
184 ResourceLoader* loader, 336 ResourceLoader* loader,
185 net::AuthChallengeInfo* auth_info) OVERRIDE { 337 net::AuthChallengeInfo* auth_info) OVERRIDE {
186 return NULL; 338 return NULL;
187 } 339 }
188 virtual bool HandleExternalProtocol(ResourceLoader* loader, 340 virtual bool HandleExternalProtocol(ResourceLoader* loader,
189 const GURL& url) OVERRIDE { 341 const GURL& url) OVERRIDE {
190 return false; 342 return false;
191 } 343 }
192 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {} 344 virtual void DidStartRequest(ResourceLoader* loader) OVERRIDE {}
193 virtual void DidReceiveRedirect(ResourceLoader* loader, 345 virtual void DidReceiveRedirect(ResourceLoader* loader,
194 const GURL& new_url) OVERRIDE {} 346 const GURL& new_url) OVERRIDE {}
195 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {} 347 virtual void DidReceiveResponse(ResourceLoader* loader) OVERRIDE {}
196 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {} 348 virtual void DidFinishLoading(ResourceLoader* loader) OVERRIDE {}
197 349
198 content::TestBrowserThreadBundle thread_bundle_; 350 content::TestBrowserThreadBundle thread_bundle_;
199 351
352 net::URLRequestJobFactoryImpl job_factory_;
200 net::TestURLRequestContext test_url_request_context_; 353 net::TestURLRequestContext test_url_request_context_;
201 ResourceContextStub resource_context_; 354 ResourceContextStub resource_context_;
202 }; 355 };
203 356
204 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested() 357 // Verifies if a call to net::UrlRequest::Delegate::OnCertificateRequested()
205 // causes client cert store to be queried for certificates and if the returned 358 // causes client cert store to be queried for certificates and if the returned
206 // certificates are correctly passed to the content browser client for 359 // certificates are correctly passed to the content browser client for
207 // selection. 360 // selection.
208 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) { 361 TEST_F(ResourceLoaderTest, ClientCertStoreLookup) {
209 const int kRenderProcessId = 1; 362 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 363
225 // Set up the test client cert store. 364 // Set up the test client cert store.
226 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>( 365 net::CertificateList dummy_certs(1, scoped_refptr<net::X509Certificate>(
227 new net::X509Certificate("test", "test", base::Time(), base::Time()))); 366 new net::X509Certificate("test", "test", base::Time(), base::Time())));
228 scoped_ptr<ClientCertStoreStub> test_store( 367 scoped_ptr<ClientCertStoreStub> test_store(
229 new ClientCertStoreStub(dummy_certs)); 368 new ClientCertStoreStub(dummy_certs));
230 EXPECT_EQ(0, test_store->request_count()); 369 EXPECT_EQ(0, test_store->request_count());
231 370
232 // Ownership of the |request| and |test_store| is about to be turned over to 371 // 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 372 // ResourceLoader. We need to keep raw pointer copies to access these objects
234 // later. 373 // later.
235 net::URLRequest* raw_ptr_to_request = request.get(); 374 net::URLRequest* raw_ptr_to_request = request.get();
236 ClientCertStoreStub* raw_ptr_to_store = test_store.get(); 375 ClientCertStoreStub* raw_ptr_to_store = test_store.get();
237 resource_context_.SetClientCertStore( 376 resource_context_.SetClientCertStore(
238 test_store.PassAs<net::ClientCertStore>()); 377 test_store.PassAs<net::ClientCertStore>());
239 378
240 scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub()); 379 scoped_ptr<ResourceHandler> resource_handler(
380 new ResourceHandlerStub(request.get()));
241 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this); 381 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this);
242 382
243 // Prepare a dummy certificate request. 383 // Prepare a dummy certificate request.
244 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( 384 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
245 new net::SSLCertRequestInfo()); 385 new net::SSLCertRequestInfo());
246 std::vector<std::string> dummy_authority(1, "dummy"); 386 std::vector<std::string> dummy_authority(1, "dummy");
247 cert_request_info->cert_authorities = dummy_authority; 387 cert_request_info->cert_authorities = dummy_authority;
248 388
249 // Plug in test content browser client. 389 // Plug in test content browser client.
250 SelectCertificateBrowserClient test_client; 390 SelectCertificateBrowserClient test_client;
(...skipping 14 matching lines...) Expand all
265 // Check if the retrieved certificates were passed to the content browser 405 // Check if the retrieved certificates were passed to the content browser
266 // client. 406 // client.
267 EXPECT_EQ(1, test_client.call_count()); 407 EXPECT_EQ(1, test_client.call_count());
268 EXPECT_EQ(dummy_certs, test_client.passed_certs()); 408 EXPECT_EQ(dummy_certs, test_client.passed_certs());
269 } 409 }
270 410
271 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested() 411 // Verifies if a call to net::URLRequest::Delegate::OnCertificateRequested()
272 // on a platform with a NULL client cert store still calls the content browser 412 // on a platform with a NULL client cert store still calls the content browser
273 // client for selection. 413 // client for selection.
274 TEST_F(ResourceLoaderTest, ClientCertStoreNull) { 414 TEST_F(ResourceLoaderTest, ClientCertStoreNull) {
275 const int kRenderProcessId = 1; 415 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 416
291 // Ownership of the |request| is about to be turned over to ResourceLoader. We 417 // 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. 418 // need to keep a raw pointer copy to access this object later.
293 net::URLRequest* raw_ptr_to_request = request.get(); 419 net::URLRequest* raw_ptr_to_request = request.get();
294 420
295 scoped_ptr<ResourceHandler> resource_handler(new ResourceHandlerStub()); 421 scoped_ptr<ResourceHandler> resource_handler(
422 new ResourceHandlerStub(request.get()));
296 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this); 423 ResourceLoader loader(request.Pass(), resource_handler.Pass(), this);
297 424
298 // Prepare a dummy certificate request. 425 // Prepare a dummy certificate request.
299 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( 426 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
300 new net::SSLCertRequestInfo()); 427 new net::SSLCertRequestInfo());
301 std::vector<std::string> dummy_authority(1, "dummy"); 428 std::vector<std::string> dummy_authority(1, "dummy");
302 cert_request_info->cert_authorities = dummy_authority; 429 cert_request_info->cert_authorities = dummy_authority;
303 430
304 // Plug in test content browser client. 431 // Plug in test content browser client.
305 SelectCertificateBrowserClient test_client; 432 SelectCertificateBrowserClient test_client;
306 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client); 433 ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client);
307 434
308 // Everything is set up. Trigger the resource loader certificate request event 435 // Everything is set up. Trigger the resource loader certificate request event
309 // and run the message loop. 436 // and run the message loop.
310 loader.OnCertificateRequested(raw_ptr_to_request, cert_request_info.get()); 437 loader.OnCertificateRequested(raw_ptr_to_request, cert_request_info.get());
311 base::RunLoop().RunUntilIdle(); 438 base::RunLoop().RunUntilIdle();
312 439
313 // Restore the original content browser client. 440 // Restore the original content browser client.
314 SetBrowserClientForTesting(old_client); 441 SetBrowserClientForTesting(old_client);
315 442
316 // Check if the SelectClientCertificate was called on the content browser 443 // Check if the SelectClientCertificate was called on the content browser
317 // client. 444 // client.
318 EXPECT_EQ(1, test_client.call_count()); 445 EXPECT_EQ(1, test_client.call_count());
319 EXPECT_EQ(net::CertificateList(), test_client.passed_certs()); 446 EXPECT_EQ(net::CertificateList(), test_client.passed_certs());
320 } 447 }
321 448
449 // Tests that a RedirectToFileResourceHandler works and forwards everything
450 // downstream.
451 TEST_F(ResourceLoaderTest, RedirectToFile) {
452 RedirectToFileMock redirect_to_file_mock;
453 base::FilePath temp_path = redirect_to_file_mock.deletable_file()->path();
454
455 // Set up the request.
456 scoped_ptr<net::URLRequest> request = CreateTestRequest(
457 net::URLRequestTestJob::test_url_1());
458 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
459 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
460 resource_handler = redirect_to_file_mock.CreateResourceHandler(
461 resource_handler.Pass(), request.get());
462 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
463 request.Pass(), resource_handler.Pass(), this));
464
465 // Run it to completion.
466 loader->StartRequest();
467 base::RunLoop().RunUntilIdle();
468
469 // Check that the handler forwarded all information to the downstream handler.
470 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
471 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
472 EXPECT_TRUE(leaf_handler->received_response_completed());
473 EXPECT_EQ(net::URLRequestStatus::SUCCESS, leaf_handler->status().status());
474 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(),
475 static_cast<size_t>(leaf_handler->total_bytes_downloaded()));
476
477 // Check that the data was written to the file.
478 std::string contents;
479 ASSERT_TRUE(base::ReadFileToString(temp_path, &contents));
480 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
481
482 // Release the loader. The file should be gone now.
483 loader.reset();
484 base::RunLoop().RunUntilIdle();
485 EXPECT_FALSE(base::PathExists(temp_path));
486 }
487
488 // Tests that RedirectToFileResourceHandler handles errors in creating the
489 // temporary file.
490 TEST_F(ResourceLoaderTest, RedirectToFileCreateTemporaryError) {
491 // Set up the request.
492 scoped_ptr<net::URLRequest> request = CreateTestRequest(
493 net::URLRequestTestJob::test_url_1());
494 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
495
496 scoped_ptr<RedirectToFileResourceHandler> resource_handler(
497 new RedirectToFileResourceHandler(
498 scoped_ptr<ResourceHandler>(leaf_handler), request.get()));
499 resource_handler->SetCreateTemporaryFileStreamFunctionForTesting(
500 base::Bind(&CreateTemporaryError, base::File::FILE_ERROR_FAILED));
501
502 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
503 request.Pass(), resource_handler.PassAs<ResourceHandler>(), this));
504
505 // Run it to completion.
506 loader->StartRequest();
507 base::RunLoop().RunUntilIdle();
508
509 // To downstream, the request was canceled.
510 EXPECT_TRUE(leaf_handler->received_response_completed());
511 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status());
512 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
513 }
514
515 // Tests that RedirectToFileResourceHandler handles synchronous write errors.
516 TEST_F(ResourceLoaderTest, RedirectToFileWriteError) {
517 RedirectToFileMock redirect_to_file_mock;
518 base::FilePath temp_path = redirect_to_file_mock.deletable_file()->path();
519 net::testing::MockFileStream* mock_file_stream =
520 redirect_to_file_mock.file_stream();
521 mock_file_stream->set_forced_error(net::ERR_FAILED);
522
523 // Set up the request.
524 scoped_ptr<net::URLRequest> request = CreateTestRequest(
525 net::URLRequestTestJob::test_url_1());
526 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
527 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
528 resource_handler = redirect_to_file_mock.CreateResourceHandler(
529 resource_handler.Pass(), request.get());
530 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
531 request.Pass(), resource_handler.Pass(), this));
532
533 // Run it to completion.
534 loader->StartRequest();
535 base::RunLoop().RunUntilIdle();
536
537 // To downstream, the request was canceled sometime after it started, but
538 // before any data was written.
539 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
540 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
541 EXPECT_TRUE(leaf_handler->received_response_completed());
542 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status());
543 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
mmenke 2014/03/03 21:10:11 Check that the file was deleted? Without a real w
davidben 2014/03/03 23:20:18 Done.
544 }
545
546 // Tests that RedirectToFileResourceHandler handles asynchronous write errors.
547 TEST_F(ResourceLoaderTest, RedirectToFileWriteErrorAsync) {
548 RedirectToFileMock redirect_to_file_mock;
549 base::FilePath temp_path = redirect_to_file_mock.deletable_file()->path();
550 net::testing::MockFileStream* mock_file_stream =
551 redirect_to_file_mock.file_stream();
552 mock_file_stream->set_forced_error_async(net::ERR_FAILED);
553
554 // Set up the request.
555 scoped_ptr<net::URLRequest> request = CreateTestRequest(
556 net::URLRequestTestJob::test_url_1());
557 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
558 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
559 resource_handler = redirect_to_file_mock.CreateResourceHandler(
560 resource_handler.Pass(), request.get());
561 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
562 request.Pass(), resource_handler.Pass(), this));
563
564 // Run it to completion.
565 loader->StartRequest();
566 base::RunLoop().RunUntilIdle();
567
568 // To downstream, the request was canceled sometime after it started, but
569 // before any data was written.
570 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
571 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
572 EXPECT_TRUE(leaf_handler->received_response_completed());
573 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status());
574 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
575 }
576
577 // Tests that RedirectToFileHandler defers completion if there are outstanding
578 // writes and accounts for errors which occur in that time.
579 TEST_F(ResourceLoaderTest, RedirectToFileDeferCompletion) {
580 // Program the MockFileStream to error asynchronously, but throttle the
581 // callback.
582 RedirectToFileMock redirect_to_file_mock;
583 base::FilePath temp_path = redirect_to_file_mock.deletable_file()->path();
584 net::testing::MockFileStream* mock_file_stream =
585 redirect_to_file_mock.file_stream();
586 mock_file_stream->set_forced_error_async(net::ERR_FAILED);
587 mock_file_stream->ThrottleCallbacks();
588
589 // Set up the request.
590 scoped_ptr<net::URLRequest> request = CreateTestRequest(
591 net::URLRequestTestJob::test_url_1());
592 net::URLRequest* raw_ptr_to_request = request.get();
593 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
594 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
595 resource_handler = redirect_to_file_mock.CreateResourceHandler(
596 resource_handler.Pass(), request.get());
597 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
598 request.Pass(), resource_handler.Pass(), this));
599
600 // Run it as far as it will go.
601 loader->StartRequest();
602 base::RunLoop().RunUntilIdle();
603
604 // At this point, the request should have completed.
605 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
606 raw_ptr_to_request->status().status());
607
608 // However, the resource loader stack is stuck somewhere after receiving the
609 // response.
610 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
611 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
612 EXPECT_FALSE(leaf_handler->received_response_completed());
613 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
614
615 // Now, release the floodgates.
616 mock_file_stream->ReleaseCallbacks();
617 base::RunLoop().RunUntilIdle();
618
619 // Although the URLRequest was successful, the leaf handler sees a failure
620 // because the write never completed.
621 EXPECT_TRUE(leaf_handler->received_response_completed());
622 EXPECT_EQ(net::URLRequestStatus::CANCELED, leaf_handler->status().status());
623 }
624
625 // Tests that a RedirectToFileResourceHandler behaves properly when the
626 // downstream handler defers OnWillStart.
627 TEST_F(ResourceLoaderTest, RedirectToFileDownstreamDeferStart) {
628 RedirectToFileMock redirect_to_file_mock;
629 base::FilePath temp_path =
630 redirect_to_file_mock.deletable_file()->path();
631
632 // Set up the request.
633 scoped_ptr<net::URLRequest> request = CreateTestRequest(
634 net::URLRequestTestJob::test_url_1());
635 ResourceHandlerStub* leaf_handler = new ResourceHandlerStub(request.get());
636 scoped_ptr<ResourceHandler> resource_handler(leaf_handler);
637 resource_handler = redirect_to_file_mock.CreateResourceHandler(
638 resource_handler.Pass(), request.get());
639 scoped_ptr<ResourceLoader> loader(new ResourceLoader(
640 request.Pass(), resource_handler.Pass(), this));
641
642 // Defer OnWillStart.
643 leaf_handler->set_defer_start(true);
644
645 // Run as far as we'll go.
646 loader->StartRequest();
647 base::RunLoop().RunUntilIdle();
648
649 // The request should have stopped at OnWillStart.
650 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
651 EXPECT_FALSE(leaf_handler->response());
652 EXPECT_FALSE(leaf_handler->received_response_completed());
653 EXPECT_EQ(0, leaf_handler->total_bytes_downloaded());
654
655 // Now resume the request. Now we complete.
656 leaf_handler->Resume();
657 base::RunLoop().RunUntilIdle();
658
659 // Check that the handler forwarded all information to the downstream handler.
660 EXPECT_EQ(temp_path, leaf_handler->response()->head.download_file_path);
661 EXPECT_EQ(net::URLRequestTestJob::test_url_1(), leaf_handler->start_url());
662 EXPECT_TRUE(leaf_handler->received_response_completed());
663 EXPECT_EQ(net::URLRequestStatus::SUCCESS, leaf_handler->status().status());
664 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(),
665 static_cast<size_t>(leaf_handler->total_bytes_downloaded()));
666
667 // Check that the data was written to the file.
668 std::string contents;
669 ASSERT_TRUE(base::ReadFileToString(temp_path, &contents));
670 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
671
672 // Release the loader. The file should be gone now.
673 loader.reset();
674 base::RunLoop().RunUntilIdle();
675 EXPECT_FALSE(base::PathExists(temp_path));
676 }
677
322 } // namespace content 678 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698