| 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_impl.h" | 5 #include "content/browser/renderer_host/resource_dispatcher_host_impl.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 "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
| 15 #include "base/string_split.h" | 15 #include "base/string_split.h" |
| 16 #include "content/browser/browser_thread_impl.h" | 16 #include "content/browser/browser_thread_impl.h" |
| 17 #include "content/browser/child_process_security_policy_impl.h" | 17 #include "content/browser/child_process_security_policy_impl.h" |
| 18 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" | 18 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" |
| 19 #include "content/browser/renderer_host/resource_message_filter.h" | 19 #include "content/browser/renderer_host/resource_message_filter.h" |
| 20 #include "content/common/child_process_host_impl.h" | 20 #include "content/common/child_process_host_impl.h" |
| 21 #include "content/common/resource_messages.h" | 21 #include "content/common/resource_messages.h" |
| 22 #include "content/common/view_messages.h" | 22 #include "content/common/view_messages.h" |
| 23 #include "content/public/browser/global_request_id.h" | 23 #include "content/public/browser/global_request_id.h" |
| 24 #include "content/public/browser/resource_context.h" | 24 #include "content/public/browser/resource_context.h" |
| 25 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 25 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
| 26 #include "content/public/browser/resource_throttle.h" | 26 #include "content/public/browser/resource_throttle.h" |
| 27 #include "content/public/browser/storage_partition.h" |
| 27 #include "content/public/common/resource_response.h" | 28 #include "content/public/common/resource_response.h" |
| 28 #include "content/public/test/test_browser_context.h" | 29 #include "content/public/test/test_browser_context.h" |
| 29 #include "content/test/test_content_browser_client.h" | 30 #include "content/test/test_content_browser_client.h" |
| 30 #include "net/base/net_errors.h" | 31 #include "net/base/net_errors.h" |
| 31 #include "net/base/upload_data.h" | 32 #include "net/base/upload_data.h" |
| 32 #include "net/http/http_util.h" | 33 #include "net/http/http_util.h" |
| 33 #include "net/url_request/url_request.h" | 34 #include "net/url_request/url_request.h" |
| 34 #include "net/url_request/url_request_context.h" | 35 #include "net/url_request/url_request_context.h" |
| 35 #include "net/url_request/url_request_job.h" | 36 #include "net/url_request/url_request_job.h" |
| 36 #include "net/url_request/url_request_simple_job.h" | 37 #include "net/url_request/url_request_simple_job.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 60 } | 61 } |
| 61 | 62 |
| 62 void GenerateIPCMessage( | 63 void GenerateIPCMessage( |
| 63 scoped_refptr<ResourceMessageFilter> filter, | 64 scoped_refptr<ResourceMessageFilter> filter, |
| 64 scoped_ptr<IPC::Message> message) { | 65 scoped_ptr<IPC::Message> message) { |
| 65 bool msg_is_ok; | 66 bool msg_is_ok; |
| 66 ResourceDispatcherHostImpl::Get()->OnMessageReceived( | 67 ResourceDispatcherHostImpl::Get()->OnMessageReceived( |
| 67 *message, filter.get(), &msg_is_ok); | 68 *message, filter.get(), &msg_is_ok); |
| 68 } | 69 } |
| 69 | 70 |
| 71 ResourceContext* GetResourceContextForTest(BrowserContext* context) { |
| 72 return BrowserContext::GetDefaultStoragePartition(context)-> |
| 73 GetResourceContext(); |
| 74 } |
| 75 |
| 70 } // namespace | 76 } // namespace |
| 71 | 77 |
| 72 static int RequestIDForMessage(const IPC::Message& msg) { | 78 static int RequestIDForMessage(const IPC::Message& msg) { |
| 73 int request_id = -1; | 79 int request_id = -1; |
| 74 switch (msg.type()) { | 80 switch (msg.type()) { |
| 75 case ResourceMsg_UploadProgress::ID: | 81 case ResourceMsg_UploadProgress::ID: |
| 76 case ResourceMsg_ReceivedResponse::ID: | 82 case ResourceMsg_ReceivedResponse::ID: |
| 77 case ResourceMsg_ReceivedRedirect::ID: | 83 case ResourceMsg_ReceivedRedirect::ID: |
| 78 case ResourceMsg_DataReceived::ID: | 84 case ResourceMsg_DataReceived::ID: |
| 79 case ResourceMsg_RequestComplete::ID: | 85 case ResourceMsg_RequestComplete::ID: |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_), | 463 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_), |
| 458 cache_thread_(BrowserThread::CACHE, &message_loop_), | 464 cache_thread_(BrowserThread::CACHE, &message_loop_), |
| 459 io_thread_(BrowserThread::IO, &message_loop_), | 465 io_thread_(BrowserThread::IO, &message_loop_), |
| 460 old_factory_(NULL), | 466 old_factory_(NULL), |
| 461 resource_type_(ResourceType::SUB_RESOURCE), | 467 resource_type_(ResourceType::SUB_RESOURCE), |
| 462 send_data_received_acks_(false) { | 468 send_data_received_acks_(false) { |
| 463 browser_context_.reset(new content::TestBrowserContext()); | 469 browser_context_.reset(new content::TestBrowserContext()); |
| 464 BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); | 470 BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); |
| 465 message_loop_.RunAllPending(); | 471 message_loop_.RunAllPending(); |
| 466 filter_ = new ForwardingFilter( | 472 filter_ = new ForwardingFilter( |
| 467 this, browser_context_->GetResourceContext()); | 473 this, GetResourceContextForTest(browser_context_.get())); |
| 468 } | 474 } |
| 469 // IPC::Sender implementation | 475 // IPC::Sender implementation |
| 470 virtual bool Send(IPC::Message* msg) { | 476 virtual bool Send(IPC::Message* msg) { |
| 471 accum_.AddMessage(*msg); | 477 accum_.AddMessage(*msg); |
| 472 | 478 |
| 473 if (send_data_received_acks_ && | 479 if (send_data_received_acks_ && |
| 474 msg->type() == ResourceMsg_DataReceived::ID) { | 480 msg->type() == ResourceMsg_DataReceived::ID) { |
| 475 GenerateDataReceivedACK(*msg); | 481 GenerateDataReceivedACK(*msg); |
| 476 } | 482 } |
| 477 | 483 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 505 DCHECK(test_fixture_ == this); | 511 DCHECK(test_fixture_ == this); |
| 506 test_fixture_ = NULL; | 512 test_fixture_ = NULL; |
| 507 | 513 |
| 508 host_.Shutdown(); | 514 host_.Shutdown(); |
| 509 | 515 |
| 510 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0); | 516 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0); |
| 511 | 517 |
| 512 // Flush the message loop to make application verifiers happy. | 518 // Flush the message loop to make application verifiers happy. |
| 513 if (ResourceDispatcherHostImpl::Get()) | 519 if (ResourceDispatcherHostImpl::Get()) |
| 514 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext( | 520 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext( |
| 515 browser_context_->GetResourceContext()); | 521 GetResourceContextForTest(browser_context_.get())); |
| 516 browser_context_.reset(); | 522 browser_context_.reset(); |
| 517 message_loop_.RunAllPending(); | 523 message_loop_.RunAllPending(); |
| 518 } | 524 } |
| 519 | 525 |
| 520 // Creates a request using the current test object as the filter. | 526 // Creates a request using the current test object as the filter. |
| 521 void MakeTestRequest(int render_view_id, | 527 void MakeTestRequest(int render_view_id, |
| 522 int request_id, | 528 int request_id, |
| 523 const GURL& url); | 529 const GURL& url); |
| 524 | 530 |
| 525 // Generates a request using the given filter. This will probably be a | 531 // Generates a request using the given filter. This will probably be a |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 bool has_canceled_; | 872 bool has_canceled_; |
| 867 int received_after_canceled_; | 873 int received_after_canceled_; |
| 868 | 874 |
| 869 private: | 875 private: |
| 870 virtual ~TestFilter() {} | 876 virtual ~TestFilter() {} |
| 871 }; | 877 }; |
| 872 | 878 |
| 873 // Tests CancelRequestsForProcess | 879 // Tests CancelRequestsForProcess |
| 874 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { | 880 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { |
| 875 scoped_refptr<TestFilter> test_filter = new TestFilter( | 881 scoped_refptr<TestFilter> test_filter = new TestFilter( |
| 876 browser_context_->GetResourceContext()); | 882 GetResourceContextForTest(browser_context_.get())); |
| 877 | 883 |
| 878 // request 1 goes to the test delegate | 884 // request 1 goes to the test delegate |
| 879 ResourceHostMsg_Request request = CreateResourceRequest( | 885 ResourceHostMsg_Request request = CreateResourceRequest( |
| 880 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); | 886 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); |
| 881 | 887 |
| 882 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); | 888 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); |
| 883 | 889 |
| 884 MakeTestRequest(test_filter.get(), 0, 1, | 890 MakeTestRequest(test_filter.get(), 0, 1, |
| 885 net::URLRequestTestJob::test_url_1()); | 891 net::URLRequestTestJob::test_url_1()); |
| 886 | 892 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 | 1026 |
| 1021 msgs.clear(); | 1027 msgs.clear(); |
| 1022 accum_.GetClassifiedMessages(&msgs); | 1028 accum_.GetClassifiedMessages(&msgs); |
| 1023 ASSERT_EQ(0U, msgs.size()); | 1029 ASSERT_EQ(0U, msgs.size()); |
| 1024 } | 1030 } |
| 1025 | 1031 |
| 1026 // Tests that blocked requests are canceled if their associated process dies. | 1032 // Tests that blocked requests are canceled if their associated process dies. |
| 1027 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { | 1033 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { |
| 1028 // This second filter is used to emulate a second process. | 1034 // This second filter is used to emulate a second process. |
| 1029 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( | 1035 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( |
| 1030 this, browser_context_->GetResourceContext()); | 1036 this, GetResourceContextForTest(browser_context_.get())); |
| 1031 | 1037 |
| 1032 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); | 1038 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id())); |
| 1033 EXPECT_EQ(0, | 1039 EXPECT_EQ(0, |
| 1034 host_.GetOutstandingRequestsMemoryCost(second_filter->child_id())); | 1040 host_.GetOutstandingRequestsMemoryCost(second_filter->child_id())); |
| 1035 | 1041 |
| 1036 host_.BlockRequestsForRoute(second_filter->child_id(), 0); | 1042 host_.BlockRequestsForRoute(second_filter->child_id(), 0); |
| 1037 | 1043 |
| 1038 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); | 1044 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); |
| 1039 MakeTestRequest(second_filter.get(), 0, 2, | 1045 MakeTestRequest(second_filter.get(), 0, 2, |
| 1040 net::URLRequestTestJob::test_url_2()); | 1046 net::URLRequestTestJob::test_url_2()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1065 EXPECT_TRUE(host_.blocked_loaders_map_.empty()); | 1071 EXPECT_TRUE(host_.blocked_loaders_map_.empty()); |
| 1066 } | 1072 } |
| 1067 | 1073 |
| 1068 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes | 1074 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes |
| 1069 // away. Note that we rely on Purify for finding the leaks if any. | 1075 // away. Note that we rely on Purify for finding the leaks if any. |
| 1070 // If this test turns the Purify bot red, check the ResourceDispatcherHost | 1076 // If this test turns the Purify bot red, check the ResourceDispatcherHost |
| 1071 // destructor to make sure the blocked requests are deleted. | 1077 // destructor to make sure the blocked requests are deleted. |
| 1072 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { | 1078 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { |
| 1073 // This second filter is used to emulate a second process. | 1079 // This second filter is used to emulate a second process. |
| 1074 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( | 1080 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( |
| 1075 this, browser_context_->GetResourceContext()); | 1081 this, GetResourceContextForTest(browser_context_.get())); |
| 1076 | 1082 |
| 1077 host_.BlockRequestsForRoute(filter_->child_id(), 1); | 1083 host_.BlockRequestsForRoute(filter_->child_id(), 1); |
| 1078 host_.BlockRequestsForRoute(filter_->child_id(), 2); | 1084 host_.BlockRequestsForRoute(filter_->child_id(), 2); |
| 1079 host_.BlockRequestsForRoute(second_filter->child_id(), 1); | 1085 host_.BlockRequestsForRoute(second_filter->child_id(), 1); |
| 1080 | 1086 |
| 1081 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); | 1087 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1()); |
| 1082 MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2()); | 1088 MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2()); |
| 1083 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3()); | 1089 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3()); |
| 1084 MakeTestRequest(second_filter.get(), 1, 4, | 1090 MakeTestRequest(second_filter.get(), 1, 4, |
| 1085 net::URLRequestTestJob::test_url_1()); | 1091 net::URLRequestTestJob::test_url_1()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 // Tighten the bound on the ResourceDispatcherHost, to speed things up. | 1170 // Tighten the bound on the ResourceDispatcherHost, to speed things up. |
| 1165 int kMaxCostPerProcess = 440000; | 1171 int kMaxCostPerProcess = 440000; |
| 1166 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess); | 1172 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess); |
| 1167 | 1173 |
| 1168 // Determine how many instance of test_url_2() we can request before | 1174 // Determine how many instance of test_url_2() we can request before |
| 1169 // throttling kicks in. | 1175 // throttling kicks in. |
| 1170 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req; | 1176 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req; |
| 1171 | 1177 |
| 1172 // This second filter is used to emulate a second process. | 1178 // This second filter is used to emulate a second process. |
| 1173 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( | 1179 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( |
| 1174 this, browser_context_->GetResourceContext()); | 1180 this, GetResourceContextForTest(browser_context_.get())); |
| 1175 | 1181 |
| 1176 // Saturate the number of outstanding requests for our process. | 1182 // Saturate the number of outstanding requests for our process. |
| 1177 for (size_t i = 0; i < kMaxRequests; ++i) { | 1183 for (size_t i = 0; i < kMaxRequests; ++i) { |
| 1178 MakeTestRequest(filter_.get(), 0, i + 1, | 1184 MakeTestRequest(filter_.get(), 0, i + 1, |
| 1179 net::URLRequestTestJob::test_url_2()); | 1185 net::URLRequestTestJob::test_url_2()); |
| 1180 } | 1186 } |
| 1181 | 1187 |
| 1182 // Issue two more requests for our process -- these should fail immediately. | 1188 // Issue two more requests for our process -- these should fail immediately. |
| 1183 MakeTestRequest(filter_.get(), 0, kMaxRequests + 1, | 1189 MakeTestRequest(filter_.get(), 0, kMaxRequests + 1, |
| 1184 net::URLRequestTestJob::test_url_2()); | 1190 net::URLRequestTestJob::test_url_2()); |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1549 TransfersAllNavigationsContentBrowserClient new_client; | 1555 TransfersAllNavigationsContentBrowserClient new_client; |
| 1550 GetContentClient()->set_browser_for_testing(&new_client); | 1556 GetContentClient()->set_browser_for_testing(&new_client); |
| 1551 | 1557 |
| 1552 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); | 1558 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); |
| 1553 | 1559 |
| 1554 // Restore. | 1560 // Restore. |
| 1555 GetContentClient()->set_browser_for_testing(old_client); | 1561 GetContentClient()->set_browser_for_testing(old_client); |
| 1556 | 1562 |
| 1557 // This second filter is used to emulate a second process. | 1563 // This second filter is used to emulate a second process. |
| 1558 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( | 1564 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( |
| 1559 this, browser_context_->GetResourceContext()); | 1565 this, GetResourceContextForTest(browser_context_.get())); |
| 1560 | 1566 |
| 1561 int new_render_view_id = 1; | 1567 int new_render_view_id = 1; |
| 1562 int new_request_id = 2; | 1568 int new_request_id = 2; |
| 1563 | 1569 |
| 1564 const std::string kResponseBody = "hello world"; | 1570 const std::string kResponseBody = "hello world"; |
| 1565 SetResponse("HTTP/1.1 200 OK\n" | 1571 SetResponse("HTTP/1.1 200 OK\n" |
| 1566 "Content-Type: text/plain\n\n", | 1572 "Content-Type: text/plain\n\n", |
| 1567 kResponseBody); | 1573 kResponseBody); |
| 1568 | 1574 |
| 1569 ResourceHostMsg_Request request = | 1575 ResourceHostMsg_Request request = |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 TransfersAllNavigationsContentBrowserClient new_client; | 1614 TransfersAllNavigationsContentBrowserClient new_client; |
| 1609 GetContentClient()->set_browser_for_testing(&new_client); | 1615 GetContentClient()->set_browser_for_testing(&new_client); |
| 1610 | 1616 |
| 1611 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); | 1617 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); |
| 1612 | 1618 |
| 1613 // Restore. | 1619 // Restore. |
| 1614 GetContentClient()->set_browser_for_testing(old_client); | 1620 GetContentClient()->set_browser_for_testing(old_client); |
| 1615 | 1621 |
| 1616 // This second filter is used to emulate a second process. | 1622 // This second filter is used to emulate a second process. |
| 1617 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( | 1623 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter( |
| 1618 this, browser_context_->GetResourceContext()); | 1624 this, GetResourceContextForTest(browser_context_.get())); |
| 1619 | 1625 |
| 1620 int new_render_view_id = 1; | 1626 int new_render_view_id = 1; |
| 1621 int new_request_id = 2; | 1627 int new_request_id = 2; |
| 1622 | 1628 |
| 1623 // Delay the start of the next request so that we can setup the response for | 1629 // Delay the start of the next request so that we can setup the response for |
| 1624 // the next URL. | 1630 // the next URL. |
| 1625 SetDelayedStartJobGeneration(true); | 1631 SetDelayedStartJobGeneration(true); |
| 1626 | 1632 |
| 1627 SetResponse("HTTP/1.1 302 Found\n" | 1633 SetResponse("HTTP/1.1 302 Found\n" |
| 1628 "Location: http://other.com/blerg\n\n"); | 1634 "Location: http://other.com/blerg\n\n"); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1765 } | 1771 } |
| 1766 | 1772 |
| 1767 MessageLoop::current()->RunAllPending(); | 1773 MessageLoop::current()->RunAllPending(); |
| 1768 | 1774 |
| 1769 msgs.clear(); | 1775 msgs.clear(); |
| 1770 accum_.GetClassifiedMessages(&msgs); | 1776 accum_.GetClassifiedMessages(&msgs); |
| 1771 } | 1777 } |
| 1772 } | 1778 } |
| 1773 | 1779 |
| 1774 } // namespace content | 1780 } // namespace content |
| OLD | NEW |