OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/renderer_host/resource_dispatcher_host.h" | 5 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
11 #include "base/memory/scoped_vector.h" | 11 #include "base/memory/scoped_vector.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/process_util.h" | 13 #include "base/process_util.h" |
14 #include "content/browser/browser_thread_impl.h" | 14 #include "content/browser/browser_thread_impl.h" |
15 #include "content/browser/child_process_security_policy_impl.h" | 15 #include "content/browser/child_process_security_policy_impl.h" |
16 #include "content/browser/mock_resource_context.h" | 16 #include "content/browser/mock_resource_context.h" |
17 #include "content/browser/renderer_host/dummy_resource_handler.h" | 17 #include "content/browser/renderer_host/dummy_resource_handler.h" |
18 #include "content/browser/renderer_host/layered_resource_handler.h" | 18 #include "content/browser/renderer_host/layered_resource_handler.h" |
19 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 19 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
20 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" | 20 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" |
21 #include "content/browser/renderer_host/resource_message_filter.h" | 21 #include "content/browser/renderer_host/resource_message_filter.h" |
22 #include "content/common/child_process_host_impl.h" | 22 #include "content/common/child_process_host_impl.h" |
23 #include "content/common/resource_messages.h" | 23 #include "content/common/resource_messages.h" |
24 #include "content/common/view_messages.h" | 24 #include "content/common/view_messages.h" |
25 #include "content/public/browser/global_request_id.h" | 25 #include "content/public/browser/global_request_id.h" |
26 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 26 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
27 #include "content/public/browser/resource_throttle.h" | 27 #include "content/public/browser/resource_throttle.h" |
28 #include "content/public/common/resource_response.h" | 28 #include "content/public/common/resource_response.h" |
| 29 #include "content/test/test_browser_context.h" |
29 #include "net/base/net_errors.h" | 30 #include "net/base/net_errors.h" |
30 #include "net/base/upload_data.h" | 31 #include "net/base/upload_data.h" |
31 #include "net/http/http_util.h" | 32 #include "net/http/http_util.h" |
32 #include "net/url_request/url_request.h" | 33 #include "net/url_request/url_request.h" |
33 #include "net/url_request/url_request_job.h" | 34 #include "net/url_request/url_request_job.h" |
34 #include "net/url_request/url_request_test_job.h" | 35 #include "net/url_request/url_request_test_job.h" |
35 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
36 #include "webkit/appcache/appcache_interfaces.h" | 37 #include "webkit/appcache/appcache_interfaces.h" |
37 | 38 |
38 namespace content { | 39 using content::BrowserContext; |
39 class DownloadManager; | |
40 } // namespace content | |
41 | |
42 using content::BrowserThread; | 40 using content::BrowserThread; |
43 using content::BrowserThreadImpl; | 41 using content::BrowserThreadImpl; |
44 using content::ChildProcessHostImpl; | 42 using content::ChildProcessHostImpl; |
45 using content::DownloadManager; | |
46 using content::GlobalRequestID; | 43 using content::GlobalRequestID; |
47 | 44 |
48 // TODO(eroman): Write unit tests for SafeBrowsing that exercise | 45 // TODO(eroman): Write unit tests for SafeBrowsing that exercise |
49 // SafeBrowsingResourceHandler. | 46 // SafeBrowsingResourceHandler. |
50 | 47 |
51 namespace { | 48 namespace { |
52 | 49 |
53 // Returns the resource response header structure for this request. | 50 // Returns the resource response header structure for this request. |
54 void GetResponseHead(const std::vector<IPC::Message>& messages, | 51 void GetResponseHead(const std::vector<IPC::Message>& messages, |
55 content::ResourceResponseHead* response_head) { | 52 content::ResourceResponseHead* response_head) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 private: | 159 private: |
163 net::URLRequestContext* const request_context_; | 160 net::URLRequestContext* const request_context_; |
164 }; | 161 }; |
165 | 162 |
166 // This class forwards the incoming messages to the ResourceDispatcherHostTest. | 163 // This class forwards the incoming messages to the ResourceDispatcherHostTest. |
167 // This is used to emulate different sub-processes, since this filter will | 164 // This is used to emulate different sub-processes, since this filter will |
168 // have a different ID than the original. For the test, we want all the incoming | 165 // have a different ID than the original. For the test, we want all the incoming |
169 // messages to go to the same place, which is why this forwards. | 166 // messages to go to the same place, which is why this forwards. |
170 class ForwardingFilter : public ResourceMessageFilter { | 167 class ForwardingFilter : public ResourceMessageFilter { |
171 public: | 168 public: |
172 explicit ForwardingFilter(IPC::Message::Sender* dest) | 169 explicit ForwardingFilter(IPC::Message::Sender* dest, |
| 170 content::ResourceContext* resource_context) |
173 : ResourceMessageFilter( | 171 : ResourceMessageFilter( |
174 ChildProcessHostImpl::GenerateChildProcessUniqueId(), | 172 ChildProcessHostImpl::GenerateChildProcessUniqueId(), |
175 content::PROCESS_TYPE_RENDERER, | 173 content::PROCESS_TYPE_RENDERER, |
176 content::MockResourceContext::GetInstance(), | 174 resource_context, |
177 new MockURLRequestContextSelector( | 175 new MockURLRequestContextSelector( |
178 content::MockResourceContext::GetInstance()->GetRequestContext())), | 176 content::MockResourceContext::GetInstance()->GetRequestContext())), |
179 dest_(dest) { | 177 dest_(dest) { |
180 OnChannelConnected(base::GetCurrentProcId()); | 178 OnChannelConnected(base::GetCurrentProcId()); |
181 } | 179 } |
182 | 180 |
183 // ResourceMessageFilter override | 181 // ResourceMessageFilter override |
184 virtual bool Send(IPC::Message* msg) { | 182 virtual bool Send(IPC::Message* msg) { |
185 if (!dest_) | 183 if (!dest_) |
186 return false; | 184 return false; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 private: | 325 private: |
328 bool defer_start_; | 326 bool defer_start_; |
329 scoped_ptr<base::SupportsUserData::Data> user_data_; | 327 scoped_ptr<base::SupportsUserData::Data> user_data_; |
330 }; | 328 }; |
331 | 329 |
332 class ResourceDispatcherHostTest : public testing::Test, | 330 class ResourceDispatcherHostTest : public testing::Test, |
333 public IPC::Message::Sender { | 331 public IPC::Message::Sender { |
334 public: | 332 public: |
335 ResourceDispatcherHostTest() | 333 ResourceDispatcherHostTest() |
336 : ui_thread_(BrowserThread::UI, &message_loop_), | 334 : ui_thread_(BrowserThread::UI, &message_loop_), |
| 335 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_), |
| 336 cache_thread_(BrowserThread::CACHE, &message_loop_), |
337 io_thread_(BrowserThread::IO, &message_loop_), | 337 io_thread_(BrowserThread::IO, &message_loop_), |
338 ALLOW_THIS_IN_INITIALIZER_LIST(filter_(new ForwardingFilter(this))), | |
339 old_factory_(NULL), | 338 old_factory_(NULL), |
340 resource_type_(ResourceType::SUB_RESOURCE) { | 339 resource_type_(ResourceType::SUB_RESOURCE) { |
| 340 BrowserContext::EnsureResourceContextInitialized(&browser_context_); |
| 341 filter_ = new ForwardingFilter(this, browser_context_.GetResourceContext()); |
341 } | 342 } |
342 // IPC::Message::Sender implementation | 343 // IPC::Message::Sender implementation |
343 virtual bool Send(IPC::Message* msg) { | 344 virtual bool Send(IPC::Message* msg) { |
344 accum_.AddMessage(*msg); | 345 accum_.AddMessage(*msg); |
345 delete msg; | 346 delete msg; |
346 return true; | 347 return true; |
347 } | 348 } |
348 | 349 |
349 protected: | 350 protected: |
350 // testing::Test | 351 // testing::Test |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 } | 451 } |
451 } | 452 } |
452 } | 453 } |
453 | 454 |
454 void SetDelayedStartJobGeneration(bool delay_job_start) { | 455 void SetDelayedStartJobGeneration(bool delay_job_start) { |
455 delay_start_ = delay_job_start; | 456 delay_start_ = delay_job_start; |
456 } | 457 } |
457 | 458 |
458 MessageLoopForIO message_loop_; | 459 MessageLoopForIO message_loop_; |
459 BrowserThreadImpl ui_thread_; | 460 BrowserThreadImpl ui_thread_; |
| 461 BrowserThreadImpl file_thread_; |
| 462 BrowserThreadImpl cache_thread_; |
460 BrowserThreadImpl io_thread_; | 463 BrowserThreadImpl io_thread_; |
| 464 TestBrowserContext browser_context_; |
461 scoped_refptr<ForwardingFilter> filter_; | 465 scoped_refptr<ForwardingFilter> filter_; |
462 ResourceDispatcherHost host_; | 466 ResourceDispatcherHost host_; |
463 ResourceIPCAccumulator accum_; | 467 ResourceIPCAccumulator accum_; |
464 std::string response_headers_; | 468 std::string response_headers_; |
465 std::string response_data_; | 469 std::string response_data_; |
466 std::string scheme_; | 470 std::string scheme_; |
467 net::URLRequest::ProtocolFactory* old_factory_; | 471 net::URLRequest::ProtocolFactory* old_factory_; |
468 ResourceType::Type resource_type_; | 472 ResourceType::Type resource_type_; |
469 static ResourceDispatcherHostTest* test_fixture_; | 473 static ResourceDispatcherHostTest* test_fixture_; |
470 static bool delay_start_; | 474 static bool delay_start_; |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 ASSERT_TRUE(IPC::ReadParam(&msgs[0][1], &iter, &request_id)); | 695 ASSERT_TRUE(IPC::ReadParam(&msgs[0][1], &iter, &request_id)); |
692 ASSERT_TRUE(IPC::ReadParam(&msgs[0][1], &iter, &status)); | 696 ASSERT_TRUE(IPC::ReadParam(&msgs[0][1], &iter, &status)); |
693 | 697 |
694 EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status()); | 698 EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status()); |
695 } | 699 } |
696 | 700 |
697 // The host delegate acts as a second one so we can have some requests | 701 // The host delegate acts as a second one so we can have some requests |
698 // pending and some canceled. | 702 // pending and some canceled. |
699 class TestFilter : public ForwardingFilter { | 703 class TestFilter : public ForwardingFilter { |
700 public: | 704 public: |
701 TestFilter() | 705 explicit TestFilter(content::ResourceContext* resource_context) |
702 : ForwardingFilter(NULL), | 706 : ForwardingFilter(NULL, resource_context), |
703 has_canceled_(false), | 707 has_canceled_(false), |
704 received_after_canceled_(0) { | 708 received_after_canceled_(0) { |
705 } | 709 } |
706 | 710 |
707 // ForwardingFilter override | 711 // ForwardingFilter override |
708 virtual bool Send(IPC::Message* msg) { | 712 virtual bool Send(IPC::Message* msg) { |
709 // no messages should be received when the process has been canceled | 713 // no messages should be received when the process has been canceled |
710 if (has_canceled_) | 714 if (has_canceled_) |
711 received_after_canceled_++; | 715 received_after_canceled_++; |
712 delete msg; | 716 delete msg; |
713 return true; | 717 return true; |
714 } | 718 } |
715 bool has_canceled_; | 719 bool has_canceled_; |
716 int received_after_canceled_; | 720 int received_after_canceled_; |
717 }; | 721 }; |
718 | 722 |
719 // Tests CancelRequestsForProcess | 723 // Tests CancelRequestsForProcess |
720 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { | 724 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { |
721 scoped_refptr<TestFilter> test_filter = new TestFilter(); | 725 scoped_refptr<TestFilter> test_filter = new TestFilter( |
| 726 browser_context_.GetResourceContext()); |
722 | 727 |
723 // request 1 goes to the test delegate | 728 // request 1 goes to the test delegate |
724 ResourceHostMsg_Request request = CreateResourceRequest( | 729 ResourceHostMsg_Request request = CreateResourceRequest( |
725 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); | 730 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); |
726 | 731 |
727 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | 732 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); |
728 | 733 |
729 MakeTestRequest(test_filter.get(), 0, 1, | 734 MakeTestRequest(test_filter.get(), 0, 1, |
730 net::URLRequestTestJob::test_url_1()); | 735 net::URLRequestTestJob::test_url_1()); |
731 | 736 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | 869 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); |
865 | 870 |
866 msgs.clear(); | 871 msgs.clear(); |
867 accum_.GetClassifiedMessages(&msgs); | 872 accum_.GetClassifiedMessages(&msgs); |
868 ASSERT_EQ(0U, msgs.size()); | 873 ASSERT_EQ(0U, msgs.size()); |
869 } | 874 } |
870 | 875 |
871 // Tests that blocked requests are canceled if their associated process dies. | 876 // Tests that blocked requests are canceled if their associated process dies. |
872 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { | 877 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { |
873 // This second filter is used to emulate a second process. | 878 // This second filter is used to emulate a second process. |
874 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); | 879 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( |
| 880 this, browser_context_.GetResourceContext()); |
875 | 881 |
876 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | 882 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); |
877 EXPECT_EQ(0, | 883 EXPECT_EQ(0, |
878 host_.GetOutstandingRequestsMemoryCost(second_filter->child_id())); | 884 host_.GetOutstandingRequestsMemoryCost(second_filter->child_id())); |
879 | 885 |
880 host_.BlockRequestsForRoute(second_filter->child_id(), 0); | 886 host_.BlockRequestsForRoute(second_filter->child_id(), 0); |
881 | 887 |
882 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); | 888 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); |
883 MakeTestRequest(second_filter.get(), 0, 2, | 889 MakeTestRequest(second_filter.get(), 0, 2, |
884 net::URLRequestTestJob::test_url_2()); | 890 net::URLRequestTestJob::test_url_2()); |
(...skipping 23 matching lines...) Expand all Loading... |
908 | 914 |
909 EXPECT_TRUE(host_.blocked_requests_map_.empty()); | 915 EXPECT_TRUE(host_.blocked_requests_map_.empty()); |
910 } | 916 } |
911 | 917 |
912 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes | 918 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes |
913 // away. Note that we rely on Purify for finding the leaks if any. | 919 // away. Note that we rely on Purify for finding the leaks if any. |
914 // If this test turns the Purify bot red, check the ResourceDispatcherHost | 920 // If this test turns the Purify bot red, check the ResourceDispatcherHost |
915 // destructor to make sure the blocked requests are deleted. | 921 // destructor to make sure the blocked requests are deleted. |
916 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { | 922 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { |
917 // This second filter is used to emulate a second process. | 923 // This second filter is used to emulate a second process. |
918 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); | 924 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( |
| 925 this, browser_context_.GetResourceContext()); |
919 | 926 |
920 host_.BlockRequestsForRoute(filter_->child_id(), 1); | 927 host_.BlockRequestsForRoute(filter_->child_id(), 1); |
921 host_.BlockRequestsForRoute(filter_->child_id(), 2); | 928 host_.BlockRequestsForRoute(filter_->child_id(), 2); |
922 host_.BlockRequestsForRoute(second_filter->child_id(), 1); | 929 host_.BlockRequestsForRoute(second_filter->child_id(), 1); |
923 | 930 |
924 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); | 931 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); |
925 MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2()); | 932 MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2()); |
926 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3()); | 933 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3()); |
927 MakeTestRequest(second_filter.get(), 1, 4, | 934 MakeTestRequest(second_filter.get(), 1, 4, |
928 net::URLRequestTestJob::test_url_1()); | 935 net::URLRequestTestJob::test_url_1()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 | 1006 |
1000 // Tighten the bound on the ResourceDispatcherHost, to speed things up. | 1007 // Tighten the bound on the ResourceDispatcherHost, to speed things up. |
1001 int kMaxCostPerProcess = 440000; | 1008 int kMaxCostPerProcess = 440000; |
1002 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess); | 1009 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess); |
1003 | 1010 |
1004 // Determine how many instance of test_url_2() we can request before | 1011 // Determine how many instance of test_url_2() we can request before |
1005 // throttling kicks in. | 1012 // throttling kicks in. |
1006 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req; | 1013 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req; |
1007 | 1014 |
1008 // This second filter is used to emulate a second process. | 1015 // This second filter is used to emulate a second process. |
1009 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(this); | 1016 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( |
| 1017 this, browser_context_.GetResourceContext()); |
1010 | 1018 |
1011 // Saturate the number of outstanding requests for our process. | 1019 // Saturate the number of outstanding requests for our process. |
1012 for (size_t i = 0; i < kMaxRequests; ++i) { | 1020 for (size_t i = 0; i < kMaxRequests; ++i) { |
1013 MakeTestRequest(filter_.get(), 0, i + 1, | 1021 MakeTestRequest(filter_.get(), 0, i + 1, |
1014 net::URLRequestTestJob::test_url_2()); | 1022 net::URLRequestTestJob::test_url_2()); |
1015 } | 1023 } |
1016 | 1024 |
1017 // Issue two more requests for our process -- these should fail immediately. | 1025 // Issue two more requests for our process -- these should fail immediately. |
1018 MakeTestRequest(filter_.get(), 0, kMaxRequests + 1, | 1026 MakeTestRequest(filter_.get(), 0, kMaxRequests + 1, |
1019 net::URLRequestTestJob::test_url_2()); | 1027 net::URLRequestTestJob::test_url_2()); |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 net::URLRequestStatus status; | 1384 net::URLRequestStatus status; |
1377 | 1385 |
1378 void* iter = NULL; | 1386 void* iter = NULL; |
1379 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id)); | 1387 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id)); |
1380 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &status)); | 1388 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &status)); |
1381 | 1389 |
1382 EXPECT_EQ(1, request_id); | 1390 EXPECT_EQ(1, request_id); |
1383 EXPECT_EQ(net::URLRequestStatus::FAILED, status.status()); | 1391 EXPECT_EQ(net::URLRequestStatus::FAILED, status.status()); |
1384 EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, status.error()); | 1392 EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, status.error()); |
1385 } | 1393 } |
OLD | NEW |