| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/process_util.h" | 9 #include "base/process_util.h" |
| 10 #include "chrome/browser/child_process_security_policy.h" | 10 #include "chrome/browser/child_process_security_policy.h" |
| 11 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | 11 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
| 12 #include "chrome/common/chrome_plugin_lib.h" | 12 #include "chrome/common/chrome_plugin_lib.h" |
| 13 #include "chrome/common/render_messages.h" | 13 #include "chrome/common/render_messages.h" |
| 14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/http/http_util.h" |
| 15 #include "net/url_request/url_request.h" | 16 #include "net/url_request/url_request.h" |
| 16 #include "net/url_request/url_request_job.h" | 17 #include "net/url_request/url_request_job.h" |
| 17 #include "net/url_request/url_request_test_job.h" | 18 #include "net/url_request/url_request_test_job.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 19 #include "webkit/appcache/appcache_interfaces.h" | 20 #include "webkit/appcache/appcache_interfaces.h" |
| 20 | 21 |
| 22 namespace { |
| 23 |
| 24 // Returns the resource response header structure for this request. |
| 25 void GetResponseHead(const std::vector<IPC::Message>& messages, |
| 26 ResourceResponseHead* response_head) { |
| 27 ASSERT_GE(messages.size(), 2U); |
| 28 |
| 29 // The first messages should be received response. |
| 30 ASSERT_EQ(ViewMsg_Resource_ReceivedResponse::ID, messages[0].type()); |
| 31 |
| 32 void* iter = NULL; |
| 33 int request_id; |
| 34 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id)); |
| 35 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head)); |
| 36 } |
| 37 |
| 38 } // namespace |
| 39 |
| 21 static int RequestIDForMessage(const IPC::Message& msg) { | 40 static int RequestIDForMessage(const IPC::Message& msg) { |
| 22 int request_id = -1; | 41 int request_id = -1; |
| 23 switch (msg.type()) { | 42 switch (msg.type()) { |
| 24 case ViewMsg_Resource_UploadProgress::ID: | 43 case ViewMsg_Resource_UploadProgress::ID: |
| 25 case ViewMsg_Resource_ReceivedResponse::ID: | 44 case ViewMsg_Resource_ReceivedResponse::ID: |
| 26 case ViewMsg_Resource_ReceivedRedirect::ID: | 45 case ViewMsg_Resource_ReceivedRedirect::ID: |
| 27 case ViewMsg_Resource_DataReceived::ID: | 46 case ViewMsg_Resource_DataReceived::ID: |
| 28 case ViewMsg_Resource_RequestComplete::ID: | 47 case ViewMsg_Resource_RequestComplete::ID: |
| 29 request_id = IPC::MessageIterator(msg).NextInt(); | 48 request_id = IPC::MessageIterator(msg).NextInt(); |
| 30 break; | 49 break; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 } | 104 } |
| 86 messages_.erase(messages_.begin()); | 105 messages_.erase(messages_.begin()); |
| 87 msgs->push_back(cur_requests); | 106 msgs->push_back(cur_requests); |
| 88 } | 107 } |
| 89 } | 108 } |
| 90 | 109 |
| 91 class ResourceDispatcherHostTest : public testing::Test, | 110 class ResourceDispatcherHostTest : public testing::Test, |
| 92 public ResourceDispatcherHost::Receiver { | 111 public ResourceDispatcherHost::Receiver { |
| 93 public: | 112 public: |
| 94 ResourceDispatcherHostTest() | 113 ResourceDispatcherHostTest() |
| 95 : Receiver(ChildProcessInfo::RENDER_PROCESS), host_(NULL), pid_(-1) { | 114 : Receiver(ChildProcessInfo::RENDER_PROCESS), host_(NULL), pid_(-1), |
| 115 old_factory_(NULL) { |
| 96 set_handle(base::GetCurrentProcessHandle()); | 116 set_handle(base::GetCurrentProcessHandle()); |
| 97 } | 117 } |
| 98 // ResourceDispatcherHost::Receiver implementation | 118 // ResourceDispatcherHost::Receiver implementation |
| 99 virtual bool Send(IPC::Message* msg) { | 119 virtual bool Send(IPC::Message* msg) { |
| 100 accum_.AddMessage(*msg); | 120 accum_.AddMessage(*msg); |
| 101 delete msg; | 121 delete msg; |
| 102 return true; | 122 return true; |
| 103 } | 123 } |
| 104 | 124 |
| 105 URLRequestContext* GetRequestContext( | 125 URLRequestContext* GetRequestContext( |
| 106 uint32 request_id, | 126 uint32 request_id, |
| 107 const ViewHostMsg_Resource_Request& request_data) { | 127 const ViewHostMsg_Resource_Request& request_data) { |
| 108 return NULL; | 128 return NULL; |
| 109 } | 129 } |
| 110 | 130 |
| 111 virtual int GetProcessId() const { return pid_; } | 131 virtual int GetProcessId() const { return pid_; } |
| 112 | 132 |
| 113 protected: | 133 protected: |
| 114 // testing::Test | 134 // testing::Test |
| 115 virtual void SetUp() { | 135 virtual void SetUp() { |
| 136 DCHECK(!test_fixture_); |
| 137 test_fixture_ = this; |
| 116 ChildProcessSecurityPolicy::GetInstance()->Add(0); | 138 ChildProcessSecurityPolicy::GetInstance()->Add(0); |
| 117 URLRequest::RegisterProtocolFactory("test", &URLRequestTestJob::Factory); | 139 URLRequest::RegisterProtocolFactory("test", |
| 140 &ResourceDispatcherHostTest::Factory); |
| 118 EnsureTestSchemeIsAllowed(); | 141 EnsureTestSchemeIsAllowed(); |
| 119 } | 142 } |
| 120 virtual void TearDown() { | 143 virtual void TearDown() { |
| 121 URLRequest::RegisterProtocolFactory("test", NULL); | 144 URLRequest::RegisterProtocolFactory("test", NULL); |
| 145 if (!scheme_.empty()) |
| 146 URLRequest::RegisterProtocolFactory(scheme_, old_factory_); |
| 147 |
| 148 DCHECK(test_fixture_ == this); |
| 149 test_fixture_ = NULL; |
| 150 |
| 122 ChildProcessSecurityPolicy::GetInstance()->Remove(0); | 151 ChildProcessSecurityPolicy::GetInstance()->Remove(0); |
| 123 | 152 |
| 124 // The plugin lib is automatically loaded during these test | 153 // The plugin lib is automatically loaded during these test |
| 125 // and we want a clean environment for other tests. | 154 // and we want a clean environment for other tests. |
| 126 ChromePluginLib::UnloadAllPlugins(); | 155 ChromePluginLib::UnloadAllPlugins(); |
| 127 | 156 |
| 128 // Flush the message loop to make Purify happy. | 157 // Flush the message loop to make Purify happy. |
| 129 message_loop_.RunAllPending(); | 158 message_loop_.RunAllPending(); |
| 130 } | 159 } |
| 131 | 160 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 142 | 171 |
| 143 void EnsureTestSchemeIsAllowed() { | 172 void EnsureTestSchemeIsAllowed() { |
| 144 static bool have_white_listed_test_scheme = false; | 173 static bool have_white_listed_test_scheme = false; |
| 145 | 174 |
| 146 if (!have_white_listed_test_scheme) { | 175 if (!have_white_listed_test_scheme) { |
| 147 ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme("test"); | 176 ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme("test"); |
| 148 have_white_listed_test_scheme = true; | 177 have_white_listed_test_scheme = true; |
| 149 } | 178 } |
| 150 } | 179 } |
| 151 | 180 |
| 181 // Set a particular response for any request from now on. To switch back to |
| 182 // the default bahavior, pass an empty |headers|. |headers| should be raw- |
| 183 // formatted (NULLs instead of EOLs). |
| 184 void SetResponse(const std::string& headers, const std::string& data) { |
| 185 response_headers_ = headers; |
| 186 response_data_ = data; |
| 187 } |
| 188 |
| 189 // Intercept requests for the given protocol. |
| 190 void HandleScheme(const std::string& scheme) { |
| 191 DCHECK(scheme_.empty()); |
| 192 DCHECK(!old_factory_); |
| 193 scheme_ = scheme; |
| 194 old_factory_ = URLRequest::RegisterProtocolFactory( |
| 195 scheme_, &ResourceDispatcherHostTest::Factory); |
| 196 } |
| 197 |
| 198 // Our own URLRequestJob factory. |
| 199 static URLRequestJob* Factory(URLRequest* request, |
| 200 const std::string& scheme) { |
| 201 if (test_fixture_->response_headers_.empty()) { |
| 202 return new URLRequestTestJob(request); |
| 203 } else { |
| 204 return new URLRequestTestJob(request, test_fixture_->response_headers_, |
| 205 test_fixture_->response_data_, false); |
| 206 } |
| 207 } |
| 208 |
| 152 MessageLoopForIO message_loop_; | 209 MessageLoopForIO message_loop_; |
| 153 ResourceDispatcherHost host_; | 210 ResourceDispatcherHost host_; |
| 154 ResourceIPCAccumulator accum_; | 211 ResourceIPCAccumulator accum_; |
| 155 int pid_; | 212 int pid_; |
| 213 std::string response_headers_; |
| 214 std::string response_data_; |
| 215 std::string scheme_; |
| 216 URLRequest::ProtocolFactory* old_factory_; |
| 217 static ResourceDispatcherHostTest* test_fixture_; |
| 156 }; | 218 }; |
| 219 // Static. |
| 220 ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL; |
| 221 |
| 157 | 222 |
| 158 // Spin up the message loop to kick off the request. | 223 // Spin up the message loop to kick off the request. |
| 159 static void KickOffRequest() { | 224 static void KickOffRequest() { |
| 160 MessageLoop::current()->RunAllPending(); | 225 MessageLoop::current()->RunAllPending(); |
| 161 } | 226 } |
| 162 | 227 |
| 163 void ResourceDispatcherHostTest::MakeTestRequest(int render_process_id, | 228 void ResourceDispatcherHostTest::MakeTestRequest(int render_process_id, |
| 164 int render_view_id, | 229 int render_view_id, |
| 165 int request_id, | 230 int request_id, |
| 166 const GURL& url) { | 231 const GURL& url) { |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 EXPECT_EQ(URLRequestStatus::CANCELED, status.status()); | 707 EXPECT_EQ(URLRequestStatus::CANCELED, status.status()); |
| 643 EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, status.os_error()); | 708 EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, status.os_error()); |
| 644 } | 709 } |
| 645 | 710 |
| 646 // The final 2 requests should have succeeded. | 711 // The final 2 requests should have succeeded. |
| 647 CheckSuccessfulRequest(msgs[kMaxRequests + 2], | 712 CheckSuccessfulRequest(msgs[kMaxRequests + 2], |
| 648 URLRequestTestJob::test_data_2()); | 713 URLRequestTestJob::test_data_2()); |
| 649 CheckSuccessfulRequest(msgs[kMaxRequests + 3], | 714 CheckSuccessfulRequest(msgs[kMaxRequests + 3], |
| 650 URLRequestTestJob::test_data_2()); | 715 URLRequestTestJob::test_data_2()); |
| 651 } | 716 } |
| 717 |
| 718 // Tests that we sniff the mime type for a simple request. |
| 719 TEST_F(ResourceDispatcherHostTest, MimeSniffed) { |
| 720 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); |
| 721 |
| 722 std::string response("HTTP/1.1 200 OK\n\n"); |
| 723 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), |
| 724 response.size())); |
| 725 std::string response_data("<html><title>Test One</title></html>"); |
| 726 SetResponse(raw_headers, response_data); |
| 727 |
| 728 HandleScheme("http"); |
| 729 MakeTestRequest(0, 0, 1, GURL("http:bla")); |
| 730 |
| 731 // Flush all pending requests. |
| 732 while (URLRequestTestJob::ProcessOnePendingMessage()); |
| 733 |
| 734 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); |
| 735 |
| 736 // Sorts out all the messages we saw by request. |
| 737 ResourceIPCAccumulator::ClassifiedMessages msgs; |
| 738 accum_.GetClassifiedMessages(&msgs); |
| 739 ASSERT_EQ(1U, msgs.size()); |
| 740 |
| 741 ResourceResponseHead response_head; |
| 742 GetResponseHead(msgs[0], &response_head); |
| 743 ASSERT_EQ("text/html", response_head.mime_type); |
| 744 } |
| 745 |
| 746 // Tests that we don't sniff the mime type when the server provides one. |
| 747 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) { |
| 748 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); |
| 749 |
| 750 std::string response("HTTP/1.1 200 OK\n" |
| 751 "Content-type: image/jpeg\n\n"); |
| 752 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), |
| 753 response.size())); |
| 754 std::string response_data("<html><title>Test One</title></html>"); |
| 755 SetResponse(raw_headers, response_data); |
| 756 |
| 757 HandleScheme("http"); |
| 758 MakeTestRequest(0, 0, 1, GURL("http:bla")); |
| 759 |
| 760 // Flush all pending requests. |
| 761 while (URLRequestTestJob::ProcessOnePendingMessage()); |
| 762 |
| 763 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); |
| 764 |
| 765 // Sorts out all the messages we saw by request. |
| 766 ResourceIPCAccumulator::ClassifiedMessages msgs; |
| 767 accum_.GetClassifiedMessages(&msgs); |
| 768 ASSERT_EQ(1U, msgs.size()); |
| 769 |
| 770 ResourceResponseHead response_head; |
| 771 GetResponseHead(msgs[0], &response_head); |
| 772 ASSERT_EQ("image/jpeg", response_head.mime_type); |
| 773 } |
| 774 |
| 775 // Tests that we don't sniff the mime type when there is no message body. |
| 776 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) { |
| 777 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); |
| 778 |
| 779 std::string response("HTTP/1.1 304 Not Modified\n\n"); |
| 780 std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(), |
| 781 response.size())); |
| 782 std::string response_data; |
| 783 SetResponse(raw_headers, response_data); |
| 784 |
| 785 HandleScheme("http"); |
| 786 MakeTestRequest(0, 0, 1, GURL("http:bla")); |
| 787 |
| 788 // Flush all pending requests. |
| 789 while (URLRequestTestJob::ProcessOnePendingMessage()); |
| 790 |
| 791 EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0)); |
| 792 |
| 793 // Sorts out all the messages we saw by request. |
| 794 ResourceIPCAccumulator::ClassifiedMessages msgs; |
| 795 accum_.GetClassifiedMessages(&msgs); |
| 796 ASSERT_EQ(1U, msgs.size()); |
| 797 |
| 798 ResourceResponseHead response_head; |
| 799 GetResponseHead(msgs[0], &response_head); |
| 800 ASSERT_EQ("", response_head.mime_type); |
| 801 } |
| OLD | NEW |