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/cross_site_resource_handler.h"
18 #include "content/browser/loader/detachable_resource_handler.h"
19 #include "content/browser/loader/resource_dispatcher_host_impl.h"
20 #include "content/browser/loader/resource_loader.h"
21 #include "content/browser/loader/resource_message_filter.h"
22 #include "content/browser/loader/resource_request_info_impl.h"
23 #include "content/browser/worker_host/worker_service_impl.h"
24 #include "content/common/child_process_host_impl.h"
25 #include "content/common/resource_messages.h"
26 #include "content/common/view_messages.h"
27 #include "content/public/browser/global_request_id.h"
28 #include "content/public/browser/resource_context.h"
29 #include "content/public/browser/resource_dispatcher_host_delegate.h"
30 #include "content/public/browser/resource_request_info.h"
31 #include "content/public/browser/resource_throttle.h"
32 #include "content/public/common/process_type.h"
33 #include "content/public/common/resource_response.h"
34 #include "content/public/test/test_browser_context.h"
35 #include "content/test/test_content_browser_client.h"
36 #include "net/base/net_errors.h"
37 #include "net/base/request_priority.h"
38 #include "net/base/upload_bytes_element_reader.h"
39 #include "net/base/upload_data_stream.h"
40 #include "net/http/http_util.h"
41 #include "net/url_request/url_request.h"
42 #include "net/url_request/url_request_context.h"
43 #include "net/url_request/url_request_job.h"
44 #include "net/url_request/url_request_simple_job.h"
45 #include "net/url_request/url_request_test_job.h"
46 #include "net/url_request/url_request_test_util.h"
47 #include "testing/gtest/include/gtest/gtest.h"
48 #include "webkit/common/appcache/appcache_interfaces.h"
50 // TODO(eroman): Write unit tests for SafeBrowsing that exercise
51 // SafeBrowsingResourceHandler.
57 // Returns the resource response header structure for this request.
58 void GetResponseHead(const std::vector<IPC::Message>& messages,
59 ResourceResponseHead* response_head) {
60 ASSERT_GE(messages.size(), 2U);
62 // The first messages should be received response.
63 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
65 PickleIterator iter(messages[0]);
67 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id));
68 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head));
71 void GenerateIPCMessage(
72 scoped_refptr<ResourceMessageFilter> filter,
73 scoped_ptr<IPC::Message> message) {
75 ResourceDispatcherHostImpl::Get()->OnMessageReceived(
76 *message, filter.get(), &msg_is_ok);
81 static int RequestIDForMessage(const IPC::Message& msg) {
84 case ResourceMsg_UploadProgress::ID:
85 case ResourceMsg_ReceivedResponse::ID:
86 case ResourceMsg_ReceivedRedirect::ID:
87 case ResourceMsg_SetDataBuffer::ID:
88 case ResourceMsg_DataReceived::ID:
89 case ResourceMsg_RequestComplete::ID: {
90 bool result = PickleIterator(msg).ReadInt(&request_id);
98 static ResourceHostMsg_Request CreateResourceRequest(
100 ResourceType::Type type,
102 ResourceHostMsg_Request request;
103 request.method = std::string(method);
105 request.first_party_for_cookies = url; // bypass third-party cookie blocking
106 request.referrer_policy = blink::WebReferrerPolicyDefault;
107 request.load_flags = 0;
108 request.origin_pid = 0;
109 request.resource_type = type;
110 request.request_context = 0;
111 request.appcache_host_id = appcache::kNoHostId;
112 request.download_to_file = false;
113 request.is_main_frame = true;
114 request.frame_id = 0;
115 request.parent_is_main_frame = false;
116 request.parent_frame_id = -1;
117 request.transition_type = PAGE_TRANSITION_LINK;
118 request.allow_download = true;
122 // Spin up the message loop to kick off the request.
123 static void KickOffRequest() {
124 base::MessageLoop::current()->RunUntilIdle();
127 // We may want to move this to a shared space if it is useful for something else
128 class ResourceIPCAccumulator {
130 void AddMessage(const IPC::Message& msg) {
131 messages_.push_back(msg);
134 // This groups the messages by their request ID. The groups will be in order
135 // that the first message for each request ID was received, and the messages
136 // within the groups will be in the order that they appeared.
137 // Note that this clears messages_.
138 typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
139 void GetClassifiedMessages(ClassifiedMessages* msgs);
142 std::vector<IPC::Message> messages_;
145 // This is very inefficient as a result of repeatedly extracting the ID, use
147 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) {
148 while (!messages_.empty()) {
149 // Ignore unknown message types as it is valid for code to generated other
150 // IPCs as side-effects that we are not testing here.
151 int cur_id = RequestIDForMessage(messages_[0]);
153 std::vector<IPC::Message> cur_requests;
154 cur_requests.push_back(messages_[0]);
155 // find all other messages with this ID
156 for (int i = 1; i < static_cast<int>(messages_.size()); i++) {
157 int id = RequestIDForMessage(messages_[i]);
159 cur_requests.push_back(messages_[i]);
160 messages_.erase(messages_.begin() + i);
164 msgs->push_back(cur_requests);
166 messages_.erase(messages_.begin());
170 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
171 // This is used to emulate different sub-processes, since this filter will
172 // have a different ID than the original. For the test, we want all the incoming
173 // messages to go to the same place, which is why this forwards.
174 class ForwardingFilter : public ResourceMessageFilter {
176 explicit ForwardingFilter(IPC::Sender* dest,
177 ResourceContext* resource_context)
178 : ResourceMessageFilter(
179 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
180 PROCESS_TYPE_RENDERER, NULL, NULL, NULL,
181 base::Bind(&ForwardingFilter::GetContexts,
182 base::Unretained(this))),
184 resource_context_(resource_context) {
185 set_peer_pid_for_testing(base::GetCurrentProcId());
188 // ResourceMessageFilter override
189 virtual bool Send(IPC::Message* msg) OVERRIDE {
192 return dest_->Send(msg);
195 ResourceContext* resource_context() { return resource_context_; }
198 virtual ~ForwardingFilter() {}
201 void GetContexts(const ResourceHostMsg_Request& request,
202 ResourceContext** resource_context,
203 net::URLRequestContext** request_context) {
204 *resource_context = resource_context_;
205 *request_context = resource_context_->GetRequestContext();
209 ResourceContext* resource_context_;
211 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
214 // This class is a variation on URLRequestTestJob that will call
215 // URLRequest::OnBeforeNetworkStart before starting.
216 class URLRequestTestDelayedNetworkJob : public net::URLRequestTestJob {
218 URLRequestTestDelayedNetworkJob(net::URLRequest* request,
219 net::NetworkDelegate* network_delegate)
220 : net::URLRequestTestJob(request, network_delegate) {}
222 // Only start if not deferred for network start.
223 virtual void Start() OVERRIDE {
225 NotifyBeforeNetworkStart(&defer);
228 net::URLRequestTestJob::Start();
231 virtual void ResumeNetworkStart() OVERRIDE {
232 net::URLRequestTestJob::StartAsync();
236 virtual ~URLRequestTestDelayedNetworkJob() {}
238 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob);
241 // This class is a variation on URLRequestTestJob in that it does
242 // not complete start upon entry, only when specifically told to.
243 class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
245 URLRequestTestDelayedStartJob(net::URLRequest* request,
246 net::NetworkDelegate* network_delegate)
247 : net::URLRequestTestJob(request, network_delegate) {
250 URLRequestTestDelayedStartJob(net::URLRequest* request,
251 net::NetworkDelegate* network_delegate,
253 : net::URLRequestTestJob(request, network_delegate, auto_advance) {
256 URLRequestTestDelayedStartJob(net::URLRequest* request,
257 net::NetworkDelegate* network_delegate,
258 const std::string& response_headers,
259 const std::string& response_data,
261 : net::URLRequestTestJob(request,
269 // Do nothing until you're told to.
270 virtual void Start() OVERRIDE {}
272 // Finish starting a URL request whose job is an instance of
273 // URLRequestTestDelayedStartJob. It is illegal to call this routine
274 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
275 static void CompleteStart(net::URLRequest* request) {
276 for (URLRequestTestDelayedStartJob* job = list_head_;
279 if (job->request() == request) {
280 job->net::URLRequestTestJob::Start();
287 static bool DelayedStartQueueEmpty() {
291 static void ClearQueue() {
294 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
295 << "; may result in leaks.";
301 virtual ~URLRequestTestDelayedStartJob() {
302 for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
303 job = &(*job)->next_) {
305 *job = (*job)->next_;
318 static URLRequestTestDelayedStartJob* list_head_;
319 URLRequestTestDelayedStartJob* next_;
322 URLRequestTestDelayedStartJob*
323 URLRequestTestDelayedStartJob::list_head_ = NULL;
325 // This class is a variation on URLRequestTestJob in that it
326 // returns IO_pending errors before every read, not just the first one.
327 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
329 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
330 net::NetworkDelegate* network_delegate)
331 : net::URLRequestTestJob(request, network_delegate) {}
332 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
333 net::NetworkDelegate* network_delegate,
335 : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
336 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
337 net::NetworkDelegate* network_delegate,
338 const std::string& response_headers,
339 const std::string& response_data,
341 : net::URLRequestTestJob(request,
348 virtual ~URLRequestTestDelayedCompletionJob() {}
351 virtual bool NextReadAsync() OVERRIDE { return true; }
354 class URLRequestBigJob : public net::URLRequestSimpleJob {
356 URLRequestBigJob(net::URLRequest* request,
357 net::NetworkDelegate* network_delegate)
358 : net::URLRequestSimpleJob(request, network_delegate) {
361 virtual int GetData(std::string* mime_type,
362 std::string* charset,
364 const net::CompletionCallback& callback) const OVERRIDE {
365 *mime_type = "text/plain";
370 if (!ParseURL(request_->url(), &text, &count))
371 return net::ERR_INVALID_URL;
373 data->reserve(text.size() * count);
374 for (int i = 0; i < count; ++i)
381 virtual ~URLRequestBigJob() {}
383 // big-job:substring,N
384 static bool ParseURL(const GURL& url, std::string* text, int* count) {
385 std::vector<std::string> parts;
386 base::SplitString(url.path(), ',', &parts);
388 if (parts.size() != 2)
392 return base::StringToInt(parts[1], count);
396 // Associated with an URLRequest to determine if the URLRequest gets deleted.
397 class TestUserData : public base::SupportsUserData::Data {
399 explicit TestUserData(bool* was_deleted)
400 : was_deleted_(was_deleted) {
403 virtual ~TestUserData() {
404 *was_deleted_ = true;
411 class TransfersAllNavigationsContentBrowserClient
412 : public TestContentBrowserClient {
414 virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context,
415 const GURL& current_url,
416 const GURL& new_url) OVERRIDE {
421 enum GenericResourceThrottleFlags {
423 DEFER_STARTING_REQUEST = 1 << 0,
424 DEFER_PROCESSING_RESPONSE = 1 << 1,
425 CANCEL_BEFORE_START = 1 << 2,
426 DEFER_NETWORK_START = 1 << 3
429 // Throttle that tracks the current throttle blocking a request. Only one
430 // can throttle any request at a time.
431 class GenericResourceThrottle : public ResourceThrottle {
433 // The value is used to indicate that the throttle should not provide
434 // a error code when cancelling a request. net::OK is used, because this
435 // is not an error code.
436 static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;
438 GenericResourceThrottle(int flags, int code)
440 error_code_for_cancellation_(code) {
443 virtual ~GenericResourceThrottle() {
444 if (active_throttle_ == this)
445 active_throttle_ = NULL;
448 // ResourceThrottle implementation:
449 virtual void WillStartRequest(bool* defer) OVERRIDE {
450 ASSERT_EQ(NULL, active_throttle_);
451 if (flags_ & DEFER_STARTING_REQUEST) {
452 active_throttle_ = this;
456 if (flags_ & CANCEL_BEFORE_START) {
457 if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
458 controller()->Cancel();
460 controller()->CancelWithError(error_code_for_cancellation_);
465 virtual void WillProcessResponse(bool* defer) OVERRIDE {
466 ASSERT_EQ(NULL, active_throttle_);
467 if (flags_ & DEFER_PROCESSING_RESPONSE) {
468 active_throttle_ = this;
473 virtual void OnBeforeNetworkStart(bool* defer) OVERRIDE {
474 ASSERT_EQ(NULL, active_throttle_);
476 if (flags_ & DEFER_NETWORK_START) {
477 active_throttle_ = this;
482 virtual const char* GetNameForLogging() const OVERRIDE {
483 return "GenericResourceThrottle";
487 ASSERT_TRUE(this == active_throttle_);
488 active_throttle_ = NULL;
489 controller()->Resume();
492 static GenericResourceThrottle* active_throttle() {
493 return active_throttle_;
497 int flags_; // bit-wise union of GenericResourceThrottleFlags.
498 int error_code_for_cancellation_;
500 // The currently active throttle, if any.
501 static GenericResourceThrottle* active_throttle_;
504 GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
506 class TestResourceDispatcherHostDelegate
507 : public ResourceDispatcherHostDelegate {
509 TestResourceDispatcherHostDelegate()
510 : create_two_throttles_(false),
512 error_code_for_cancellation_(
513 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
516 void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
517 user_data_.reset(user_data);
520 void set_flags(int value) {
524 void set_error_code_for_cancellation(int code) {
525 error_code_for_cancellation_ = code;
528 void set_create_two_throttles(bool create_two_throttles) {
529 create_two_throttles_ = create_two_throttles;
532 // ResourceDispatcherHostDelegate implementation:
534 virtual void RequestBeginning(
535 net::URLRequest* request,
536 ResourceContext* resource_context,
537 appcache::AppCacheService* appcache_service,
538 ResourceType::Type resource_type,
541 ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
543 const void* key = user_data_.get();
544 request->SetUserData(key, user_data_.release());
547 if (flags_ != NONE) {
548 throttles->push_back(new GenericResourceThrottle(
549 flags_, error_code_for_cancellation_));
550 if (create_two_throttles_)
551 throttles->push_back(new GenericResourceThrottle(
552 flags_, error_code_for_cancellation_));
557 bool create_two_throttles_;
559 int error_code_for_cancellation_;
560 scoped_ptr<base::SupportsUserData::Data> user_data_;
563 class ResourceDispatcherHostTest : public testing::Test,
566 ResourceDispatcherHostTest()
567 : ui_thread_(BrowserThread::UI, &message_loop_),
568 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_),
569 cache_thread_(BrowserThread::CACHE, &message_loop_),
570 io_thread_(BrowserThread::IO, &message_loop_),
572 send_data_received_acks_(false) {
573 browser_context_.reset(new TestBrowserContext());
574 BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
575 message_loop_.RunUntilIdle();
576 ResourceContext* resource_context = browser_context_->GetResourceContext();
577 filter_ = new ForwardingFilter(this, resource_context);
578 resource_context->GetRequestContext()->set_network_delegate(
582 virtual ~ResourceDispatcherHostTest() {
583 for (std::set<int>::iterator it = child_ids_.begin();
584 it != child_ids_.end(); ++it) {
585 host_.CancelRequestsForProcess(*it);
589 // IPC::Sender implementation
590 virtual bool Send(IPC::Message* msg) OVERRIDE {
591 accum_.AddMessage(*msg);
593 if (send_data_received_acks_ &&
594 msg->type() == ResourceMsg_DataReceived::ID) {
595 GenerateDataReceivedACK(*msg);
604 virtual void SetUp() {
605 DCHECK(!test_fixture_);
606 test_fixture_ = this;
607 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
608 net::URLRequest::Deprecated::RegisterProtocolFactory(
610 &ResourceDispatcherHostTest::Factory);
611 EnsureTestSchemeIsAllowed();
612 delay_start_ = false;
613 delay_complete_ = false;
614 network_start_notification_ = false;
615 url_request_jobs_created_count_ = 0;
618 virtual void TearDown() {
619 net::URLRequest::Deprecated::RegisterProtocolFactory("test", NULL);
620 if (!scheme_.empty())
621 net::URLRequest::Deprecated::RegisterProtocolFactory(
622 scheme_, old_factory_);
624 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
625 URLRequestTestDelayedStartJob::ClearQueue();
627 DCHECK(test_fixture_ == this);
628 test_fixture_ = NULL;
632 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
634 // Flush the message loop to make application verifiers happy.
635 if (ResourceDispatcherHostImpl::Get())
636 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
637 browser_context_->GetResourceContext());
639 WorkerServiceImpl::GetInstance()->PerformTeardownForTesting();
641 browser_context_.reset();
642 message_loop_.RunUntilIdle();
645 // Creates a request using the current test object as the filter and
646 // SubResource as the resource type.
647 void MakeTestRequest(int render_view_id,
651 // Generates a request using the given filter and resource type.
652 void MakeTestRequestWithResourceType(ResourceMessageFilter* filter,
653 int render_view_id, int request_id,
655 ResourceType::Type type);
657 void CancelRequest(int request_id);
658 void RendererCancelRequest(int request_id) {
659 ResourceMessageFilter* old_filter = SetFilter(filter_.get());
660 host_.OnCancelRequest(request_id);
661 SetFilter(old_filter);
664 void CompleteStartRequest(int request_id);
665 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
667 net::TestNetworkDelegate* network_delegate() { return &network_delegate_; }
669 void EnsureSchemeIsAllowed(const std::string& scheme) {
670 ChildProcessSecurityPolicyImpl* policy =
671 ChildProcessSecurityPolicyImpl::GetInstance();
672 if (!policy->IsWebSafeScheme(scheme))
673 policy->RegisterWebSafeScheme(scheme);
676 void EnsureTestSchemeIsAllowed() {
677 EnsureSchemeIsAllowed("test");
680 // Sets a particular response for any request from now on. To switch back to
681 // the default bahavior, pass an empty |headers|. |headers| should be raw-
682 // formatted (NULLs instead of EOLs).
683 void SetResponse(const std::string& headers, const std::string& data) {
684 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
686 response_data_ = data;
688 void SetResponse(const std::string& headers) {
689 SetResponse(headers, std::string());
692 void SendDataReceivedACKs(bool send_acks) {
693 send_data_received_acks_ = send_acks;
696 // Intercepts requests for the given protocol.
697 void HandleScheme(const std::string& scheme) {
698 DCHECK(scheme_.empty());
699 DCHECK(!old_factory_);
701 old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory(
702 scheme_, &ResourceDispatcherHostTest::Factory);
703 EnsureSchemeIsAllowed(scheme);
706 // Our own net::URLRequestJob factory.
707 static net::URLRequestJob* Factory(net::URLRequest* request,
708 net::NetworkDelegate* network_delegate,
709 const std::string& scheme) {
710 url_request_jobs_created_count_++;
711 if (test_fixture_->response_headers_.empty()) {
713 return new URLRequestTestDelayedStartJob(request, network_delegate);
714 } else if (delay_complete_) {
715 return new URLRequestTestDelayedCompletionJob(request,
717 } else if (network_start_notification_) {
718 return new URLRequestTestDelayedNetworkJob(request, network_delegate);
719 } else if (scheme == "big-job") {
720 return new URLRequestBigJob(request, network_delegate);
722 return new net::URLRequestTestJob(request, network_delegate);
726 return new URLRequestTestDelayedStartJob(
727 request, network_delegate,
728 test_fixture_->response_headers_, test_fixture_->response_data_,
730 } else if (delay_complete_) {
731 return new URLRequestTestDelayedCompletionJob(
732 request, network_delegate,
733 test_fixture_->response_headers_, test_fixture_->response_data_,
736 return new net::URLRequestTestJob(
737 request, network_delegate,
738 test_fixture_->response_headers_, test_fixture_->response_data_,
744 void SetDelayedStartJobGeneration(bool delay_job_start) {
745 delay_start_ = delay_job_start;
748 void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
749 delay_complete_ = delay_job_complete;
752 void SetNetworkStartNotificationJobGeneration(bool notification) {
753 network_start_notification_ = notification;
756 void GenerateDataReceivedACK(const IPC::Message& msg) {
757 EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
760 bool result = PickleIterator(msg).ReadInt(&request_id);
762 scoped_ptr<IPC::Message> ack(
763 new ResourceHostMsg_DataReceived_ACK(request_id));
765 base::MessageLoop::current()->PostTask(
767 base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
770 // Setting filters for testing renderer messages.
771 // Returns the previous filter.
772 ResourceMessageFilter* SetFilter(ResourceMessageFilter* new_filter) {
773 ResourceMessageFilter* old_filter = host_.filter_;
774 host_.filter_ = new_filter;
778 base::MessageLoopForIO message_loop_;
779 BrowserThreadImpl ui_thread_;
780 BrowserThreadImpl file_thread_;
781 BrowserThreadImpl cache_thread_;
782 BrowserThreadImpl io_thread_;
783 scoped_ptr<TestBrowserContext> browser_context_;
784 scoped_refptr<ForwardingFilter> filter_;
785 net::TestNetworkDelegate network_delegate_;
786 ResourceDispatcherHostImpl host_;
787 ResourceIPCAccumulator accum_;
788 std::string response_headers_;
789 std::string response_data_;
791 net::URLRequest::ProtocolFactory* old_factory_;
792 bool send_data_received_acks_;
793 std::set<int> child_ids_;
794 static ResourceDispatcherHostTest* test_fixture_;
795 static bool delay_start_;
796 static bool delay_complete_;
797 static bool network_start_notification_;
798 static int url_request_jobs_created_count_;
801 ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL;
802 bool ResourceDispatcherHostTest::delay_start_ = false;
803 bool ResourceDispatcherHostTest::delay_complete_ = false;
804 bool ResourceDispatcherHostTest::network_start_notification_ = false;
805 int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0;
807 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
810 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
811 url, ResourceType::SUB_RESOURCE);
814 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
815 ResourceMessageFilter* filter,
819 ResourceType::Type type) {
820 // If it's already there, this'll be dropped on the floor, which is fine.
821 child_ids_.insert(filter->child_id());
823 ResourceHostMsg_Request request =
824 CreateResourceRequest("GET", type, url);
825 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
827 host_.OnMessageReceived(msg, filter, &msg_was_ok);
831 void ResourceDispatcherHostTest::CancelRequest(int request_id) {
832 host_.CancelRequest(filter_->child_id(), request_id);
835 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
836 CompleteStartRequest(filter_.get(), request_id);
839 void ResourceDispatcherHostTest::CompleteStartRequest(
840 ResourceMessageFilter* filter,
842 GlobalRequestID gid(filter->child_id(), request_id);
843 net::URLRequest* req = host_.GetURLRequest(gid);
846 URLRequestTestDelayedStartJob::CompleteStart(req);
849 void CheckRequestCompleteErrorCode(const IPC::Message& message,
850 int expected_error_code) {
851 // Verify the expected error code was received.
855 ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
857 PickleIterator iter(message);
858 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
859 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
860 ASSERT_EQ(expected_error_code, error_code);
863 testing::AssertionResult ExtractDataOffsetAndLength(const IPC::Message& message,
866 PickleIterator iter(message);
868 if (!IPC::ReadParam(&message, &iter, &request_id))
869 return testing::AssertionFailure() << "Could not read request_id";
870 if (!IPC::ReadParam(&message, &iter, data_offset))
871 return testing::AssertionFailure() << "Could not read data_offset";
872 if (!IPC::ReadParam(&message, &iter, data_length))
873 return testing::AssertionFailure() << "Could not read data_length";
874 return testing::AssertionSuccess();
877 void CheckSuccessfulRequestWithErrorCode(
878 const std::vector<IPC::Message>& messages,
879 const std::string& reference_data,
880 int expected_error) {
881 // A successful request will have received 4 messages:
882 // ReceivedResponse (indicates headers received)
883 // SetDataBuffer (contains shared memory handle)
884 // DataReceived (data offset and length into shared memory)
885 // RequestComplete (request is done)
887 // This function verifies that we received 4 messages and that they are
888 // appropriate. It allows for an error code other than net::OK if the request
889 // should successfully receive data and then abort, e.g., on cancel.
890 ASSERT_EQ(4U, messages.size());
892 // The first messages should be received response
893 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
895 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
897 PickleIterator iter(messages[1]);
899 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
900 base::SharedMemoryHandle shm_handle;
901 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
903 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
905 // Followed by the data, currently we only do the data in one chunk, but
906 // should probably test multiple chunks later
907 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
912 ExtractDataOffsetAndLength(messages[2], &data_offset, &data_length));
914 ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
915 ASSERT_GE(shm_size, data_length);
917 base::SharedMemory shared_mem(shm_handle, true); // read only
918 shared_mem.Map(data_length);
919 const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
920 ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
922 // The last message should be all data received.
923 CheckRequestCompleteErrorCode(messages[3], expected_error);
926 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
927 const std::string& reference_data) {
928 CheckSuccessfulRequestWithErrorCode(messages, reference_data, net::OK);
931 void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages,
932 const std::string& reference_data) {
933 ASSERT_EQ(5U, messages.size());
934 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type());
936 const std::vector<IPC::Message> second_req_msgs =
937 std::vector<IPC::Message>(messages.begin() + 1, messages.end());
938 CheckSuccessfulRequest(second_req_msgs, reference_data);
941 void CheckFailedRequest(const std::vector<IPC::Message>& messages,
942 const std::string& reference_data,
943 int expected_error) {
944 ASSERT_LT(0U, messages.size());
945 ASSERT_GE(2U, messages.size());
946 size_t failure_index = messages.size() - 1;
948 if (messages.size() == 2) {
949 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
952 CheckRequestCompleteErrorCode(messages[failure_index], expected_error);
955 // Tests whether many messages get dispatched properly.
956 TEST_F(ResourceDispatcherHostTest, TestMany) {
957 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
958 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
959 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
960 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
961 net::URLRequestTestJob::test_url_4(),
962 ResourceType::PREFETCH); // detachable type
963 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
965 // Finish the redirection
966 ResourceHostMsg_FollowRedirect redirect_msg(5, false, GURL());
968 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
969 base::MessageLoop::current()->RunUntilIdle();
971 // flush all the pending requests
972 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
974 // sorts out all the messages we saw by request
975 ResourceIPCAccumulator::ClassifiedMessages msgs;
976 accum_.GetClassifiedMessages(&msgs);
978 // there are five requests, so we should have gotten them classified as such
979 ASSERT_EQ(5U, msgs.size());
981 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
982 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
983 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
984 CheckSuccessfulRequest(msgs[3], net::URLRequestTestJob::test_data_4());
985 CheckSuccessfulRedirect(msgs[4], net::URLRequestTestJob::test_data_2());
988 // Tests whether messages get canceled properly. We issue four requests,
989 // cancel two of them, and make sure that each sent the proper notifications.
990 TEST_F(ResourceDispatcherHostTest, Cancel) {
991 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
992 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
993 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
995 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
996 net::URLRequestTestJob::test_url_4(),
997 ResourceType::PREFETCH); // detachable type
1001 // Cancel request must come from the renderer for a detachable resource to
1003 RendererCancelRequest(4);
1005 // The handler should have been detached now.
1006 GlobalRequestID global_request_id(filter_->child_id(), 4);
1007 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1008 host_.GetURLRequest(global_request_id));
1009 ASSERT_TRUE(info->detachable_handler()->is_detached());
1011 // flush all the pending requests
1012 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1013 base::MessageLoop::current()->RunUntilIdle();
1015 // Everything should be out now.
1016 EXPECT_EQ(0, host_.pending_requests());
1018 ResourceIPCAccumulator::ClassifiedMessages msgs;
1019 accum_.GetClassifiedMessages(&msgs);
1021 // there are four requests, so we should have gotten them classified as such
1022 ASSERT_EQ(4U, msgs.size());
1024 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1025 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1027 // Check that request 2 and 4 got canceled, as far as the renderer is
1028 // concerned. Request 2 will have been deleted.
1029 ASSERT_EQ(1U, msgs[1].size());
1030 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1032 ASSERT_EQ(2U, msgs[3].size());
1033 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[3][0].type());
1034 CheckRequestCompleteErrorCode(msgs[3][1], net::ERR_ABORTED);
1036 // However, request 4 should have actually gone to completion. (Only request 2
1038 EXPECT_EQ(4, network_delegate()->completed_requests());
1039 EXPECT_EQ(1, network_delegate()->canceled_requests());
1040 EXPECT_EQ(0, network_delegate()->error_count());
1043 // Shows that detachable requests will timeout if the request takes too long to
1045 TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
1046 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1047 net::URLRequestTestJob::test_url_2(),
1048 ResourceType::PREFETCH); // detachable type
1049 GlobalRequestID global_request_id(filter_->child_id(), 1);
1050 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1051 host_.GetURLRequest(global_request_id));
1052 ASSERT_TRUE(info->detachable_handler());
1053 info->detachable_handler()->set_cancel_delay(
1054 base::TimeDelta::FromMilliseconds(200));
1055 base::MessageLoop::current()->RunUntilIdle();
1057 RendererCancelRequest(1);
1059 // From the renderer's perspective, the request was cancelled.
1060 ResourceIPCAccumulator::ClassifiedMessages msgs;
1061 accum_.GetClassifiedMessages(&msgs);
1062 ASSERT_EQ(1U, msgs.size());
1063 ASSERT_EQ(2U, msgs[0].size());
1064 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1065 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1067 // But it continues detached.
1068 EXPECT_EQ(1, host_.pending_requests());
1069 EXPECT_TRUE(info->detachable_handler()->is_detached());
1071 // Wait until after the delay timer times out before we start processing any
1073 base::OneShotTimer<base::MessageLoop> timer;
1074 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1075 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1076 base::MessageLoop::current()->Run();
1078 // The prefetch should be cancelled by now.
1079 EXPECT_EQ(0, host_.pending_requests());
1080 EXPECT_EQ(1, network_delegate()->completed_requests());
1081 EXPECT_EQ(1, network_delegate()->canceled_requests());
1082 EXPECT_EQ(0, network_delegate()->error_count());
1085 // If the filter has disappeared then detachable resources should continue to
1087 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
1088 // test_url_1's data is available synchronously, so use 2 and 3.
1089 ResourceHostMsg_Request request_prefetch = CreateResourceRequest(
1090 "GET", ResourceType::PREFETCH, net::URLRequestTestJob::test_url_2());
1091 ResourceHostMsg_Request request_ping = CreateResourceRequest(
1092 "GET", ResourceType::PING, net::URLRequestTestJob::test_url_3());
1095 ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch);
1096 host_.OnMessageReceived(msg_prefetch, filter_, &msg_was_ok);
1097 ResourceHostMsg_RequestResource msg_ping(0, 2, request_ping);
1098 host_.OnMessageReceived(msg_ping, filter_, &msg_was_ok);
1100 // Remove the filter before processing the requests by simulating channel
1102 ResourceRequestInfoImpl* info_prefetch = ResourceRequestInfoImpl::ForRequest(
1103 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
1104 ResourceRequestInfoImpl* info_ping = ResourceRequestInfoImpl::ForRequest(
1105 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2)));
1106 DCHECK_EQ(filter_.get(), info_prefetch->filter());
1107 DCHECK_EQ(filter_.get(), info_ping->filter());
1108 filter_->OnChannelClosing();
1109 info_prefetch->filter_.reset();
1110 info_ping->filter_.reset();
1112 // From the renderer's perspective, the requests were cancelled.
1113 ResourceIPCAccumulator::ClassifiedMessages msgs;
1114 accum_.GetClassifiedMessages(&msgs);
1115 ASSERT_EQ(2U, msgs.size());
1116 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1117 CheckRequestCompleteErrorCode(msgs[1][0], net::ERR_ABORTED);
1119 // But it continues detached.
1120 EXPECT_EQ(2, host_.pending_requests());
1121 EXPECT_TRUE(info_prefetch->detachable_handler()->is_detached());
1122 EXPECT_TRUE(info_ping->detachable_handler()->is_detached());
1126 // Make sure the requests weren't canceled early.
1127 EXPECT_EQ(2, host_.pending_requests());
1129 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1130 base::MessageLoop::current()->RunUntilIdle();
1132 EXPECT_EQ(0, host_.pending_requests());
1133 EXPECT_EQ(2, network_delegate()->completed_requests());
1134 EXPECT_EQ(0, network_delegate()->canceled_requests());
1135 EXPECT_EQ(0, network_delegate()->error_count());
1138 // If the filter has disappeared (original process dies) then detachable
1139 // resources should continue to load, even when redirected.
1140 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
1141 ResourceHostMsg_Request request = CreateResourceRequest(
1142 "GET", ResourceType::PREFETCH,
1143 net::URLRequestTestJob::test_url_redirect_to_url_2());
1145 ResourceHostMsg_RequestResource msg(0, 1, request);
1147 host_.OnMessageReceived(msg, filter_, &msg_was_ok);
1149 // Remove the filter before processing the request by simulating channel
1151 GlobalRequestID global_request_id(filter_->child_id(), 1);
1152 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1153 host_.GetURLRequest(global_request_id));
1154 info->filter_->OnChannelClosing();
1155 info->filter_.reset();
1157 // From the renderer's perspective, the request was cancelled.
1158 ResourceIPCAccumulator::ClassifiedMessages msgs;
1159 accum_.GetClassifiedMessages(&msgs);
1160 ASSERT_EQ(1U, msgs.size());
1161 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1163 // But it continues detached.
1164 EXPECT_EQ(1, host_.pending_requests());
1165 EXPECT_TRUE(info->detachable_handler()->is_detached());
1167 // Verify no redirects before resetting the filter.
1168 net::URLRequest* url_request = host_.GetURLRequest(global_request_id);
1169 EXPECT_EQ(1u, url_request->url_chain().size());
1172 // Verify that a redirect was followed.
1173 EXPECT_EQ(2u, url_request->url_chain().size());
1175 // Make sure the request wasn't canceled early.
1176 EXPECT_EQ(1, host_.pending_requests());
1178 // Finish up the request.
1179 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1180 base::MessageLoop::current()->RunUntilIdle();
1182 EXPECT_EQ(0, host_.pending_requests());
1183 EXPECT_EQ(1, network_delegate()->completed_requests());
1184 EXPECT_EQ(0, network_delegate()->canceled_requests());
1185 EXPECT_EQ(0, network_delegate()->error_count());
1188 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
1189 bool was_deleted = false;
1191 // Arrange to have requests deferred before starting.
1192 TestResourceDispatcherHostDelegate delegate;
1193 delegate.set_flags(DEFER_STARTING_REQUEST);
1194 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1195 host_.SetDelegate(&delegate);
1197 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1198 // We cancel from the renderer because all non-renderer cancels delete
1199 // the request synchronously.
1200 RendererCancelRequest(1);
1202 // Our TestResourceThrottle should not have been deleted yet. This is to
1203 // ensure that destruction of the URLRequest happens asynchronously to
1204 // calling CancelRequest.
1205 EXPECT_FALSE(was_deleted);
1207 base::MessageLoop::current()->RunUntilIdle();
1209 EXPECT_TRUE(was_deleted);
1212 TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
1213 bool was_deleted = false;
1215 // Arrange to have requests deferred before starting.
1216 TestResourceDispatcherHostDelegate delegate;
1217 delegate.set_flags(DEFER_STARTING_REQUEST);
1218 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1219 host_.SetDelegate(&delegate);
1221 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1222 net::URLRequestTestJob::test_url_1(),
1223 ResourceType::PREFETCH); // detachable type
1224 // Cancel request must come from the renderer for a detachable resource to
1226 RendererCancelRequest(1);
1228 // Even after driving the event loop, the request has not been deleted.
1229 EXPECT_FALSE(was_deleted);
1231 // However, it is still throttled because the defer happened above the
1232 // DetachableResourceHandler.
1233 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1234 base::MessageLoop::current()->RunUntilIdle();
1235 EXPECT_FALSE(was_deleted);
1237 // Resume the request.
1238 GenericResourceThrottle* throttle =
1239 GenericResourceThrottle::active_throttle();
1240 ASSERT_TRUE(throttle);
1243 // Now, the request completes.
1244 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1245 base::MessageLoop::current()->RunUntilIdle();
1246 EXPECT_TRUE(was_deleted);
1247 EXPECT_EQ(1, network_delegate()->completed_requests());
1248 EXPECT_EQ(0, network_delegate()->canceled_requests());
1249 EXPECT_EQ(0, network_delegate()->error_count());
1252 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1253 // URLRequest will not be started.
1254 TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
1255 TestResourceDispatcherHostDelegate delegate;
1256 delegate.set_flags(CANCEL_BEFORE_START);
1257 host_.SetDelegate(&delegate);
1259 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1261 // flush all the pending requests
1262 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1263 base::MessageLoop::current()->RunUntilIdle();
1265 ResourceIPCAccumulator::ClassifiedMessages msgs;
1266 accum_.GetClassifiedMessages(&msgs);
1268 // Check that request got canceled.
1269 ASSERT_EQ(1U, msgs[0].size());
1270 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1272 // Make sure URLRequest is never started.
1273 EXPECT_EQ(0, url_request_jobs_created_count_);
1276 TEST_F(ResourceDispatcherHostTest, PausedStartError) {
1277 // Arrange to have requests deferred before processing response headers.
1278 TestResourceDispatcherHostDelegate delegate;
1279 delegate.set_flags(DEFER_PROCESSING_RESPONSE);
1280 host_.SetDelegate(&delegate);
1282 SetDelayedStartJobGeneration(true);
1283 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1284 CompleteStartRequest(1);
1286 // flush all the pending requests
1287 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1288 base::MessageLoop::current()->RunUntilIdle();
1290 EXPECT_EQ(0, host_.pending_requests());
1293 // Test the OnBeforeNetworkStart throttle.
1294 TEST_F(ResourceDispatcherHostTest, ThrottleNetworkStart) {
1295 // Arrange to have requests deferred before processing response headers.
1296 TestResourceDispatcherHostDelegate delegate;
1297 delegate.set_flags(DEFER_NETWORK_START);
1298 host_.SetDelegate(&delegate);
1300 SetNetworkStartNotificationJobGeneration(true);
1301 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1303 // Should have deferred for network start.
1304 GenericResourceThrottle* first_throttle =
1305 GenericResourceThrottle::active_throttle();
1306 ASSERT_TRUE(first_throttle);
1307 EXPECT_EQ(0, network_delegate()->completed_requests());
1308 EXPECT_EQ(1, host_.pending_requests());
1310 first_throttle->Resume();
1312 // Flush all the pending requests.
1313 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1314 base::MessageLoop::current()->RunUntilIdle();
1316 EXPECT_EQ(1, network_delegate()->completed_requests());
1317 EXPECT_EQ(0, host_.pending_requests());
1320 TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
1321 // Arrange to have requests deferred before starting.
1322 TestResourceDispatcherHostDelegate delegate;
1323 delegate.set_flags(DEFER_STARTING_REQUEST);
1324 delegate.set_create_two_throttles(true);
1325 host_.SetDelegate(&delegate);
1327 // Make sure the first throttle blocked the request, and then resume.
1328 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1329 GenericResourceThrottle* first_throttle =
1330 GenericResourceThrottle::active_throttle();
1331 ASSERT_TRUE(first_throttle);
1332 first_throttle->Resume();
1334 // Make sure the second throttle blocked the request, and then resume.
1335 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1336 ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
1337 GenericResourceThrottle::active_throttle()->Resume();
1339 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1341 // The request is started asynchronously.
1342 base::MessageLoop::current()->RunUntilIdle();
1344 // Flush all the pending requests.
1345 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1347 EXPECT_EQ(0, host_.pending_requests());
1349 // Make sure the request completed successfully.
1350 ResourceIPCAccumulator::ClassifiedMessages msgs;
1351 accum_.GetClassifiedMessages(&msgs);
1352 ASSERT_EQ(1U, msgs.size());
1353 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1357 // Tests that the delegate can cancel a request and provide a error code.
1358 TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
1359 TestResourceDispatcherHostDelegate delegate;
1360 delegate.set_flags(CANCEL_BEFORE_START);
1361 delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
1362 host_.SetDelegate(&delegate);
1364 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1365 // The request will get cancelled by the throttle.
1367 // flush all the pending requests
1368 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1369 base::MessageLoop::current()->RunUntilIdle();
1371 ResourceIPCAccumulator::ClassifiedMessages msgs;
1372 accum_.GetClassifiedMessages(&msgs);
1374 // Check the cancellation
1375 ASSERT_EQ(1U, msgs.size());
1376 ASSERT_EQ(1U, msgs[0].size());
1378 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ACCESS_DENIED);
1381 // The host delegate acts as a second one so we can have some requests
1382 // pending and some canceled.
1383 class TestFilter : public ForwardingFilter {
1385 explicit TestFilter(ResourceContext* resource_context)
1386 : ForwardingFilter(NULL, resource_context),
1387 has_canceled_(false),
1388 received_after_canceled_(0) {
1391 // ForwardingFilter override
1392 virtual bool Send(IPC::Message* msg) OVERRIDE {
1393 // no messages should be received when the process has been canceled
1395 received_after_canceled_++;
1401 int received_after_canceled_;
1404 virtual ~TestFilter() {}
1407 // Tests CancelRequestsForProcess
1408 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
1409 scoped_refptr<TestFilter> test_filter = new TestFilter(
1410 browser_context_->GetResourceContext());
1412 // request 1 goes to the test delegate
1413 ResourceHostMsg_Request request = CreateResourceRequest(
1414 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
1416 MakeTestRequestWithResourceType(test_filter.get(), 0, 1,
1417 net::URLRequestTestJob::test_url_1(),
1418 ResourceType::SUB_RESOURCE);
1420 // request 2 goes to us
1421 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1423 // request 3 goes to the test delegate
1424 MakeTestRequestWithResourceType(test_filter.get(), 0, 3,
1425 net::URLRequestTestJob::test_url_3(),
1426 ResourceType::SUB_RESOURCE);
1428 // request 4 goes to us
1429 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1430 net::URLRequestTestJob::test_url_4(),
1431 ResourceType::PREFETCH); // detachable type
1434 // Make sure all requests have finished stage one. test_url_1 will have
1436 base::MessageLoop::current()->RunUntilIdle();
1439 // Now that the async IO path is in place, the IO always completes on the
1440 // initial call; so the requests have already completed. This basically
1441 // breaks the whole test.
1442 //EXPECT_EQ(3, host_.pending_requests());
1444 // Process test_url_2 and test_url_3 for one level so one callback is called.
1445 // We'll cancel test_url_4 (detachable) before processing it to verify that it
1446 // delays the cancel.
1447 for (int i = 0; i < 2; i++)
1448 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1450 // Cancel the requests to the test process.
1451 host_.CancelRequestsForProcess(filter_->child_id());
1452 test_filter->has_canceled_ = true;
1454 // The requests should all be cancelled, except request 4, which is detached.
1455 EXPECT_EQ(1, host_.pending_requests());
1456 GlobalRequestID global_request_id(filter_->child_id(), 4);
1457 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1458 host_.GetURLRequest(global_request_id));
1459 ASSERT_TRUE(info->detachable_handler()->is_detached());
1461 // Flush all the pending requests.
1462 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1464 EXPECT_EQ(0, host_.pending_requests());
1466 // The test delegate should not have gotten any messages after being canceled.
1467 ASSERT_EQ(0, test_filter->received_after_canceled_);
1469 // There should be two results.
1470 ResourceIPCAccumulator::ClassifiedMessages msgs;
1471 accum_.GetClassifiedMessages(&msgs);
1472 ASSERT_EQ(2U, msgs.size());
1473 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1474 // The detachable request was cancelled by the renderer before it
1475 // finished. From the perspective of the renderer, it should have cancelled.
1476 ASSERT_EQ(2U, msgs[1].size());
1477 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1478 CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED);
1479 // But it completed anyway. For the network stack, no requests were canceled.
1480 EXPECT_EQ(4, network_delegate()->completed_requests());
1481 EXPECT_EQ(0, network_delegate()->canceled_requests());
1482 EXPECT_EQ(0, network_delegate()->error_count());
1485 TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
1486 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1487 net::URLRequestTestJob::test_url_4(),
1488 ResourceType::PREFETCH); // detachable type
1489 GlobalRequestID global_request_id(filter_->child_id(), 1);
1490 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1491 host_.GetURLRequest(global_request_id));
1492 ASSERT_TRUE(info->detachable_handler());
1493 info->detachable_handler()->set_cancel_delay(
1494 base::TimeDelta::FromMilliseconds(200));
1495 base::MessageLoop::current()->RunUntilIdle();
1497 // Cancel the requests to the test process.
1498 host_.CancelRequestsForProcess(filter_->child_id());
1499 EXPECT_EQ(1, host_.pending_requests());
1501 // Wait until after the delay timer times out before we start processing any
1503 base::OneShotTimer<base::MessageLoop> timer;
1504 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1505 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1506 base::MessageLoop::current()->Run();
1508 // The prefetch should be cancelled by now.
1509 EXPECT_EQ(0, host_.pending_requests());
1511 // In case any messages are still to be processed.
1512 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1513 base::MessageLoop::current()->RunUntilIdle();
1515 ResourceIPCAccumulator::ClassifiedMessages msgs;
1516 accum_.GetClassifiedMessages(&msgs);
1518 ASSERT_EQ(1U, msgs.size());
1520 // The request should have cancelled.
1521 ASSERT_EQ(2U, msgs[0].size());
1522 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1523 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1524 // And not run to completion.
1525 EXPECT_EQ(1, network_delegate()->completed_requests());
1526 EXPECT_EQ(1, network_delegate()->canceled_requests());
1527 EXPECT_EQ(0, network_delegate()->error_count());
1530 // Tests blocking and resuming requests.
1531 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
1532 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1533 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1534 host_.BlockRequestsForRoute(filter_->child_id(), 3);
1536 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1537 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1538 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1539 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1540 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1541 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1543 // Flush all the pending requests
1544 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1546 // Sort out all the messages we saw by request
1547 ResourceIPCAccumulator::ClassifiedMessages msgs;
1548 accum_.GetClassifiedMessages(&msgs);
1550 // All requests but the 2 for the RVH 0 should have been blocked.
1551 ASSERT_EQ(2U, msgs.size());
1553 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1554 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1556 // Resume requests for RVH 1 and flush pending requests.
1557 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
1559 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1562 accum_.GetClassifiedMessages(&msgs);
1563 ASSERT_EQ(2U, msgs.size());
1564 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1565 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
1567 // Test that new requests are not blocked for RVH 1.
1568 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1569 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1571 accum_.GetClassifiedMessages(&msgs);
1572 ASSERT_EQ(1U, msgs.size());
1573 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1575 // Now resumes requests for all RVH (2 and 3).
1576 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
1577 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
1579 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1582 accum_.GetClassifiedMessages(&msgs);
1583 ASSERT_EQ(2U, msgs.size());
1584 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1585 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1588 // Tests blocking and canceling requests.
1589 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
1590 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1592 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1593 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1594 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1595 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1596 // Blocked detachable resources should not delay cancellation.
1597 MakeTestRequestWithResourceType(filter_.get(), 1, 5,
1598 net::URLRequestTestJob::test_url_4(),
1599 ResourceType::PREFETCH); // detachable type
1601 // Flush all the pending requests.
1602 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1604 // Sort out all the messages we saw by request.
1605 ResourceIPCAccumulator::ClassifiedMessages msgs;
1606 accum_.GetClassifiedMessages(&msgs);
1608 // The 2 requests for the RVH 0 should have been processed.
1609 ASSERT_EQ(2U, msgs.size());
1611 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1612 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1614 // Cancel requests for RVH 1.
1615 host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
1617 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1620 accum_.GetClassifiedMessages(&msgs);
1621 ASSERT_EQ(0U, msgs.size());
1624 // Tests that blocked requests are canceled if their associated process dies.
1625 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
1626 // This second filter is used to emulate a second process.
1627 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1628 this, browser_context_->GetResourceContext());
1630 host_.BlockRequestsForRoute(second_filter->child_id(), 0);
1632 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1633 net::URLRequestTestJob::test_url_1(),
1634 ResourceType::SUB_RESOURCE);
1635 MakeTestRequestWithResourceType(second_filter.get(), 0, 2,
1636 net::URLRequestTestJob::test_url_2(),
1637 ResourceType::SUB_RESOURCE);
1638 MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1639 net::URLRequestTestJob::test_url_3(),
1640 ResourceType::SUB_RESOURCE);
1641 MakeTestRequestWithResourceType(second_filter.get(), 0, 4,
1642 net::URLRequestTestJob::test_url_1(),
1643 ResourceType::SUB_RESOURCE);
1644 MakeTestRequestWithResourceType(second_filter.get(), 0, 5,
1645 net::URLRequestTestJob::test_url_4(),
1646 ResourceType::PREFETCH); // detachable type
1648 // Simulate process death.
1649 host_.CancelRequestsForProcess(second_filter->child_id());
1651 // Flush all the pending requests.
1652 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1654 // Sort out all the messages we saw by request.
1655 ResourceIPCAccumulator::ClassifiedMessages msgs;
1656 accum_.GetClassifiedMessages(&msgs);
1658 // The 2 requests for the RVH 0 should have been processed. Note that
1659 // blocked detachable requests are canceled without delay.
1660 ASSERT_EQ(2U, msgs.size());
1662 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1663 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1665 EXPECT_TRUE(host_.blocked_loaders_map_.empty());
1668 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1669 // away. Note that we rely on Purify for finding the leaks if any.
1670 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1671 // destructor to make sure the blocked requests are deleted.
1672 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
1673 // This second filter is used to emulate a second process.
1674 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1675 this, browser_context_->GetResourceContext());
1677 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1678 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1679 host_.BlockRequestsForRoute(second_filter->child_id(), 1);
1681 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1682 net::URLRequestTestJob::test_url_1(),
1683 ResourceType::SUB_RESOURCE);
1684 MakeTestRequestWithResourceType(filter_.get(), 1, 2,
1685 net::URLRequestTestJob::test_url_2(),
1686 ResourceType::SUB_RESOURCE);
1687 MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1688 net::URLRequestTestJob::test_url_3(),
1689 ResourceType::SUB_RESOURCE);
1690 MakeTestRequestWithResourceType(second_filter.get(), 1, 4,
1691 net::URLRequestTestJob::test_url_1(),
1692 ResourceType::SUB_RESOURCE);
1693 MakeTestRequestWithResourceType(filter_.get(), 2, 5,
1694 net::URLRequestTestJob::test_url_2(),
1695 ResourceType::SUB_RESOURCE);
1696 MakeTestRequestWithResourceType(filter_.get(), 2, 6,
1697 net::URLRequestTestJob::test_url_3(),
1698 ResourceType::SUB_RESOURCE);
1699 MakeTestRequestWithResourceType(filter_.get(), 0, 7,
1700 net::URLRequestTestJob::test_url_4(),
1701 ResourceType::PREFETCH); // detachable type
1702 MakeTestRequestWithResourceType(second_filter.get(), 1, 8,
1703 net::URLRequestTestJob::test_url_4(),
1704 ResourceType::PREFETCH); // detachable type
1706 host_.CancelRequestsForProcess(filter_->child_id());
1707 host_.CancelRequestsForProcess(second_filter->child_id());
1709 // Flush all the pending requests.
1710 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1713 // Test the private helper method "CalculateApproximateMemoryCost()".
1714 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
1715 net::URLRequestContext context;
1716 net::URLRequest req(
1717 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL, &context);
1719 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1721 // Add 9 bytes of referrer.
1722 req.SetReferrer("123456789");
1724 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1726 // Add 33 bytes of upload content.
1727 std::string upload_content;
1728 upload_content.resize(33);
1729 std::fill(upload_content.begin(), upload_content.end(), 'x');
1730 scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader(
1731 upload_content.data(), upload_content.size()));
1732 req.set_upload(make_scoped_ptr(
1733 net::UploadDataStream::CreateWithReader(reader.Pass(), 0)));
1735 // Since the upload throttling is disabled, this has no effect on the cost.
1737 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1740 // Test that too much memory for outstanding requests for a particular
1741 // render_process_host_id causes requests to fail.
1742 TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
1743 // Expected cost of each request as measured by
1744 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1745 int kMemoryCostOfTest2Req =
1746 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
1747 std::string("GET").size() +
1748 net::URLRequestTestJob::test_url_2().spec().size();
1750 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1751 int kMaxCostPerProcess = 440000;
1752 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
1754 // Determine how many instance of test_url_2() we can request before
1755 // throttling kicks in.
1756 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
1758 // This second filter is used to emulate a second process.
1759 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1760 this, browser_context_->GetResourceContext());
1762 // Saturate the number of outstanding requests for our process.
1763 for (size_t i = 0; i < kMaxRequests; ++i) {
1764 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1765 net::URLRequestTestJob::test_url_2(),
1766 ResourceType::SUB_RESOURCE);
1769 // Issue two more requests for our process -- these should fail immediately.
1770 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 1,
1771 net::URLRequestTestJob::test_url_2(),
1772 ResourceType::SUB_RESOURCE);
1773 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 2,
1774 net::URLRequestTestJob::test_url_2(),
1775 ResourceType::SUB_RESOURCE);
1777 // Issue two requests for the second process -- these should succeed since
1778 // it is just process 0 that is saturated.
1779 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 3,
1780 net::URLRequestTestJob::test_url_2(),
1781 ResourceType::SUB_RESOURCE);
1782 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 4,
1783 net::URLRequestTestJob::test_url_2(),
1784 ResourceType::SUB_RESOURCE);
1786 // Flush all the pending requests.
1787 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1788 base::MessageLoop::current()->RunUntilIdle();
1790 // Sorts out all the messages we saw by request.
1791 ResourceIPCAccumulator::ClassifiedMessages msgs;
1792 accum_.GetClassifiedMessages(&msgs);
1794 // We issued (kMaxRequests + 4) total requests.
1795 ASSERT_EQ(kMaxRequests + 4, msgs.size());
1797 // Check that the first kMaxRequests succeeded.
1798 for (size_t i = 0; i < kMaxRequests; ++i)
1799 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1801 // Check that the subsequent two requests (kMaxRequests + 1) and
1802 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1803 for (int i = 0; i < 2; ++i) {
1804 // Should have sent a single RequestComplete message.
1805 int index = kMaxRequests + i;
1806 CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(),
1807 net::ERR_INSUFFICIENT_RESOURCES);
1810 // The final 2 requests should have succeeded.
1811 CheckSuccessfulRequest(msgs[kMaxRequests + 2],
1812 net::URLRequestTestJob::test_data_2());
1813 CheckSuccessfulRequest(msgs[kMaxRequests + 3],
1814 net::URLRequestTestJob::test_data_2());
1817 // Test that when too many requests are outstanding for a particular
1818 // render_process_host_id, any subsequent request from it fails. Also verify
1819 // that the global limit is honored.
1820 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
1821 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1822 const size_t kMaxRequestsPerProcess = 2;
1823 host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
1824 const size_t kMaxRequests = 3;
1825 host_.set_max_num_in_flight_requests(kMaxRequests);
1827 // Needed to emulate additional processes.
1828 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1829 this, browser_context_->GetResourceContext());
1830 scoped_refptr<ForwardingFilter> third_filter = new ForwardingFilter(
1831 this, browser_context_->GetResourceContext());
1833 // Saturate the number of outstanding requests for our process.
1834 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
1835 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1836 net::URLRequestTestJob::test_url_2(),
1837 ResourceType::SUB_RESOURCE);
1840 // Issue another request for our process -- this should fail immediately.
1841 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequestsPerProcess + 1,
1842 net::URLRequestTestJob::test_url_2(),
1843 ResourceType::SUB_RESOURCE);
1845 // Issue a request for the second process -- this should succeed, because it
1846 // is just process 0 that is saturated.
1847 MakeTestRequestWithResourceType(
1848 second_filter.get(), 0, kMaxRequestsPerProcess + 2,
1849 net::URLRequestTestJob::test_url_2(), ResourceType::SUB_RESOURCE);
1851 // Issue a request for the third process -- this should fail, because the
1852 // global limit has been reached.
1853 MakeTestRequestWithResourceType(
1854 third_filter.get(), 0, kMaxRequestsPerProcess + 3,
1855 net::URLRequestTestJob::test_url_2(), ResourceType::SUB_RESOURCE);
1857 // Flush all the pending requests.
1858 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1859 base::MessageLoop::current()->RunUntilIdle();
1861 // Sorts out all the messages we saw by request.
1862 ResourceIPCAccumulator::ClassifiedMessages msgs;
1863 accum_.GetClassifiedMessages(&msgs);
1865 // The processes issued the following requests:
1866 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1867 // #2 issued 1 request that passed
1868 // #3 issued 1 request that failed
1869 ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size());
1871 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
1872 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1874 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0],
1875 net::URLRequestTestJob::test_data_2(),
1876 net::ERR_INSUFFICIENT_RESOURCES);
1877 CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1],
1878 net::URLRequestTestJob::test_data_2());
1879 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2],
1880 net::URLRequestTestJob::test_data_2(),
1881 net::ERR_INSUFFICIENT_RESOURCES);
1884 // Tests that we sniff the mime type for a simple request.
1885 TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
1886 std::string raw_headers("HTTP/1.1 200 OK\n\n");
1887 std::string response_data("<html><title>Test One</title></html>");
1888 SetResponse(raw_headers, response_data);
1890 HandleScheme("http");
1891 MakeTestRequest(0, 1, GURL("http:bla"));
1893 // Flush all pending requests.
1894 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1896 // Sorts out all the messages we saw by request.
1897 ResourceIPCAccumulator::ClassifiedMessages msgs;
1898 accum_.GetClassifiedMessages(&msgs);
1899 ASSERT_EQ(1U, msgs.size());
1901 ResourceResponseHead response_head;
1902 GetResponseHead(msgs[0], &response_head);
1903 ASSERT_EQ("text/html", response_head.mime_type);
1906 // Tests that we don't sniff the mime type when the server provides one.
1907 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
1908 std::string raw_headers("HTTP/1.1 200 OK\n"
1909 "Content-type: image/jpeg\n\n");
1910 std::string response_data("<html><title>Test One</title></html>");
1911 SetResponse(raw_headers, response_data);
1913 HandleScheme("http");
1914 MakeTestRequest(0, 1, GURL("http:bla"));
1916 // Flush all pending requests.
1917 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1919 // Sorts out all the messages we saw by request.
1920 ResourceIPCAccumulator::ClassifiedMessages msgs;
1921 accum_.GetClassifiedMessages(&msgs);
1922 ASSERT_EQ(1U, msgs.size());
1924 ResourceResponseHead response_head;
1925 GetResponseHead(msgs[0], &response_head);
1926 ASSERT_EQ("image/jpeg", response_head.mime_type);
1929 // Tests that we don't sniff the mime type when there is no message body.
1930 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
1931 SetResponse("HTTP/1.1 304 Not Modified\n\n");
1933 HandleScheme("http");
1934 MakeTestRequest(0, 1, GURL("http:bla"));
1936 // Flush all pending requests.
1937 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1939 // Sorts out all the messages we saw by request.
1940 ResourceIPCAccumulator::ClassifiedMessages msgs;
1941 accum_.GetClassifiedMessages(&msgs);
1942 ASSERT_EQ(1U, msgs.size());
1944 ResourceResponseHead response_head;
1945 GetResponseHead(msgs[0], &response_head);
1946 ASSERT_EQ("", response_head.mime_type);
1949 TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
1950 SetResponse("HTTP/1.1 204 No Content\n\n");
1952 HandleScheme("http");
1953 MakeTestRequest(0, 1, GURL("http:bla"));
1955 // Flush all pending requests.
1956 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1958 // Sorts out all the messages we saw by request.
1959 ResourceIPCAccumulator::ClassifiedMessages msgs;
1960 accum_.GetClassifiedMessages(&msgs);
1961 ASSERT_EQ(1U, msgs.size());
1963 ResourceResponseHead response_head;
1964 GetResponseHead(msgs[0], &response_head);
1965 ASSERT_EQ("text/plain", response_head.mime_type);
1968 TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
1969 SetResponse("HTTP/1.1 200 OK\n\n");
1971 HandleScheme("http");
1972 MakeTestRequest(0, 1, GURL("http:bla"));
1974 // Flush all pending requests.
1975 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1977 // Sorts out all the messages we saw by request.
1978 ResourceIPCAccumulator::ClassifiedMessages msgs;
1979 accum_.GetClassifiedMessages(&msgs);
1980 ASSERT_EQ(1U, msgs.size());
1982 ResourceResponseHead response_head;
1983 GetResponseHead(msgs[0], &response_head);
1984 ASSERT_EQ("text/plain", response_head.mime_type);
1987 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
1988 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
1989 std::string raw_headers("HTTP/1.1 403 Forbidden\n"
1990 "Content-disposition: attachment; filename=blah\n"
1991 "Content-type: application/octet-stream\n\n");
1992 std::string response_data("<html><title>Test One</title></html>");
1993 SetResponse(raw_headers, response_data);
1995 HandleScheme("http");
1997 // Only MAIN_FRAMEs can trigger a download.
1998 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"),
1999 ResourceType::MAIN_FRAME);
2001 // Flush all pending requests.
2002 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2004 // Sorts out all the messages we saw by request.
2005 ResourceIPCAccumulator::ClassifiedMessages msgs;
2006 accum_.GetClassifiedMessages(&msgs);
2008 // We should have gotten one RequestComplete message.
2009 ASSERT_EQ(1U, msgs[0].size());
2010 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2012 // The RequestComplete message should have had the error code of
2013 // ERR_FILE_NOT_FOUND.
2014 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_FILE_NOT_FOUND);
2017 // Test for http://crbug.com/76202 . We don't want to destroy a
2018 // download request prematurely when processing a cancellation from
2020 TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
2021 EXPECT_EQ(0, host_.pending_requests());
2023 int render_view_id = 0;
2026 std::string raw_headers("HTTP\n"
2027 "Content-disposition: attachment; filename=foo\n\n");
2028 std::string response_data("01234567890123456789\x01foobar");
2030 // Get past sniffing metrics in the BufferedResourceHandler. Note that
2031 // if we don't get past the sniffing metrics, the result will be that
2032 // the BufferedResourceHandler won't have figured out that it's a download,
2033 // won't have constructed a DownloadResourceHandler, and and the request
2034 // will be successfully canceled below, failing the test.
2035 response_data.resize(1025, ' ');
2037 SetResponse(raw_headers, response_data);
2038 SetDelayedCompleteJobGeneration(true);
2039 HandleScheme("http");
2041 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2042 GURL("http://example.com/blah"),
2043 ResourceType::MAIN_FRAME);
2044 // Return some data so that the request is identified as a download
2045 // and the proper resource handlers are created.
2046 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2048 // And now simulate a cancellation coming from the renderer.
2049 ResourceHostMsg_CancelRequest msg(request_id);
2051 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2053 // Since the request had already started processing as a download,
2054 // the cancellation above should have been ignored and the request
2055 // should still be alive.
2056 EXPECT_EQ(1, host_.pending_requests());
2058 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2061 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
2062 EXPECT_EQ(0, host_.pending_requests());
2064 int render_view_id = 0;
2067 std::string raw_headers("HTTP\n"
2068 "Content-disposition: attachment; filename=foo\n\n");
2069 std::string response_data("01234567890123456789\x01foobar");
2070 // Get past sniffing metrics.
2071 response_data.resize(1025, ' ');
2073 SetResponse(raw_headers, response_data);
2074 SetDelayedCompleteJobGeneration(true);
2075 HandleScheme("http");
2077 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2078 GURL("http://example.com/blah"),
2079 ResourceType::MAIN_FRAME);
2080 // Return some data so that the request is identified as a download
2081 // and the proper resource handlers are created.
2082 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2084 // And now simulate a cancellation coming from the renderer.
2085 ResourceHostMsg_CancelRequest msg(request_id);
2087 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2089 // Since the request had already started processing as a download,
2090 // the cancellation above should have been ignored and the request
2091 // should still be alive.
2092 EXPECT_EQ(1, host_.pending_requests());
2094 // Cancelling by other methods shouldn't work either.
2095 host_.CancelRequestsForProcess(render_view_id);
2096 EXPECT_EQ(1, host_.pending_requests());
2098 // Cancelling by context should work.
2099 host_.CancelRequestsForContext(filter_->resource_context());
2100 EXPECT_EQ(0, host_.pending_requests());
2103 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
2104 EXPECT_EQ(0, host_.pending_requests());
2106 int render_view_id = 0;
2109 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2110 net::URLRequestTestJob::test_url_4(),
2111 ResourceType::PREFETCH); // detachable type
2113 // Simulate a cancel coming from the renderer.
2114 RendererCancelRequest(request_id);
2116 // Since the request had already started processing as detachable,
2117 // the cancellation above should have been ignored and the request
2118 // should have been detached.
2119 EXPECT_EQ(1, host_.pending_requests());
2121 // Cancelling by other methods should also leave it detached.
2122 host_.CancelRequestsForProcess(render_view_id);
2123 EXPECT_EQ(1, host_.pending_requests());
2125 // Cancelling by context should work.
2126 host_.CancelRequestsForContext(filter_->resource_context());
2127 EXPECT_EQ(0, host_.pending_requests());
2130 // Test the cancelling of requests that are being transferred to a new renderer
2131 // due to a redirection.
2132 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
2133 EXPECT_EQ(0, host_.pending_requests());
2135 int render_view_id = 0;
2138 std::string raw_headers("HTTP/1.1 200 OK\n"
2139 "Content-Type: text/html; charset=utf-8\n\n");
2140 std::string response_data("<html>foobar</html>");
2142 SetResponse(raw_headers, response_data);
2143 HandleScheme("http");
2145 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2146 GURL("http://example.com/blah"),
2147 ResourceType::MAIN_FRAME);
2150 GlobalRequestID global_request_id(filter_->child_id(), request_id);
2151 host_.MarkAsTransferredNavigation(global_request_id);
2153 // And now simulate a cancellation coming from the renderer.
2154 ResourceHostMsg_CancelRequest msg(request_id);
2156 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2158 // Since the request is marked as being transferred,
2159 // the cancellation above should have been ignored and the request
2160 // should still be alive.
2161 EXPECT_EQ(1, host_.pending_requests());
2163 // Cancelling by other methods shouldn't work either.
2164 host_.CancelRequestsForProcess(render_view_id);
2165 EXPECT_EQ(1, host_.pending_requests());
2167 // Cancelling by context should work.
2168 host_.CancelRequestsForContext(filter_->resource_context());
2169 EXPECT_EQ(0, host_.pending_requests());
2172 // Test transferred navigations with text/html, which doesn't trigger any
2173 // content sniffing.
2174 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
2175 // This test expects the cross site request to be leaked, so it can transfer
2176 // the request directly.
2177 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2179 EXPECT_EQ(0, host_.pending_requests());
2181 int render_view_id = 0;
2184 // Configure initial request.
2185 SetResponse("HTTP/1.1 302 Found\n"
2186 "Location: http://other.com/blech\n\n");
2188 HandleScheme("http");
2190 // Temporarily replace ContentBrowserClient with one that will trigger the
2191 // transfer navigation code paths.
2192 TransfersAllNavigationsContentBrowserClient new_client;
2193 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2195 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2196 GURL("http://example.com/blah"),
2197 ResourceType::MAIN_FRAME);
2199 // Now that we're blocked on the redirect, update the response and unblock by
2200 // telling the AsyncResourceHandler to follow the redirect.
2201 const std::string kResponseBody = "hello world";
2202 SetResponse("HTTP/1.1 200 OK\n"
2203 "Content-Type: text/html\n\n",
2205 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
2207 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
2208 base::MessageLoop::current()->RunUntilIdle();
2210 // Flush all the pending requests to get the response through the
2211 // BufferedResourceHandler.
2212 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2214 // Restore, now that we've set up a transfer.
2215 SetBrowserClientForTesting(old_client);
2217 // This second filter is used to emulate a second process.
2218 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
2219 this, browser_context_->GetResourceContext());
2221 int new_render_view_id = 1;
2222 int new_request_id = 2;
2224 ResourceHostMsg_Request request =
2225 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2226 GURL("http://other.com/blech"));
2227 request.transferred_request_child_id = filter_->child_id();
2228 request.transferred_request_request_id = request_id;
2231 child_ids_.insert(second_filter->child_id());
2232 ResourceHostMsg_RequestResource transfer_request_msg(
2233 new_render_view_id, new_request_id, request);
2234 host_.OnMessageReceived(
2235 transfer_request_msg, second_filter.get(), &msg_was_ok);
2236 base::MessageLoop::current()->RunUntilIdle();
2238 // Check generated messages.
2239 ResourceIPCAccumulator::ClassifiedMessages msgs;
2240 accum_.GetClassifiedMessages(&msgs);
2242 ASSERT_EQ(2U, msgs.size());
2243 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2244 CheckSuccessfulRequest(msgs[1], kResponseBody);
2247 // Test transferred navigations with text/plain, which causes
2248 // BufferedResourceHandler to buffer the response to sniff the content
2249 // before the transfer occurs.
2250 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
2251 // This test expects the cross site request to be leaked, so it can transfer
2252 // the request directly.
2253 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2255 EXPECT_EQ(0, host_.pending_requests());
2257 int render_view_id = 0;
2260 // Configure initial request.
2261 SetResponse("HTTP/1.1 302 Found\n"
2262 "Location: http://other.com/blech\n\n");
2264 HandleScheme("http");
2266 // Temporarily replace ContentBrowserClient with one that will trigger the
2267 // transfer navigation code paths.
2268 TransfersAllNavigationsContentBrowserClient new_client;
2269 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2271 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2272 GURL("http://example.com/blah"),
2273 ResourceType::MAIN_FRAME);
2275 // Now that we're blocked on the redirect, update the response and unblock by
2276 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
2277 // MIME type, which causes BufferedResourceHandler to buffer it before the
2279 const std::string kResponseBody = "hello world";
2280 SetResponse("HTTP/1.1 200 OK\n"
2281 "Content-Type: text/plain\n\n",
2283 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
2285 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
2286 base::MessageLoop::current()->RunUntilIdle();
2288 // Flush all the pending requests to get the response through the
2289 // BufferedResourceHandler.
2290 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2292 // Restore, now that we've set up a transfer.
2293 SetBrowserClientForTesting(old_client);
2295 // This second filter is used to emulate a second process.
2296 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
2297 this, browser_context_->GetResourceContext());
2299 int new_render_view_id = 1;
2300 int new_request_id = 2;
2302 ResourceHostMsg_Request request =
2303 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2304 GURL("http://other.com/blech"));
2305 request.transferred_request_child_id = filter_->child_id();
2306 request.transferred_request_request_id = request_id;
2309 child_ids_.insert(second_filter->child_id());
2310 ResourceHostMsg_RequestResource transfer_request_msg(
2311 new_render_view_id, new_request_id, request);
2312 host_.OnMessageReceived(
2313 transfer_request_msg, second_filter.get(), &msg_was_ok);
2314 base::MessageLoop::current()->RunUntilIdle();
2316 // Check generated messages.
2317 ResourceIPCAccumulator::ClassifiedMessages msgs;
2318 accum_.GetClassifiedMessages(&msgs);
2320 ASSERT_EQ(2U, msgs.size());
2321 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2322 CheckSuccessfulRequest(msgs[1], kResponseBody);
2325 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
2326 // This test expects the cross site request to be leaked, so it can transfer
2327 // the request directly.
2328 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2330 EXPECT_EQ(0, host_.pending_requests());
2332 int render_view_id = 0;
2334 int first_child_id = -1;
2336 // Configure initial request.
2337 SetResponse("HTTP/1.1 302 Found\n"
2338 "Location: http://other.com/blech\n\n");
2339 const std::string kResponseBody = "hello world";
2341 HandleScheme("http");
2343 // Temporarily replace ContentBrowserClient with one that will trigger the
2344 // transfer navigation code paths.
2345 TransfersAllNavigationsContentBrowserClient new_client;
2346 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2348 // Create a first filter that can be deleted before the second one starts.
2350 scoped_refptr<ForwardingFilter> first_filter = new ForwardingFilter(
2351 this, browser_context_->GetResourceContext());
2352 first_child_id = first_filter->child_id();
2354 ResourceHostMsg_Request first_request =
2355 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2356 GURL("http://example.com/blah"));
2359 child_ids_.insert(first_child_id);
2360 ResourceHostMsg_RequestResource first_request_msg(
2361 render_view_id, request_id, first_request);
2363 host_.OnMessageReceived(
2364 first_request_msg, first_filter.get(), &msg_was_ok);
2365 base::MessageLoop::current()->RunUntilIdle();
2367 // Now that we're blocked on the redirect, update the response and unblock
2368 // by telling the AsyncResourceHandler to follow the redirect.
2369 SetResponse("HTTP/1.1 200 OK\n"
2370 "Content-Type: text/html\n\n",
2372 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
2373 host_.OnMessageReceived(redirect_msg, first_filter.get(), &msg_was_ok);
2374 base::MessageLoop::current()->RunUntilIdle();
2376 // Flush all the pending requests to get the response through the
2377 // BufferedResourceHandler.
2378 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2380 // The first filter is now deleted, as if the child process died.
2383 SetBrowserClientForTesting(old_client);
2385 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2386 GlobalRequestID first_global_request_id(first_child_id, request_id);
2388 // This second filter is used to emulate a second process.
2389 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
2390 this, browser_context_->GetResourceContext());
2392 int new_render_view_id = 1;
2393 int new_request_id = 2;
2395 ResourceHostMsg_Request request =
2396 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2397 GURL("http://other.com/blech"));
2398 request.transferred_request_child_id = first_child_id;
2399 request.transferred_request_request_id = request_id;
2402 child_ids_.insert(second_filter->child_id());
2403 ResourceHostMsg_RequestResource transfer_request_msg(
2404 new_render_view_id, new_request_id, request);
2406 host_.OnMessageReceived(
2407 transfer_request_msg, second_filter.get(), &msg_was_ok);
2408 base::MessageLoop::current()->RunUntilIdle();
2410 // Check generated messages.
2411 ResourceIPCAccumulator::ClassifiedMessages msgs;
2412 accum_.GetClassifiedMessages(&msgs);
2414 ASSERT_EQ(2U, msgs.size());
2415 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2416 CheckSuccessfulRequest(msgs[1], kResponseBody);
2419 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
2420 // This test expects the cross site request to be leaked, so it can transfer
2421 // the request directly.
2422 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2424 EXPECT_EQ(0, host_.pending_requests());
2426 int render_view_id = 0;
2429 // Configure initial request.
2430 SetResponse("HTTP/1.1 302 Found\n"
2431 "Location: http://other.com/blech\n\n");
2433 HandleScheme("http");
2435 // Temporarily replace ContentBrowserClient with one that will trigger the
2436 // transfer navigation code paths.
2437 TransfersAllNavigationsContentBrowserClient new_client;
2438 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2440 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2441 GURL("http://example.com/blah"),
2442 ResourceType::MAIN_FRAME);
2444 // Now that we're blocked on the redirect, simulate hitting another redirect.
2445 SetResponse("HTTP/1.1 302 Found\n"
2446 "Location: http://other.com/blerg\n\n");
2447 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
2449 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
2450 base::MessageLoop::current()->RunUntilIdle();
2452 // Now that we're blocked on the second redirect, update the response and
2453 // unblock by telling the AsyncResourceHandler to follow the redirect.
2454 // Again, use text/plain to force BufferedResourceHandler to buffer before
2456 const std::string kResponseBody = "hello world";
2457 SetResponse("HTTP/1.1 200 OK\n"
2458 "Content-Type: text/plain\n\n",
2460 ResourceHostMsg_FollowRedirect redirect_msg2(request_id, false, GURL());
2461 host_.OnMessageReceived(redirect_msg2, filter_.get(), &msg_was_ok);
2462 base::MessageLoop::current()->RunUntilIdle();
2464 // Flush all the pending requests to get the response through the
2465 // BufferedResourceHandler.
2466 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2469 SetBrowserClientForTesting(old_client);
2471 // This second filter is used to emulate a second process.
2472 scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
2473 this, browser_context_->GetResourceContext());
2475 int new_render_view_id = 1;
2476 int new_request_id = 2;
2478 ResourceHostMsg_Request request =
2479 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2480 GURL("http://other.com/blech"));
2481 request.transferred_request_child_id = filter_->child_id();
2482 request.transferred_request_request_id = request_id;
2485 child_ids_.insert(second_filter->child_id());
2486 ResourceHostMsg_RequestResource transfer_request_msg(
2487 new_render_view_id, new_request_id, request);
2488 host_.OnMessageReceived(
2489 transfer_request_msg, second_filter.get(), &msg_was_ok);
2491 // Verify that we update the ResourceRequestInfo.
2492 GlobalRequestID global_request_id(second_filter->child_id(), new_request_id);
2493 const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
2494 host_.GetURLRequest(global_request_id));
2495 EXPECT_EQ(second_filter->child_id(), info->GetChildID());
2496 EXPECT_EQ(new_render_view_id, info->GetRouteID());
2497 EXPECT_EQ(new_request_id, info->GetRequestID());
2498 EXPECT_EQ(second_filter, info->filter());
2500 // Let request complete.
2501 base::MessageLoop::current()->RunUntilIdle();
2503 // Check generated messages.
2504 ResourceIPCAccumulator::ClassifiedMessages msgs;
2505 accum_.GetClassifiedMessages(&msgs);
2507 ASSERT_EQ(2U, msgs.size());
2508 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2509 CheckSuccessfulRequest(msgs[1], kResponseBody);
2512 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
2513 EXPECT_EQ(0, host_.pending_requests());
2515 HandleScheme("http");
2517 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"),
2518 ResourceType::MAIN_FRAME);
2520 // Flush all pending requests.
2521 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2523 // Sort all the messages we saw by request.
2524 ResourceIPCAccumulator::ClassifiedMessages msgs;
2525 accum_.GetClassifiedMessages(&msgs);
2527 // We should have gotten one RequestComplete message.
2528 ASSERT_EQ(1U, msgs[0].size());
2529 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2531 // The RequestComplete message should have the error code of
2532 // ERR_UNKNOWN_URL_SCHEME.
2533 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME);
2536 TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
2537 EXPECT_EQ(0, host_.pending_requests());
2539 SendDataReceivedACKs(true);
2541 HandleScheme("big-job");
2542 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2544 // Sort all the messages we saw by request.
2545 ResourceIPCAccumulator::ClassifiedMessages msgs;
2546 accum_.GetClassifiedMessages(&msgs);
2548 size_t size = msgs[0].size();
2550 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2551 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2552 for (size_t i = 2; i < size - 1; ++i)
2553 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2554 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
2557 // Request a very large detachable resource and cancel part way. Some of the
2558 // data should have been sent to the renderer, but not all.
2559 TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) {
2560 EXPECT_EQ(0, host_.pending_requests());
2562 int render_view_id = 0;
2565 std::string raw_headers("HTTP\n"
2566 "Content-type: image/jpeg\n\n");
2567 std::string response_data("01234567890123456789\x01foobar");
2569 // Create a response larger than kMaxAllocationSize (currently 32K). Note
2570 // that if this increase beyond 512K we'll need to make the response longer.
2571 const int kAllocSize = 1024*512;
2572 response_data.resize(kAllocSize, ' ');
2574 SetResponse(raw_headers, response_data);
2575 SetDelayedCompleteJobGeneration(true);
2576 HandleScheme("http");
2578 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2579 GURL("http://example.com/blah"),
2580 ResourceType::PREFETCH);
2582 // Get a bit of data before cancelling.
2583 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2585 // Simulate a cancellation coming from the renderer.
2586 ResourceHostMsg_CancelRequest msg(request_id);
2588 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2590 EXPECT_EQ(1, host_.pending_requests());
2592 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2594 // Sort all the messages we saw by request.
2595 ResourceIPCAccumulator::ClassifiedMessages msgs;
2596 accum_.GetClassifiedMessages(&msgs);
2598 EXPECT_EQ(4U, msgs[0].size());
2600 // Figure out how many bytes were received by the renderer.
2604 ExtractDataOffsetAndLength(msgs[0][2], &data_offset, &data_length));
2605 EXPECT_LT(0, data_length);
2606 EXPECT_GT(kAllocSize, data_length);
2608 // Verify the data that was received before cancellation. The request should
2609 // have appeared to cancel, however.
2610 CheckSuccessfulRequestWithErrorCode(
2612 std::string(response_data.begin(), response_data.begin() + data_length),
2616 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
2617 EXPECT_EQ(0, host_.pending_requests());
2619 HandleScheme("big-job");
2620 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2622 // Sort all the messages we saw by request.
2623 ResourceIPCAccumulator::ClassifiedMessages msgs;
2624 accum_.GetClassifiedMessages(&msgs);
2626 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2627 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2628 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2629 for (size_t i = 2; i < msgs[0].size(); ++i)
2630 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2632 // NOTE: If we fail the above checks then it means that we probably didn't
2633 // load a big enough response to trigger the delay mechanism we are trying to
2636 msgs[0].erase(msgs[0].begin());
2637 msgs[0].erase(msgs[0].begin());
2639 // ACK all DataReceived messages until we find a RequestComplete message.
2640 bool complete = false;
2642 for (size_t i = 0; i < msgs[0].size(); ++i) {
2643 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2648 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2650 ResourceHostMsg_DataReceived_ACK msg(1);
2652 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2655 base::MessageLoop::current()->RunUntilIdle();
2658 accum_.GetClassifiedMessages(&msgs);
2662 // Flakyness of this test might indicate memory corruption issues with
2663 // for example the ResourceBuffer of AsyncResourceHandler.
2664 TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) {
2665 EXPECT_EQ(0, host_.pending_requests());
2667 HandleScheme("big-job");
2668 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2670 // Sort all the messages we saw by request.
2671 ResourceIPCAccumulator::ClassifiedMessages msgs;
2672 accum_.GetClassifiedMessages(&msgs);
2674 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2675 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2676 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2677 for (size_t i = 2; i < msgs[0].size(); ++i)
2678 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2680 // NOTE: If we fail the above checks then it means that we probably didn't
2681 // load a big enough response to trigger the delay mechanism.
2683 // Send some unexpected ACKs.
2684 for (size_t i = 0; i < 128; ++i) {
2685 ResourceHostMsg_DataReceived_ACK msg(1);
2687 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2690 msgs[0].erase(msgs[0].begin());
2691 msgs[0].erase(msgs[0].begin());
2693 // ACK all DataReceived messages until we find a RequestComplete message.
2694 bool complete = false;
2696 for (size_t i = 0; i < msgs[0].size(); ++i) {
2697 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2702 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2704 ResourceHostMsg_DataReceived_ACK msg(1);
2706 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2709 base::MessageLoop::current()->RunUntilIdle();
2712 accum_.GetClassifiedMessages(&msgs);
2716 } // namespace content