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
3 // found in the LICENSE file.
8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/pickle.h"
12 #include "base/run_loop.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_split.h"
15 #include "content/browser/browser_thread_impl.h"
16 #include "content/browser/child_process_security_policy_impl.h"
17 #include "content/browser/loader/resource_dispatcher_host_impl.h"
18 #include "content/browser/loader/resource_message_filter.h"
19 #include "content/browser/loader/resource_request_info_impl.h"
20 #include "content/browser/worker_host/worker_service_impl.h"
21 #include "content/common/child_process_host_impl.h"
22 #include "content/common/resource_messages.h"
23 #include "content/common/view_messages.h"
24 #include "content/public/browser/global_request_id.h"
25 #include "content/public/browser/resource_context.h"
26 #include "content/public/browser/resource_dispatcher_host_delegate.h"
27 #include "content/public/browser/resource_request_info.h"
28 #include "content/public/browser/resource_throttle.h"
29 #include "content/public/common/process_type.h"
30 #include "content/public/common/resource_response.h"
31 #include "content/public/test/test_browser_context.h"
32 #include "content/test/test_content_browser_client.h"
33 #include "net/base/net_errors.h"
34 #include "net/base/request_priority.h"
35 #include "net/base/upload_bytes_element_reader.h"
36 #include "net/base/upload_data_stream.h"
37 #include "net/http/http_util.h"
38 #include "net/url_request/url_request.h"
39 #include "net/url_request/url_request_context.h"
40 #include "net/url_request/url_request_job.h"
41 #include "net/url_request/url_request_simple_job.h"
42 #include "net/url_request/url_request_test_job.h"
43 #include "testing/gtest/include/gtest/gtest.h"
44 #include "webkit/common/appcache/appcache_interfaces.h"
46 // TODO(eroman): Write unit tests for SafeBrowsing that exercise
47 // SafeBrowsingResourceHandler.
53 // Returns the resource response header structure for this request.
54 void GetResponseHead(const std::vector<IPC::Message>& messages,
55 ResourceResponseHead* response_head) {
56 ASSERT_GE(messages.size(), 2U);
58 // The first messages should be received response.
59 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
61 PickleIterator iter(messages[0]);
63 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id));
64 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head));
67 void GenerateIPCMessage(
68 scoped_refptr<ResourceMessageFilter> filter,
69 scoped_ptr<IPC::Message> message) {
71 ResourceDispatcherHostImpl::Get()->OnMessageReceived(
72 *message, filter.get(), &msg_is_ok);
77 static int RequestIDForMessage(const IPC::Message& msg) {
80 case ResourceMsg_UploadProgress::ID:
81 case ResourceMsg_ReceivedResponse::ID:
82 case ResourceMsg_ReceivedRedirect::ID:
83 case ResourceMsg_SetDataBuffer::ID:
84 case ResourceMsg_DataReceived::ID:
85 case ResourceMsg_RequestComplete::ID: {
86 bool result = PickleIterator(msg).ReadInt(&request_id);
94 static ResourceHostMsg_Request CreateResourceRequest(
96 ResourceType::Type type,
98 ResourceHostMsg_Request request;
99 request.method = std::string(method);
101 request.first_party_for_cookies = url; // bypass third-party cookie blocking
102 request.referrer_policy = WebKit::WebReferrerPolicyDefault;
103 request.load_flags = 0;
104 request.origin_pid = 0;
105 request.resource_type = type;
106 request.request_context = 0;
107 request.appcache_host_id = appcache::kNoHostId;
108 request.download_to_file = false;
109 request.is_main_frame = true;
110 request.frame_id = 0;
111 request.parent_is_main_frame = false;
112 request.parent_frame_id = -1;
113 request.transition_type = PAGE_TRANSITION_LINK;
114 request.allow_download = true;
118 // Spin up the message loop to kick off the request.
119 static void KickOffRequest() {
120 base::MessageLoop::current()->RunUntilIdle();
123 // We may want to move this to a shared space if it is useful for something else
124 class ResourceIPCAccumulator {
126 void AddMessage(const IPC::Message& msg) {
127 messages_.push_back(msg);
130 // This groups the messages by their request ID. The groups will be in order
131 // that the first message for each request ID was received, and the messages
132 // within the groups will be in the order that they appeared.
133 // Note that this clears messages_.
134 typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
135 void GetClassifiedMessages(ClassifiedMessages* msgs);
138 std::vector<IPC::Message> messages_;
141 // This is very inefficient as a result of repeatedly extracting the ID, use
143 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) {
144 while (!messages_.empty()) {
145 // Ignore unknown message types as it is valid for code to generated other
146 // IPCs as side-effects that we are not testing here.
147 int cur_id = RequestIDForMessage(messages_[0]);
149 std::vector<IPC::Message> cur_requests;
150 cur_requests.push_back(messages_[0]);
151 // find all other messages with this ID
152 for (int i = 1; i < static_cast<int>(messages_.size()); i++) {
153 int id = RequestIDForMessage(messages_[i]);
155 cur_requests.push_back(messages_[i]);
156 messages_.erase(messages_.begin() + i);
160 msgs->push_back(cur_requests);
162 messages_.erase(messages_.begin());
166 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
167 // 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
169 // messages to go to the same place, which is why this forwards.
170 class ForwardingFilter : public ResourceMessageFilter {
172 explicit ForwardingFilter(IPC::Sender* dest,
173 ResourceContext* resource_context)
174 : ResourceMessageFilter(
175 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
176 PROCESS_TYPE_RENDERER, NULL, NULL, NULL,
177 base::Bind(&ForwardingFilter::GetContexts,
178 base::Unretained(this))),
180 resource_context_(resource_context) {
181 set_peer_pid_for_testing(base::GetCurrentProcId());
184 // ResourceMessageFilter override
185 virtual bool Send(IPC::Message* msg) OVERRIDE {
188 return dest_->Send(msg);
191 ResourceContext* resource_context() { return resource_context_; }
194 virtual ~ForwardingFilter() {}
197 void GetContexts(const ResourceHostMsg_Request& request,
198 ResourceContext** resource_context,
199 net::URLRequestContext** request_context) {
200 *resource_context = resource_context_;
201 *request_context = resource_context_->GetRequestContext();
205 ResourceContext* resource_context_;
207 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
210 // This class is a variation on URLRequestTestJob in that it does
211 // not complete start upon entry, only when specifically told to.
212 class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
214 URLRequestTestDelayedStartJob(net::URLRequest* request,
215 net::NetworkDelegate* network_delegate)
216 : net::URLRequestTestJob(request, network_delegate) {
219 URLRequestTestDelayedStartJob(net::URLRequest* request,
220 net::NetworkDelegate* network_delegate,
222 : net::URLRequestTestJob(request, network_delegate, auto_advance) {
225 URLRequestTestDelayedStartJob(net::URLRequest* request,
226 net::NetworkDelegate* network_delegate,
227 const std::string& response_headers,
228 const std::string& response_data,
230 : net::URLRequestTestJob(request,
238 // Do nothing until you're told to.
239 virtual void Start() OVERRIDE {}
241 // Finish starting a URL request whose job is an instance of
242 // URLRequestTestDelayedStartJob. It is illegal to call this routine
243 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
244 static void CompleteStart(net::URLRequest* request) {
245 for (URLRequestTestDelayedStartJob* job = list_head_;
248 if (job->request() == request) {
249 job->net::URLRequestTestJob::Start();
256 static bool DelayedStartQueueEmpty() {
260 static void ClearQueue() {
263 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
264 << "; may result in leaks.";
270 virtual ~URLRequestTestDelayedStartJob() {
271 for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
272 job = &(*job)->next_) {
274 *job = (*job)->next_;
287 static URLRequestTestDelayedStartJob* list_head_;
288 URLRequestTestDelayedStartJob* next_;
291 URLRequestTestDelayedStartJob*
292 URLRequestTestDelayedStartJob::list_head_ = NULL;
294 // This class is a variation on URLRequestTestJob in that it
295 // returns IO_pending errors before every read, not just the first one.
296 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
298 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
299 net::NetworkDelegate* network_delegate)
300 : net::URLRequestTestJob(request, network_delegate) {}
301 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
302 net::NetworkDelegate* network_delegate,
304 : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
305 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
306 net::NetworkDelegate* network_delegate,
307 const std::string& response_headers,
308 const std::string& response_data,
310 : net::URLRequestTestJob(request,
317 virtual ~URLRequestTestDelayedCompletionJob() {}
320 virtual bool NextReadAsync() OVERRIDE { return true; }
323 class URLRequestBigJob : public net::URLRequestSimpleJob {
325 URLRequestBigJob(net::URLRequest* request,
326 net::NetworkDelegate* network_delegate)
327 : net::URLRequestSimpleJob(request, network_delegate) {
330 virtual int GetData(std::string* mime_type,
331 std::string* charset,
333 const net::CompletionCallback& callback) const OVERRIDE {
334 *mime_type = "text/plain";
339 if (!ParseURL(request_->url(), &text, &count))
340 return net::ERR_INVALID_URL;
342 data->reserve(text.size() * count);
343 for (int i = 0; i < count; ++i)
350 virtual ~URLRequestBigJob() {}
352 // big-job:substring,N
353 static bool ParseURL(const GURL& url, std::string* text, int* count) {
354 std::vector<std::string> parts;
355 base::SplitString(url.path(), ',', &parts);
357 if (parts.size() != 2)
361 return base::StringToInt(parts[1], count);
365 // Associated with an URLRequest to determine if the URLRequest gets deleted.
366 class TestUserData : public base::SupportsUserData::Data {
368 explicit TestUserData(bool* was_deleted)
369 : was_deleted_(was_deleted) {
372 virtual ~TestUserData() {
373 *was_deleted_ = true;
380 class TransfersAllNavigationsContentBrowserClient
381 : public TestContentBrowserClient {
383 virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context,
384 const GURL& current_url,
385 const GURL& new_url) OVERRIDE {
390 enum GenericResourceThrottleFlags {
392 DEFER_STARTING_REQUEST = 1 << 0,
393 DEFER_PROCESSING_RESPONSE = 1 << 1,
394 CANCEL_BEFORE_START = 1 << 2
397 // Throttle that tracks the current throttle blocking a request. Only one
398 // can throttle any request at a time.
399 class GenericResourceThrottle : public ResourceThrottle {
401 // The value is used to indicate that the throttle should not provide
402 // a error code when cancelling a request. net::OK is used, because this
403 // is not an error code.
404 static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;
406 GenericResourceThrottle(int flags, int code)
408 error_code_for_cancellation_(code) {
411 virtual ~GenericResourceThrottle() {
412 if (active_throttle_ == this)
413 active_throttle_ = NULL;
416 // ResourceThrottle implementation:
417 virtual void WillStartRequest(bool* defer) OVERRIDE {
418 ASSERT_EQ(NULL, active_throttle_);
419 if (flags_ & DEFER_STARTING_REQUEST) {
420 active_throttle_ = this;
424 if (flags_ & CANCEL_BEFORE_START) {
425 if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
426 controller()->Cancel();
428 controller()->CancelWithError(error_code_for_cancellation_);
433 virtual void WillProcessResponse(bool* defer) OVERRIDE {
434 ASSERT_EQ(NULL, active_throttle_);
435 if (flags_ & DEFER_PROCESSING_RESPONSE) {
436 active_throttle_ = this;
442 ASSERT_TRUE(this == active_throttle_);
443 active_throttle_ = NULL;
444 controller()->Resume();
447 static GenericResourceThrottle* active_throttle() {
448 return active_throttle_;
452 int flags_; // bit-wise union of GenericResourceThrottleFlags.
453 int error_code_for_cancellation_;
455 // The currently active throttle, if any.
456 static GenericResourceThrottle* active_throttle_;
459 GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
461 class TestResourceDispatcherHostDelegate
462 : public ResourceDispatcherHostDelegate {
464 TestResourceDispatcherHostDelegate()
465 : create_two_throttles_(false),
467 error_code_for_cancellation_(
468 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
471 void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
472 user_data_.reset(user_data);
475 void set_flags(int value) {
479 void set_error_code_for_cancellation(int code) {
480 error_code_for_cancellation_ = code;
483 void set_create_two_throttles(bool create_two_throttles) {
484 create_two_throttles_ = create_two_throttles;
487 // ResourceDispatcherHostDelegate implementation:
489 virtual void RequestBeginning(
490 net::URLRequest* request,
491 ResourceContext* resource_context,
492 appcache::AppCacheService* appcache_service,
493 ResourceType::Type resource_type,
496 ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
498 const void* key = user_data_.get();
499 request->SetUserData(key, user_data_.release());
502 if (flags_ != NONE) {
503 throttles->push_back(new GenericResourceThrottle(
504 flags_, error_code_for_cancellation_));
505 if (create_two_throttles_)
506 throttles->push_back(new GenericResourceThrottle(
507 flags_, error_code_for_cancellation_));
512 bool create_two_throttles_;
514 int error_code_for_cancellation_;
515 scoped_ptr<base::SupportsUserData::Data> user_data_;
518 class ResourceDispatcherHostTest : public testing::Test,
521 ResourceDispatcherHostTest()
522 : ui_thread_(BrowserThread::UI, &message_loop_),
523 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_),
524 cache_thread_(BrowserThread::CACHE, &message_loop_),
525 io_thread_(BrowserThread::IO, &message_loop_),
527 resource_type_(ResourceType::SUB_RESOURCE),
528 send_data_received_acks_(false) {
529 browser_context_.reset(new TestBrowserContext());
530 BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
531 message_loop_.RunUntilIdle();
532 filter_ = new ForwardingFilter(
533 this, browser_context_->GetResourceContext());
536 virtual ~ResourceDispatcherHostTest() {
537 for (std::set<int>::iterator it = child_ids_.begin();
538 it != child_ids_.end(); ++it) {
539 host_.CancelRequestsForProcess(*it);
543 // IPC::Sender implementation
544 virtual bool Send(IPC::Message* msg) OVERRIDE {
545 accum_.AddMessage(*msg);
547 if (send_data_received_acks_ &&
548 msg->type() == ResourceMsg_DataReceived::ID) {
549 GenerateDataReceivedACK(*msg);
558 virtual void SetUp() {
559 DCHECK(!test_fixture_);
560 test_fixture_ = this;
561 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
562 net::URLRequest::Deprecated::RegisterProtocolFactory(
564 &ResourceDispatcherHostTest::Factory);
565 EnsureTestSchemeIsAllowed();
566 delay_start_ = false;
567 delay_complete_ = false;
568 url_request_jobs_created_count_ = 0;
571 virtual void TearDown() {
572 net::URLRequest::Deprecated::RegisterProtocolFactory("test", NULL);
573 if (!scheme_.empty())
574 net::URLRequest::Deprecated::RegisterProtocolFactory(
575 scheme_, old_factory_);
577 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
578 URLRequestTestDelayedStartJob::ClearQueue();
580 DCHECK(test_fixture_ == this);
581 test_fixture_ = NULL;
585 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
587 // Flush the message loop to make application verifiers happy.
588 if (ResourceDispatcherHostImpl::Get())
589 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
590 browser_context_->GetResourceContext());
592 WorkerServiceImpl::GetInstance()->PerformTeardownForTesting();
594 browser_context_.reset();
595 message_loop_.RunUntilIdle();
598 // Creates a request using the current test object as the filter.
599 void MakeTestRequest(int render_view_id,
603 // Generates a request using the given filter. This will probably be a
605 void MakeTestRequest(ResourceMessageFilter* filter,
610 void CancelRequest(int request_id);
612 void CompleteStartRequest(int request_id);
613 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
615 void EnsureSchemeIsAllowed(const std::string& scheme) {
616 ChildProcessSecurityPolicyImpl* policy =
617 ChildProcessSecurityPolicyImpl::GetInstance();
618 if (!policy->IsWebSafeScheme(scheme))
619 policy->RegisterWebSafeScheme(scheme);
622 void EnsureTestSchemeIsAllowed() {
623 EnsureSchemeIsAllowed("test");
626 // Sets a particular response for any request from now on. To switch back to
627 // the default bahavior, pass an empty |headers|. |headers| should be raw-
628 // formatted (NULLs instead of EOLs).
629 void SetResponse(const std::string& headers, const std::string& data) {
630 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
632 response_data_ = data;
634 void SetResponse(const std::string& headers) {
635 SetResponse(headers, std::string());
638 // Sets a particular resource type for any request from now on.
639 void SetResourceType(ResourceType::Type type) {
640 resource_type_ = type;
643 void SendDataReceivedACKs(bool send_acks) {
644 send_data_received_acks_ = send_acks;
647 // Intercepts requests for the given protocol.
648 void HandleScheme(const std::string& scheme) {
649 DCHECK(scheme_.empty());
650 DCHECK(!old_factory_);
652 old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory(
653 scheme_, &ResourceDispatcherHostTest::Factory);
654 EnsureSchemeIsAllowed(scheme);
657 // Our own net::URLRequestJob factory.
658 static net::URLRequestJob* Factory(net::URLRequest* request,
659 net::NetworkDelegate* network_delegate,
660 const std::string& scheme) {
661 url_request_jobs_created_count_++;
662 if (test_fixture_->response_headers_.empty()) {
664 return new URLRequestTestDelayedStartJob(request, network_delegate);
665 } else if (delay_complete_) {
666 return new URLRequestTestDelayedCompletionJob(request,
668 } else if (scheme == "big-job") {
669 return new URLRequestBigJob(request, network_delegate);
671 return new net::URLRequestTestJob(request, network_delegate);
675 return new URLRequestTestDelayedStartJob(
676 request, network_delegate,
677 test_fixture_->response_headers_, test_fixture_->response_data_,
679 } else if (delay_complete_) {
680 return new URLRequestTestDelayedCompletionJob(
681 request, network_delegate,
682 test_fixture_->response_headers_, test_fixture_->response_data_,
685 return new net::URLRequestTestJob(
686 request, network_delegate,
687 test_fixture_->response_headers_, test_fixture_->response_data_,
693 void SetDelayedStartJobGeneration(bool delay_job_start) {
694 delay_start_ = delay_job_start;
697 void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
698 delay_complete_ = delay_job_complete;
701 void GenerateDataReceivedACK(const IPC::Message& msg) {
702 EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
705 bool result = PickleIterator(msg).ReadInt(&request_id);
707 scoped_ptr<IPC::Message> ack(
708 new ResourceHostMsg_DataReceived_ACK(request_id));
710 base::MessageLoop::current()->PostTask(
712 base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
715 base::MessageLoopForIO message_loop_;
716 BrowserThreadImpl ui_thread_;
717 BrowserThreadImpl file_thread_;
718 BrowserThreadImpl cache_thread_;
719 BrowserThreadImpl io_thread_;
720 scoped_ptr<TestBrowserContext> browser_context_;
721 scoped_refptr<ForwardingFilter> filter_;
722 ResourceDispatcherHostImpl host_;
723 ResourceIPCAccumulator accum_;
724 std::string response_headers_;
725 std::string response_data_;
727 net::URLRequest::ProtocolFactory* old_factory_;
728 ResourceType::Type resource_type_;
729 bool send_data_received_acks_;
730 std::set<int> child_ids_;
731 static ResourceDispatcherHostTest* test_fixture_;
732 static bool delay_start_;
733 static bool delay_complete_;
734 static int url_request_jobs_created_count_;
737 ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL;
738 bool ResourceDispatcherHostTest::delay_start_ = false;
739 bool ResourceDispatcherHostTest::delay_complete_ = false;
740 int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0;
742 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
745 MakeTestRequest(filter_.get(), render_view_id, request_id, url);
748 void ResourceDispatcherHostTest::MakeTestRequest(
749 ResourceMessageFilter* filter,
753 // If it's already there, this'll be dropped on the floor, which is fine.
754 child_ids_.insert(filter->child_id());
756 ResourceHostMsg_Request request =
757 CreateResourceRequest("GET", resource_type_, url);
758 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
760 host_.OnMessageReceived(msg, filter, &msg_was_ok);
764 void ResourceDispatcherHostTest::CancelRequest(int request_id) {
765 host_.CancelRequest(filter_->child_id(), request_id, false);
768 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
769 CompleteStartRequest(filter_.get(), request_id);
772 void ResourceDispatcherHostTest::CompleteStartRequest(
773 ResourceMessageFilter* filter,
775 GlobalRequestID gid(filter->child_id(), request_id);
776 net::URLRequest* req = host_.GetURLRequest(gid);
779 URLRequestTestDelayedStartJob::CompleteStart(req);
782 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
783 const std::string& reference_data) {
784 // A successful request will have received 4 messages:
785 // ReceivedResponse (indicates headers received)
786 // SetDataBuffer (contains shared memory handle)
787 // DataReceived (data offset and length into shared memory)
788 // RequestComplete (request is done)
790 // This function verifies that we received 4 messages and that they
792 ASSERT_EQ(4U, messages.size());
794 // The first messages should be received response
795 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
797 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
799 PickleIterator iter(messages[1]);
801 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
802 base::SharedMemoryHandle shm_handle;
803 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
805 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
807 // Followed by the data, currently we only do the data in one chunk, but
808 // should probably test multiple chunks later
809 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
811 PickleIterator iter2(messages[2]);
812 ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &request_id));
814 ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &data_offset));
816 ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &data_length));
818 ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
819 ASSERT_GE(shm_size, data_length);
821 base::SharedMemory shared_mem(shm_handle, true); // read only
822 shared_mem.Map(data_length);
823 const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
824 ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
826 // The last message should be all data received.
827 ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[3].type());
830 void CheckFailedRequest(const std::vector<IPC::Message>& messages,
831 const std::string& reference_data,
832 int expected_error) {
833 ASSERT_LT(0U, messages.size());
834 ASSERT_GE(2U, messages.size());
835 size_t failure_index = messages.size() - 1;
837 if (messages.size() == 2) {
838 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
840 EXPECT_EQ(ResourceMsg_RequestComplete::ID, messages[failure_index].type());
845 PickleIterator iter(messages[failure_index]);
846 EXPECT_TRUE(IPC::ReadParam(&messages[failure_index], &iter, &request_id));
847 EXPECT_TRUE(IPC::ReadParam(&messages[failure_index], &iter, &error_code));
848 EXPECT_EQ(expected_error, error_code);
851 // Tests whether many messages get dispatched properly.
852 TEST_F(ResourceDispatcherHostTest, TestMany) {
853 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
854 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
855 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
857 // flush all the pending requests
858 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
860 // sorts out all the messages we saw by request
861 ResourceIPCAccumulator::ClassifiedMessages msgs;
862 accum_.GetClassifiedMessages(&msgs);
864 // there are three requests, so we should have gotten them classified as such
865 ASSERT_EQ(3U, msgs.size());
867 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
868 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
869 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
872 void CheckCancelledRequestCompleteMessage(const IPC::Message& message) {
873 ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
878 PickleIterator iter(message);
879 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
880 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
882 EXPECT_EQ(net::ERR_ABORTED, error_code);
885 // Tests whether messages get canceled properly. We issue three requests,
886 // cancel one of them, and make sure that each sent the proper notifications.
887 TEST_F(ResourceDispatcherHostTest, Cancel) {
888 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
889 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
890 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
893 // flush all the pending requests
894 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
895 base::MessageLoop::current()->RunUntilIdle();
897 ResourceIPCAccumulator::ClassifiedMessages msgs;
898 accum_.GetClassifiedMessages(&msgs);
900 // there are three requests, so we should have gotten them classified as such
901 ASSERT_EQ(3U, msgs.size());
903 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
904 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
906 // Check that request 2 got canceled.
907 ASSERT_EQ(2U, msgs[1].size());
908 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
909 CheckCancelledRequestCompleteMessage(msgs[1][1]);
912 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
913 bool was_deleted = false;
915 // Arrange to have requests deferred before starting.
916 TestResourceDispatcherHostDelegate delegate;
917 delegate.set_flags(DEFER_STARTING_REQUEST);
918 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
919 host_.SetDelegate(&delegate);
921 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
924 // Our TestResourceThrottle should not have been deleted yet. This is to
925 // ensure that destruction of the URLRequest happens asynchronously to
926 // calling CancelRequest.
927 EXPECT_FALSE(was_deleted);
929 // flush all the pending requests
930 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
931 base::MessageLoop::current()->RunUntilIdle();
933 EXPECT_TRUE(was_deleted);
936 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
937 // URLRequest will not be started.
938 TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
939 TestResourceDispatcherHostDelegate delegate;
940 delegate.set_flags(CANCEL_BEFORE_START);
941 host_.SetDelegate(&delegate);
943 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
945 // flush all the pending requests
946 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
947 base::MessageLoop::current()->RunUntilIdle();
949 ResourceIPCAccumulator::ClassifiedMessages msgs;
950 accum_.GetClassifiedMessages(&msgs);
952 // Check that request got canceled.
953 ASSERT_EQ(1U, msgs[0].size());
954 CheckCancelledRequestCompleteMessage(msgs[0][0]);
956 // Make sure URLRequest is never started.
957 EXPECT_EQ(0, url_request_jobs_created_count_);
960 TEST_F(ResourceDispatcherHostTest, PausedStartError) {
961 // Arrange to have requests deferred before processing response headers.
962 TestResourceDispatcherHostDelegate delegate;
963 delegate.set_flags(DEFER_PROCESSING_RESPONSE);
964 host_.SetDelegate(&delegate);
966 SetDelayedStartJobGeneration(true);
967 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
968 CompleteStartRequest(1);
970 // flush all the pending requests
971 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
972 base::MessageLoop::current()->RunUntilIdle();
974 EXPECT_EQ(0, host_.pending_requests());
977 TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
978 // Arrange to have requests deferred before starting.
979 TestResourceDispatcherHostDelegate delegate;
980 delegate.set_flags(DEFER_STARTING_REQUEST);
981 delegate.set_create_two_throttles(true);
982 host_.SetDelegate(&delegate);
984 // Make sure the first throttle blocked the request, and then resume.
985 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
986 GenericResourceThrottle* first_throttle =
987 GenericResourceThrottle::active_throttle();
988 ASSERT_TRUE(first_throttle);
989 first_throttle->Resume();
991 // Make sure the second throttle blocked the request, and then resume.
992 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
993 ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
994 GenericResourceThrottle::active_throttle()->Resume();
996 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
998 // The request is started asynchronously.
999 base::MessageLoop::current()->RunUntilIdle();
1001 // Flush all the pending requests.
1002 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1004 EXPECT_EQ(0, host_.pending_requests());
1006 // Make sure the request completed successfully.
1007 ResourceIPCAccumulator::ClassifiedMessages msgs;
1008 accum_.GetClassifiedMessages(&msgs);
1009 ASSERT_EQ(1U, msgs.size());
1010 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1014 // Tests that the delegate can cancel a request and provide a error code.
1015 TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
1016 TestResourceDispatcherHostDelegate delegate;
1017 delegate.set_flags(CANCEL_BEFORE_START);
1018 delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
1019 host_.SetDelegate(&delegate);
1021 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1022 // The request will get cancelled by the throttle.
1024 // flush all the pending requests
1025 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1026 base::MessageLoop::current()->RunUntilIdle();
1028 ResourceIPCAccumulator::ClassifiedMessages msgs;
1029 accum_.GetClassifiedMessages(&msgs);
1031 // Check the cancellation
1032 ASSERT_EQ(1U, msgs.size());
1033 ASSERT_EQ(1U, msgs[0].size());
1034 ASSERT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
1039 PickleIterator iter(msgs[0][0]);
1040 ASSERT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
1041 ASSERT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
1043 EXPECT_EQ(net::ERR_ACCESS_DENIED, error_code);
1046 // The host delegate acts as a second one so we can have some requests
1047 // pending and some canceled.
1048 class TestFilter : public ForwardingFilter {
1050 explicit TestFilter(ResourceContext* resource_context)
1051 : ForwardingFilter(NULL, resource_context),
1052 has_canceled_(false),
1053 received_after_canceled_(0) {
1056 // ForwardingFilter override
1057 virtual bool Send(IPC::Message* msg) OVERRIDE {
1058 // no messages should be received when the process has been canceled
1060 received_after_canceled_++;
1066 int received_after_canceled_;
1069 virtual ~TestFilter() {}
1072 // Tests CancelRequestsForProcess
1073 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
1074 scoped_refptr<TestFilter> test_filter = new TestFilter(
1075 browser_context_->GetResourceContext());
1077 // request 1 goes to the test delegate
1078 ResourceHostMsg_Request request = CreateResourceRequest(
1079 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
1081 MakeTestRequest(test_filter.get(), 0, 1,
1082 net::URLRequestTestJob::test_url_1());
1084 // request 2 goes to us
1085 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1087 // request 3 goes to the test delegate
1088 MakeTestRequest(test_filter.get(), 0, 3,
1089 net::URLRequestTestJob::test_url_3());
1091 // Make sure all requests have finished stage one. test_url_1 will have
1093 base::MessageLoop::current()->RunUntilIdle();
1096 // Now that the async IO path is in place, the IO always completes on the
1097 // initial call; so the requests have already completed. This basically
1098 // breaks the whole test.
1099 //EXPECT_EQ(3, host_.pending_requests());
1101 // Process each request for one level so one callback is called.
1102 for (int i = 0; i < 2; i++)
1103 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1105 // Cancel the requests to the test process.
1106 host_.CancelRequestsForProcess(filter_->child_id());
1107 test_filter->has_canceled_ = true;
1109 // Flush all the pending requests.
1110 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1112 EXPECT_EQ(0, host_.pending_requests());
1114 // The test delegate should not have gotten any messages after being canceled.
1115 ASSERT_EQ(0, test_filter->received_after_canceled_);
1117 // We should have gotten exactly one result.
1118 ResourceIPCAccumulator::ClassifiedMessages msgs;
1119 accum_.GetClassifiedMessages(&msgs);
1120 ASSERT_EQ(1U, msgs.size());
1121 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1124 // Tests blocking and resuming requests.
1125 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
1126 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1127 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1128 host_.BlockRequestsForRoute(filter_->child_id(), 3);
1130 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1131 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1132 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1133 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1134 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1135 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1137 // Flush all the pending requests
1138 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1140 // Sort out all the messages we saw by request
1141 ResourceIPCAccumulator::ClassifiedMessages msgs;
1142 accum_.GetClassifiedMessages(&msgs);
1144 // All requests but the 2 for the RVH 0 should have been blocked.
1145 ASSERT_EQ(2U, msgs.size());
1147 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1148 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1150 // Resume requests for RVH 1 and flush pending requests.
1151 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
1153 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1156 accum_.GetClassifiedMessages(&msgs);
1157 ASSERT_EQ(2U, msgs.size());
1158 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1159 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
1161 // Test that new requests are not blocked for RVH 1.
1162 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1163 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1165 accum_.GetClassifiedMessages(&msgs);
1166 ASSERT_EQ(1U, msgs.size());
1167 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1169 // Now resumes requests for all RVH (2 and 3).
1170 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
1171 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
1173 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1176 accum_.GetClassifiedMessages(&msgs);
1177 ASSERT_EQ(2U, msgs.size());
1178 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1179 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1182 // Tests blocking and canceling requests.
1183 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
1184 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1186 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1187 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1188 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1189 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1191 // Flush all the pending requests.
1192 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1194 // Sort out all the messages we saw by request.
1195 ResourceIPCAccumulator::ClassifiedMessages msgs;
1196 accum_.GetClassifiedMessages(&msgs);
1198 // The 2 requests for the RVH 0 should have been processed.
1199 ASSERT_EQ(2U, msgs.size());
1201 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1202 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1204 // Cancel requests for RVH 1.
1205 host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
1207 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1210 accum_.GetClassifiedMessages(&msgs);
1211 ASSERT_EQ(0U, msgs.size());
1214 // Tests that blocked requests are canceled if their associated process dies.
1215 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
1216 // This second filter is used to emulate a second process.
1217 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1218 this, browser_context_->GetResourceContext());
1220 host_.BlockRequestsForRoute(second_filter->child_id(), 0);
1222 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1());
1223 MakeTestRequest(second_filter.get(), 0, 2,
1224 net::URLRequestTestJob::test_url_2());
1225 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3());
1226 MakeTestRequest(second_filter.get(), 0, 4,
1227 net::URLRequestTestJob::test_url_1());
1229 // Simulate process death.
1230 host_.CancelRequestsForProcess(second_filter->child_id());
1232 // Flush all the pending requests.
1233 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1235 // Sort out all the messages we saw by request.
1236 ResourceIPCAccumulator::ClassifiedMessages msgs;
1237 accum_.GetClassifiedMessages(&msgs);
1239 // The 2 requests for the RVH 0 should have been processed.
1240 ASSERT_EQ(2U, msgs.size());
1242 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1243 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1245 EXPECT_TRUE(host_.blocked_loaders_map_.empty());
1248 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1249 // away. Note that we rely on Purify for finding the leaks if any.
1250 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1251 // destructor to make sure the blocked requests are deleted.
1252 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
1253 // This second filter is used to emulate a second process.
1254 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1255 this, browser_context_->GetResourceContext());
1257 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1258 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1259 host_.BlockRequestsForRoute(second_filter->child_id(), 1);
1261 MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1());
1262 MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2());
1263 MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3());
1264 MakeTestRequest(second_filter.get(), 1, 4,
1265 net::URLRequestTestJob::test_url_1());
1266 MakeTestRequest(filter_.get(), 2, 5, net::URLRequestTestJob::test_url_2());
1267 MakeTestRequest(filter_.get(), 2, 6, net::URLRequestTestJob::test_url_3());
1269 host_.CancelRequestsForProcess(filter_->child_id());
1270 host_.CancelRequestsForProcess(second_filter->child_id());
1272 // Flush all the pending requests.
1273 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1276 // Test the private helper method "CalculateApproximateMemoryCost()".
1277 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
1278 net::URLRequestContext context;
1279 net::URLRequest req(
1280 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL, &context);
1282 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1284 // Add 9 bytes of referrer.
1285 req.SetReferrer("123456789");
1287 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1289 // Add 33 bytes of upload content.
1290 std::string upload_content;
1291 upload_content.resize(33);
1292 std::fill(upload_content.begin(), upload_content.end(), 'x');
1293 scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader(
1294 upload_content.data(), upload_content.size()));
1295 req.set_upload(make_scoped_ptr(
1296 net::UploadDataStream::CreateWithReader(reader.Pass(), 0)));
1298 // Since the upload throttling is disabled, this has no effect on the cost.
1300 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1303 // Test that too much memory for outstanding requests for a particular
1304 // render_process_host_id causes requests to fail.
1305 TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
1306 // Expected cost of each request as measured by
1307 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1308 int kMemoryCostOfTest2Req =
1309 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
1310 std::string("GET").size() +
1311 net::URLRequestTestJob::test_url_2().spec().size();
1313 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1314 int kMaxCostPerProcess = 440000;
1315 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
1317 // Determine how many instance of test_url_2() we can request before
1318 // throttling kicks in.
1319 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
1321 // This second filter is used to emulate a second process.
1322 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1323 this, browser_context_->GetResourceContext());
1325 // Saturate the number of outstanding requests for our process.
1326 for (size_t i = 0; i < kMaxRequests; ++i) {
1327 MakeTestRequest(filter_.get(), 0, i + 1,
1328 net::URLRequestTestJob::test_url_2());
1331 // Issue two more requests for our process -- these should fail immediately.
1332 MakeTestRequest(filter_.get(), 0, kMaxRequests + 1,
1333 net::URLRequestTestJob::test_url_2());
1334 MakeTestRequest(filter_.get(), 0, kMaxRequests + 2,
1335 net::URLRequestTestJob::test_url_2());
1337 // Issue two requests for the second process -- these should succeed since
1338 // it is just process 0 that is saturated.
1339 MakeTestRequest(second_filter.get(), 0, kMaxRequests + 3,
1340 net::URLRequestTestJob::test_url_2());
1341 MakeTestRequest(second_filter.get(), 0, kMaxRequests + 4,
1342 net::URLRequestTestJob::test_url_2());
1344 // Flush all the pending requests.
1345 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1346 base::MessageLoop::current()->RunUntilIdle();
1348 // Sorts out all the messages we saw by request.
1349 ResourceIPCAccumulator::ClassifiedMessages msgs;
1350 accum_.GetClassifiedMessages(&msgs);
1352 // We issued (kMaxRequests + 4) total requests.
1353 ASSERT_EQ(kMaxRequests + 4, msgs.size());
1355 // Check that the first kMaxRequests succeeded.
1356 for (size_t i = 0; i < kMaxRequests; ++i)
1357 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1359 // Check that the subsequent two requests (kMaxRequests + 1) and
1360 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1361 for (int i = 0; i < 2; ++i) {
1362 // Should have sent a single RequestComplete message.
1363 int index = kMaxRequests + i;
1364 CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(),
1365 net::ERR_INSUFFICIENT_RESOURCES);
1368 // The final 2 requests should have succeeded.
1369 CheckSuccessfulRequest(msgs[kMaxRequests + 2],
1370 net::URLRequestTestJob::test_data_2());
1371 CheckSuccessfulRequest(msgs[kMaxRequests + 3],
1372 net::URLRequestTestJob::test_data_2());
1375 // Test that when too many requests are outstanding for a particular
1376 // render_process_host_id, any subsequent request from it fails. Also verify
1377 // that the global limit is honored.
1378 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
1379 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1380 const size_t kMaxRequestsPerProcess = 2;
1381 host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
1382 const size_t kMaxRequests = 3;
1383 host_.set_max_num_in_flight_requests(kMaxRequests);
1385 // Needed to emulate additional processes.
1386 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1387 this, browser_context_->GetResourceContext());
1388 scoped_refptr<ForwardingFilter> third_filter = new ForwardingFilter(
1389 this, browser_context_->GetResourceContext());
1391 // Saturate the number of outstanding requests for our process.
1392 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
1393 MakeTestRequest(filter_.get(), 0, i + 1,
1394 net::URLRequestTestJob::test_url_2());
1397 // Issue another request for our process -- this should fail immediately.
1398 MakeTestRequest(filter_.get(), 0, kMaxRequestsPerProcess + 1,
1399 net::URLRequestTestJob::test_url_2());
1401 // Issue a request for the second process -- this should succeed, because it
1402 // is just process 0 that is saturated.
1403 MakeTestRequest(second_filter.get(), 0, kMaxRequestsPerProcess + 2,
1404 net::URLRequestTestJob::test_url_2());
1406 // Issue a request for the third process -- this should fail, because the
1407 // global limit has been reached.
1408 MakeTestRequest(third_filter.get(), 0, kMaxRequestsPerProcess + 3,
1409 net::URLRequestTestJob::test_url_2());
1411 // Flush all the pending requests.
1412 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1413 base::MessageLoop::current()->RunUntilIdle();
1415 // Sorts out all the messages we saw by request.
1416 ResourceIPCAccumulator::ClassifiedMessages msgs;
1417 accum_.GetClassifiedMessages(&msgs);
1419 // The processes issued the following requests:
1420 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1421 // #2 issued 1 request that passed
1422 // #3 issued 1 request that failed
1423 ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size());
1425 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
1426 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1428 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0],
1429 net::URLRequestTestJob::test_data_2(),
1430 net::ERR_INSUFFICIENT_RESOURCES);
1431 CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1],
1432 net::URLRequestTestJob::test_data_2());
1433 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2],
1434 net::URLRequestTestJob::test_data_2(),
1435 net::ERR_INSUFFICIENT_RESOURCES);
1438 // Tests that we sniff the mime type for a simple request.
1439 TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
1440 std::string raw_headers("HTTP/1.1 200 OK\n\n");
1441 std::string response_data("<html><title>Test One</title></html>");
1442 SetResponse(raw_headers, response_data);
1444 HandleScheme("http");
1445 MakeTestRequest(0, 1, GURL("http:bla"));
1447 // Flush all pending requests.
1448 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1450 // Sorts out all the messages we saw by request.
1451 ResourceIPCAccumulator::ClassifiedMessages msgs;
1452 accum_.GetClassifiedMessages(&msgs);
1453 ASSERT_EQ(1U, msgs.size());
1455 ResourceResponseHead response_head;
1456 GetResponseHead(msgs[0], &response_head);
1457 ASSERT_EQ("text/html", response_head.mime_type);
1460 // Tests that we don't sniff the mime type when the server provides one.
1461 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
1462 std::string raw_headers("HTTP/1.1 200 OK\n"
1463 "Content-type: image/jpeg\n\n");
1464 std::string response_data("<html><title>Test One</title></html>");
1465 SetResponse(raw_headers, response_data);
1467 HandleScheme("http");
1468 MakeTestRequest(0, 1, GURL("http:bla"));
1470 // Flush all pending requests.
1471 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1473 // Sorts out all the messages we saw by request.
1474 ResourceIPCAccumulator::ClassifiedMessages msgs;
1475 accum_.GetClassifiedMessages(&msgs);
1476 ASSERT_EQ(1U, msgs.size());
1478 ResourceResponseHead response_head;
1479 GetResponseHead(msgs[0], &response_head);
1480 ASSERT_EQ("image/jpeg", response_head.mime_type);
1483 // Tests that we don't sniff the mime type when there is no message body.
1484 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
1485 SetResponse("HTTP/1.1 304 Not Modified\n\n");
1487 HandleScheme("http");
1488 MakeTestRequest(0, 1, GURL("http:bla"));
1490 // Flush all pending requests.
1491 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1493 // Sorts out all the messages we saw by request.
1494 ResourceIPCAccumulator::ClassifiedMessages msgs;
1495 accum_.GetClassifiedMessages(&msgs);
1496 ASSERT_EQ(1U, msgs.size());
1498 ResourceResponseHead response_head;
1499 GetResponseHead(msgs[0], &response_head);
1500 ASSERT_EQ("", response_head.mime_type);
1503 TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
1504 SetResponse("HTTP/1.1 204 No Content\n\n");
1506 HandleScheme("http");
1507 MakeTestRequest(0, 1, GURL("http:bla"));
1509 // Flush all pending requests.
1510 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1512 // Sorts out all the messages we saw by request.
1513 ResourceIPCAccumulator::ClassifiedMessages msgs;
1514 accum_.GetClassifiedMessages(&msgs);
1515 ASSERT_EQ(1U, msgs.size());
1517 ResourceResponseHead response_head;
1518 GetResponseHead(msgs[0], &response_head);
1519 ASSERT_EQ("text/plain", response_head.mime_type);
1522 TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
1523 SetResponse("HTTP/1.1 200 OK\n\n");
1525 HandleScheme("http");
1526 MakeTestRequest(0, 1, GURL("http:bla"));
1528 // Flush all pending requests.
1529 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1531 // Sorts out all the messages we saw by request.
1532 ResourceIPCAccumulator::ClassifiedMessages msgs;
1533 accum_.GetClassifiedMessages(&msgs);
1534 ASSERT_EQ(1U, msgs.size());
1536 ResourceResponseHead response_head;
1537 GetResponseHead(msgs[0], &response_head);
1538 ASSERT_EQ("text/plain", response_head.mime_type);
1541 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
1542 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
1543 std::string raw_headers("HTTP/1.1 403 Forbidden\n"
1544 "Content-disposition: attachment; filename=blah\n"
1545 "Content-type: application/octet-stream\n\n");
1546 std::string response_data("<html><title>Test One</title></html>");
1547 SetResponse(raw_headers, response_data);
1549 // Only MAIN_FRAMEs can trigger a download.
1550 SetResourceType(ResourceType::MAIN_FRAME);
1552 HandleScheme("http");
1553 MakeTestRequest(0, 1, GURL("http:bla"));
1555 // Flush all pending requests.
1556 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1558 // Sorts out all the messages we saw by request.
1559 ResourceIPCAccumulator::ClassifiedMessages msgs;
1560 accum_.GetClassifiedMessages(&msgs);
1562 // We should have gotten one RequestComplete message.
1563 ASSERT_EQ(1U, msgs[0].size());
1564 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
1566 // The RequestComplete message should have had the error code of
1567 // ERR_FILE_NOT_FOUND.
1571 PickleIterator iter(msgs[0][0]);
1572 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
1573 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
1575 EXPECT_EQ(1, request_id);
1576 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, error_code);
1579 // Test for http://crbug.com/76202 . We don't want to destroy a
1580 // download request prematurely when processing a cancellation from
1582 TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
1583 EXPECT_EQ(0, host_.pending_requests());
1585 int render_view_id = 0;
1588 std::string raw_headers("HTTP\n"
1589 "Content-disposition: attachment; filename=foo\n\n");
1590 std::string response_data("01234567890123456789\x01foobar");
1592 // Get past sniffing metrics in the BufferedResourceHandler. Note that
1593 // if we don't get past the sniffing metrics, the result will be that
1594 // the BufferedResourceHandler won't have figured out that it's a download,
1595 // won't have constructed a DownloadResourceHandler, and and the request
1596 // will be successfully canceled below, failing the test.
1597 response_data.resize(1025, ' ');
1599 SetResponse(raw_headers, response_data);
1600 SetResourceType(ResourceType::MAIN_FRAME);
1601 SetDelayedCompleteJobGeneration(true);
1602 HandleScheme("http");
1604 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1605 // Return some data so that the request is identified as a download
1606 // and the proper resource handlers are created.
1607 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1609 // And now simulate a cancellation coming from the renderer.
1610 ResourceHostMsg_CancelRequest msg(request_id);
1612 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1614 // Since the request had already started processing as a download,
1615 // the cancellation above should have been ignored and the request
1616 // should still be alive.
1617 EXPECT_EQ(1, host_.pending_requests());
1619 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1622 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
1623 EXPECT_EQ(0, host_.pending_requests());
1625 int render_view_id = 0;
1628 std::string raw_headers("HTTP\n"
1629 "Content-disposition: attachment; filename=foo\n\n");
1630 std::string response_data("01234567890123456789\x01foobar");
1631 // Get past sniffing metrics.
1632 response_data.resize(1025, ' ');
1634 SetResponse(raw_headers, response_data);
1635 SetResourceType(ResourceType::MAIN_FRAME);
1636 SetDelayedCompleteJobGeneration(true);
1637 HandleScheme("http");
1639 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1640 // Return some data so that the request is identified as a download
1641 // and the proper resource handlers are created.
1642 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1644 // And now simulate a cancellation coming from the renderer.
1645 ResourceHostMsg_CancelRequest msg(request_id);
1647 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1649 // Since the request had already started processing as a download,
1650 // the cancellation above should have been ignored and the request
1651 // should still be alive.
1652 EXPECT_EQ(1, host_.pending_requests());
1654 // Cancelling by other methods shouldn't work either.
1655 host_.CancelRequestsForProcess(render_view_id);
1656 EXPECT_EQ(1, host_.pending_requests());
1658 // Cancelling by context should work.
1659 host_.CancelRequestsForContext(filter_->resource_context());
1660 EXPECT_EQ(0, host_.pending_requests());
1663 // Test the cancelling of requests that are being transferred to a new renderer
1664 // due to a redirection.
1665 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
1666 EXPECT_EQ(0, host_.pending_requests());
1668 int render_view_id = 0;
1671 std::string raw_headers("HTTP/1.1 200 OK\n"
1672 "Content-Type: text/html; charset=utf-8\n\n");
1673 std::string response_data("<html>foobar</html>");
1675 SetResponse(raw_headers, response_data);
1676 SetResourceType(ResourceType::MAIN_FRAME);
1677 HandleScheme("http");
1679 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1681 GlobalRequestID global_request_id(filter_->child_id(), request_id);
1682 host_.MarkAsTransferredNavigation(global_request_id,
1683 GURL("http://example.com/blah"));
1685 // And now simulate a cancellation coming from the renderer.
1686 ResourceHostMsg_CancelRequest msg(request_id);
1688 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1690 // Since the request is marked as being transferred,
1691 // the cancellation above should have been ignored and the request
1692 // should still be alive.
1693 EXPECT_EQ(1, host_.pending_requests());
1695 // Cancelling by other methods shouldn't work either.
1696 host_.CancelRequestsForProcess(render_view_id);
1697 EXPECT_EQ(1, host_.pending_requests());
1699 // Cancelling by context should work.
1700 host_.CancelRequestsForContext(filter_->resource_context());
1701 EXPECT_EQ(0, host_.pending_requests());
1704 // Test transferred navigations with text/html, which doesn't trigger any
1705 // content sniffing.
1706 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
1707 EXPECT_EQ(0, host_.pending_requests());
1709 int render_view_id = 0;
1712 // Configure initial request.
1713 SetResponse("HTTP/1.1 302 Found\n"
1714 "Location: http://other.com/blech\n\n");
1716 SetResourceType(ResourceType::MAIN_FRAME);
1717 HandleScheme("http");
1719 // Temporarily replace ContentBrowserClient with one that will trigger the
1720 // transfer navigation code paths.
1721 TransfersAllNavigationsContentBrowserClient new_client;
1722 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
1724 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1726 // Now that we're blocked on the redirect, update the response and unblock by
1727 // telling the AsyncResourceHandler to follow the redirect.
1728 const std::string kResponseBody = "hello world";
1729 SetResponse("HTTP/1.1 200 OK\n"
1730 "Content-Type: text/html\n\n",
1732 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
1734 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
1735 base::MessageLoop::current()->RunUntilIdle();
1737 // Flush all the pending requests to get the response through the
1738 // BufferedResourceHandler.
1739 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1741 // Restore, now that we've set up a transfer.
1742 SetBrowserClientForTesting(old_client);
1744 // This second filter is used to emulate a second process.
1745 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1746 this, browser_context_->GetResourceContext());
1748 int new_render_view_id = 1;
1749 int new_request_id = 2;
1751 ResourceHostMsg_Request request =
1752 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
1753 GURL("http://other.com/blech"));
1754 request.transferred_request_child_id = filter_->child_id();
1755 request.transferred_request_request_id = request_id;
1758 child_ids_.insert(second_filter->child_id());
1759 ResourceHostMsg_RequestResource transfer_request_msg(
1760 new_render_view_id, new_request_id, request);
1761 host_.OnMessageReceived(
1762 transfer_request_msg, second_filter.get(), &msg_was_ok);
1763 base::MessageLoop::current()->RunUntilIdle();
1765 // Check generated messages.
1766 ResourceIPCAccumulator::ClassifiedMessages msgs;
1767 accum_.GetClassifiedMessages(&msgs);
1769 ASSERT_EQ(2U, msgs.size());
1770 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
1771 CheckSuccessfulRequest(msgs[1], kResponseBody);
1774 // Test transferred navigations with text/plain, which causes
1775 // BufferedResourceHandler to buffer the response to sniff the content
1776 // before the transfer occurs.
1777 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
1778 EXPECT_EQ(0, host_.pending_requests());
1780 int render_view_id = 0;
1783 // Configure initial request.
1784 SetResponse("HTTP/1.1 302 Found\n"
1785 "Location: http://other.com/blech\n\n");
1787 SetResourceType(ResourceType::MAIN_FRAME);
1788 HandleScheme("http");
1790 // Temporarily replace ContentBrowserClient with one that will trigger the
1791 // transfer navigation code paths.
1792 TransfersAllNavigationsContentBrowserClient new_client;
1793 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
1795 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1797 // Now that we're blocked on the redirect, update the response and unblock by
1798 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
1799 // MIME type, which causes BufferedResourceHandler to buffer it before the
1801 const std::string kResponseBody = "hello world";
1802 SetResponse("HTTP/1.1 200 OK\n"
1803 "Content-Type: text/plain\n\n",
1805 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
1807 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
1808 base::MessageLoop::current()->RunUntilIdle();
1810 // Flush all the pending requests to get the response through the
1811 // BufferedResourceHandler.
1812 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1814 // Restore, now that we've set up a transfer.
1815 SetBrowserClientForTesting(old_client);
1817 // This second filter is used to emulate a second process.
1818 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1819 this, browser_context_->GetResourceContext());
1821 int new_render_view_id = 1;
1822 int new_request_id = 2;
1824 ResourceHostMsg_Request request =
1825 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
1826 GURL("http://other.com/blech"));
1827 request.transferred_request_child_id = filter_->child_id();
1828 request.transferred_request_request_id = request_id;
1831 child_ids_.insert(second_filter->child_id());
1832 ResourceHostMsg_RequestResource transfer_request_msg(
1833 new_render_view_id, new_request_id, request);
1834 host_.OnMessageReceived(
1835 transfer_request_msg, second_filter.get(), &msg_was_ok);
1836 base::MessageLoop::current()->RunUntilIdle();
1838 // Check generated messages.
1839 ResourceIPCAccumulator::ClassifiedMessages msgs;
1840 accum_.GetClassifiedMessages(&msgs);
1842 ASSERT_EQ(2U, msgs.size());
1843 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
1844 CheckSuccessfulRequest(msgs[1], kResponseBody);
1847 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
1848 EXPECT_EQ(0, host_.pending_requests());
1850 int render_view_id = 0;
1852 int first_child_id = -1;
1854 // Configure initial request.
1855 SetResponse("HTTP/1.1 302 Found\n"
1856 "Location: http://other.com/blech\n\n");
1857 const std::string kResponseBody = "hello world";
1859 SetResourceType(ResourceType::MAIN_FRAME);
1860 HandleScheme("http");
1862 // Temporarily replace ContentBrowserClient with one that will trigger the
1863 // transfer navigation code paths.
1864 TransfersAllNavigationsContentBrowserClient new_client;
1865 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
1867 // Create a first filter that can be deleted before the second one starts.
1869 scoped_refptr<ForwardingFilter> first_filter = new ForwardingFilter(
1870 this, browser_context_->GetResourceContext());
1871 first_child_id = first_filter->child_id();
1873 ResourceHostMsg_Request first_request =
1874 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
1875 GURL("http://example.com/blah"));
1878 child_ids_.insert(first_child_id);
1879 ResourceHostMsg_RequestResource first_request_msg(
1880 render_view_id, request_id, first_request);
1882 host_.OnMessageReceived(
1883 first_request_msg, first_filter.get(), &msg_was_ok);
1884 base::MessageLoop::current()->RunUntilIdle();
1886 // Now that we're blocked on the redirect, update the response and unblock
1887 // by telling the AsyncResourceHandler to follow the redirect.
1888 SetResponse("HTTP/1.1 200 OK\n"
1889 "Content-Type: text/html\n\n",
1891 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
1892 host_.OnMessageReceived(redirect_msg, first_filter.get(), &msg_was_ok);
1893 base::MessageLoop::current()->RunUntilIdle();
1895 // Flush all the pending requests to get the response through the
1896 // BufferedResourceHandler.
1897 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1899 // The first filter is now deleted, as if the child process died.
1902 SetBrowserClientForTesting(old_client);
1904 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
1905 GlobalRequestID first_global_request_id(first_child_id, request_id);
1907 // This second filter is used to emulate a second process.
1908 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1909 this, browser_context_->GetResourceContext());
1911 int new_render_view_id = 1;
1912 int new_request_id = 2;
1914 ResourceHostMsg_Request request =
1915 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
1916 GURL("http://other.com/blech"));
1917 request.transferred_request_child_id = first_child_id;
1918 request.transferred_request_request_id = request_id;
1921 child_ids_.insert(second_filter->child_id());
1922 ResourceHostMsg_RequestResource transfer_request_msg(
1923 new_render_view_id, new_request_id, request);
1925 host_.OnMessageReceived(
1926 transfer_request_msg, second_filter.get(), &msg_was_ok);
1927 base::MessageLoop::current()->RunUntilIdle();
1929 // Check generated messages.
1930 ResourceIPCAccumulator::ClassifiedMessages msgs;
1931 accum_.GetClassifiedMessages(&msgs);
1933 ASSERT_EQ(2U, msgs.size());
1934 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
1935 CheckSuccessfulRequest(msgs[1], kResponseBody);
1938 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
1939 EXPECT_EQ(0, host_.pending_requests());
1941 int render_view_id = 0;
1944 // Configure initial request.
1945 SetResponse("HTTP/1.1 302 Found\n"
1946 "Location: http://other.com/blech\n\n");
1948 SetResourceType(ResourceType::MAIN_FRAME);
1949 HandleScheme("http");
1951 // Temporarily replace ContentBrowserClient with one that will trigger the
1952 // transfer navigation code paths.
1953 TransfersAllNavigationsContentBrowserClient new_client;
1954 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
1956 MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1958 // Now that we're blocked on the redirect, simulate hitting another redirect.
1959 SetResponse("HTTP/1.1 302 Found\n"
1960 "Location: http://other.com/blerg\n\n");
1961 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
1963 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
1964 base::MessageLoop::current()->RunUntilIdle();
1966 // Now that we're blocked on the second redirect, update the response and
1967 // unblock by telling the AsyncResourceHandler to follow the redirect.
1968 // Again, use text/plain to force BufferedResourceHandler to buffer before
1970 const std::string kResponseBody = "hello world";
1971 SetResponse("HTTP/1.1 200 OK\n"
1972 "Content-Type: text/plain\n\n",
1974 ResourceHostMsg_FollowRedirect redirect_msg2(request_id, false, GURL());
1975 host_.OnMessageReceived(redirect_msg2, filter_.get(), &msg_was_ok);
1976 base::MessageLoop::current()->RunUntilIdle();
1978 // Flush all the pending requests to get the response through the
1979 // BufferedResourceHandler.
1980 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1983 SetBrowserClientForTesting(old_client);
1985 // This second filter is used to emulate a second process.
1986 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1987 this, browser_context_->GetResourceContext());
1989 int new_render_view_id = 1;
1990 int new_request_id = 2;
1992 ResourceHostMsg_Request request =
1993 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
1994 GURL("http://other.com/blech"));
1995 request.transferred_request_child_id = filter_->child_id();
1996 request.transferred_request_request_id = request_id;
1999 child_ids_.insert(second_filter->child_id());
2000 ResourceHostMsg_RequestResource transfer_request_msg(
2001 new_render_view_id, new_request_id, request);
2002 host_.OnMessageReceived(
2003 transfer_request_msg, second_filter.get(), &msg_was_ok);
2005 // Verify that we update the ResourceRequestInfo.
2006 GlobalRequestID global_request_id(second_filter->child_id(), new_request_id);
2007 const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
2008 host_.GetURLRequest(global_request_id));
2009 EXPECT_EQ(second_filter->child_id(), info->GetChildID());
2010 EXPECT_EQ(new_render_view_id, info->GetRouteID());
2011 EXPECT_EQ(new_request_id, info->GetRequestID());
2012 EXPECT_EQ(second_filter, info->filter());
2014 // Let request complete.
2015 base::MessageLoop::current()->RunUntilIdle();
2017 // Check generated messages.
2018 ResourceIPCAccumulator::ClassifiedMessages msgs;
2019 accum_.GetClassifiedMessages(&msgs);
2021 ASSERT_EQ(2U, msgs.size());
2022 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2023 CheckSuccessfulRequest(msgs[1], kResponseBody);
2026 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
2027 EXPECT_EQ(0, host_.pending_requests());
2029 SetResourceType(ResourceType::MAIN_FRAME);
2030 HandleScheme("http");
2032 MakeTestRequest(0, 1, GURL("foo://bar"));
2034 // Flush all pending requests.
2035 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2037 // Sort all the messages we saw by request.
2038 ResourceIPCAccumulator::ClassifiedMessages msgs;
2039 accum_.GetClassifiedMessages(&msgs);
2041 // We should have gotten one RequestComplete message.
2042 ASSERT_EQ(1U, msgs[0].size());
2043 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2045 // The RequestComplete message should have the error code of
2046 // ERR_UNKNOWN_URL_SCHEME.
2050 PickleIterator iter(msgs[0][0]);
2051 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
2052 EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
2054 EXPECT_EQ(1, request_id);
2055 EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, error_code);
2058 TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
2059 EXPECT_EQ(0, host_.pending_requests());
2061 SendDataReceivedACKs(true);
2063 HandleScheme("big-job");
2064 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2066 // Sort all the messages we saw by request.
2067 ResourceIPCAccumulator::ClassifiedMessages msgs;
2068 accum_.GetClassifiedMessages(&msgs);
2070 size_t size = msgs[0].size();
2072 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2073 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2074 for (size_t i = 2; i < size - 1; ++i)
2075 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2076 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
2079 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
2080 EXPECT_EQ(0, host_.pending_requests());
2082 HandleScheme("big-job");
2083 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2085 // Sort all the messages we saw by request.
2086 ResourceIPCAccumulator::ClassifiedMessages msgs;
2087 accum_.GetClassifiedMessages(&msgs);
2089 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2090 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2091 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2092 for (size_t i = 2; i < msgs[0].size(); ++i)
2093 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2095 // NOTE: If we fail the above checks then it means that we probably didn't
2096 // load a big enough response to trigger the delay mechanism we are trying to
2099 msgs[0].erase(msgs[0].begin());
2100 msgs[0].erase(msgs[0].begin());
2102 // ACK all DataReceived messages until we find a RequestComplete message.
2103 bool complete = false;
2105 for (size_t i = 0; i < msgs[0].size(); ++i) {
2106 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2111 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2113 ResourceHostMsg_DataReceived_ACK msg(1);
2115 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2118 base::MessageLoop::current()->RunUntilIdle();
2121 accum_.GetClassifiedMessages(&msgs);
2125 // Flakyness of this test might indicate memory corruption issues with
2126 // for example the ResourceBuffer of AsyncResourceHandler.
2127 TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) {
2128 EXPECT_EQ(0, host_.pending_requests());
2130 HandleScheme("big-job");
2131 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2133 // Sort all the messages we saw by request.
2134 ResourceIPCAccumulator::ClassifiedMessages msgs;
2135 accum_.GetClassifiedMessages(&msgs);
2137 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2138 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2139 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2140 for (size_t i = 2; i < msgs[0].size(); ++i)
2141 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2143 // NOTE: If we fail the above checks then it means that we probably didn't
2144 // load a big enough response to trigger the delay mechanism.
2146 // Send some unexpected ACKs.
2147 for (size_t i = 0; i < 128; ++i) {
2148 ResourceHostMsg_DataReceived_ACK msg(1);
2150 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2153 msgs[0].erase(msgs[0].begin());
2154 msgs[0].erase(msgs[0].begin());
2156 // ACK all DataReceived messages until we find a RequestComplete message.
2157 bool complete = false;
2159 for (size_t i = 0; i < msgs[0].size(); ++i) {
2160 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2165 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2167 ResourceHostMsg_DataReceived_ACK msg(1);
2169 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2172 base::MessageLoop::current()->RunUntilIdle();
2175 accum_.GetClassifiedMessages(&msgs);
2179 } // namespace content