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 |