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.
7 #include "base/basictypes.h"
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/memory/shared_memory.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/pickle.h"
15 #include "base/run_loop.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h"
18 #include "content/browser/browser_thread_impl.h"
19 #include "content/browser/child_process_security_policy_impl.h"
20 #include "content/browser/loader/cross_site_resource_handler.h"
21 #include "content/browser/loader/detachable_resource_handler.h"
22 #include "content/browser/loader/resource_dispatcher_host_impl.h"
23 #include "content/browser/loader/resource_loader.h"
24 #include "content/browser/loader/resource_message_filter.h"
25 #include "content/browser/loader/resource_request_info_impl.h"
26 #include "content/browser/worker_host/worker_service_impl.h"
27 #include "content/common/child_process_host_impl.h"
28 #include "content/common/resource_messages.h"
29 #include "content/common/view_messages.h"
30 #include "content/public/browser/global_request_id.h"
31 #include "content/public/browser/resource_context.h"
32 #include "content/public/browser/resource_dispatcher_host_delegate.h"
33 #include "content/public/browser/resource_request_info.h"
34 #include "content/public/browser/resource_throttle.h"
35 #include "content/public/common/process_type.h"
36 #include "content/public/common/resource_response.h"
37 #include "content/public/test/test_browser_context.h"
38 #include "content/public/test/test_browser_thread_bundle.h"
39 #include "content/test/test_content_browser_client.h"
40 #include "net/base/net_errors.h"
41 #include "net/base/request_priority.h"
42 #include "net/base/upload_bytes_element_reader.h"
43 #include "net/base/upload_data_stream.h"
44 #include "net/http/http_util.h"
45 #include "net/url_request/url_request.h"
46 #include "net/url_request/url_request_context.h"
47 #include "net/url_request/url_request_job.h"
48 #include "net/url_request/url_request_simple_job.h"
49 #include "net/url_request/url_request_test_job.h"
50 #include "net/url_request/url_request_test_util.h"
51 #include "testing/gtest/include/gtest/gtest.h"
52 #include "webkit/common/appcache/appcache_interfaces.h"
53 #include "webkit/common/blob/shareable_file_reference.h"
55 // TODO(eroman): Write unit tests for SafeBrowsing that exercise
56 // SafeBrowsingResourceHandler.
58 using webkit_blob::ShareableFileReference;
64 // Returns the resource response header structure for this request.
65 void GetResponseHead(const std::vector<IPC::Message>& messages,
66 ResourceResponseHead* response_head) {
67 ASSERT_GE(messages.size(), 2U);
69 // The first messages should be received response.
70 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
72 PickleIterator iter(messages[0]);
74 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id));
75 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head));
78 void GenerateIPCMessage(
79 scoped_refptr<ResourceMessageFilter> filter,
80 scoped_ptr<IPC::Message> message) {
82 ResourceDispatcherHostImpl::Get()->OnMessageReceived(
83 *message, filter.get(), &msg_is_ok);
86 // On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
87 // automatically released.
89 // See ResourceDispatcher::ReleaseResourcesInDataMessage.
91 // TODO(davidben): It would be nice if the behavior for base::SharedMemoryHandle
92 // were more like it is in POSIX where the received fds are tracked in a
93 // ref-counted core that closes them if not extracted.
94 void ReleaseHandlesInMessage(const IPC::Message& message) {
95 if (message.type() == ResourceMsg_SetDataBuffer::ID) {
96 PickleIterator iter(message);
98 CHECK(message.ReadInt(&iter, &request_id));
99 base::SharedMemoryHandle shm_handle;
100 if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message,
103 if (base::SharedMemory::IsHandleValid(shm_handle))
104 base::SharedMemory::CloseHandle(shm_handle);
111 static int RequestIDForMessage(const IPC::Message& msg) {
113 switch (msg.type()) {
114 case ResourceMsg_UploadProgress::ID:
115 case ResourceMsg_ReceivedResponse::ID:
116 case ResourceMsg_ReceivedRedirect::ID:
117 case ResourceMsg_SetDataBuffer::ID:
118 case ResourceMsg_DataReceived::ID:
119 case ResourceMsg_DataDownloaded::ID:
120 case ResourceMsg_RequestComplete::ID: {
121 bool result = PickleIterator(msg).ReadInt(&request_id);
129 static ResourceHostMsg_Request CreateResourceRequest(
131 ResourceType::Type type,
133 ResourceHostMsg_Request request;
134 request.method = std::string(method);
136 request.first_party_for_cookies = url; // bypass third-party cookie blocking
137 request.referrer_policy = blink::WebReferrerPolicyDefault;
138 request.load_flags = 0;
139 request.origin_pid = 0;
140 request.resource_type = type;
141 request.request_context = 0;
142 request.appcache_host_id = appcache::kNoHostId;
143 request.download_to_file = false;
144 request.is_main_frame = true;
145 request.parent_is_main_frame = false;
146 request.parent_render_frame_id = -1;
147 request.transition_type = PAGE_TRANSITION_LINK;
148 request.allow_download = true;
152 // Spin up the message loop to kick off the request.
153 static void KickOffRequest() {
154 base::MessageLoop::current()->RunUntilIdle();
157 // We may want to move this to a shared space if it is useful for something else
158 class ResourceIPCAccumulator {
160 ~ResourceIPCAccumulator() {
161 for (size_t i = 0; i < messages_.size(); i++) {
162 ReleaseHandlesInMessage(messages_[i]);
166 // On Windows, takes ownership of SharedMemoryHandles in |msg|.
167 void AddMessage(const IPC::Message& msg) {
168 messages_.push_back(msg);
171 // This groups the messages by their request ID. The groups will be in order
172 // that the first message for each request ID was received, and the messages
173 // within the groups will be in the order that they appeared.
174 // Note that this clears messages_. The caller takes ownership of any
175 // SharedMemoryHandles in messages placed into |msgs|.
176 typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
177 void GetClassifiedMessages(ClassifiedMessages* msgs);
180 std::vector<IPC::Message> messages_;
183 // This is very inefficient as a result of repeatedly extracting the ID, use
185 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) {
186 while (!messages_.empty()) {
187 // Ignore unknown message types as it is valid for code to generated other
188 // IPCs as side-effects that we are not testing here.
189 int cur_id = RequestIDForMessage(messages_[0]);
191 std::vector<IPC::Message> cur_requests;
192 cur_requests.push_back(messages_[0]);
193 // find all other messages with this ID
194 for (int i = 1; i < static_cast<int>(messages_.size()); i++) {
195 int id = RequestIDForMessage(messages_[i]);
197 cur_requests.push_back(messages_[i]);
198 messages_.erase(messages_.begin() + i);
202 msgs->push_back(cur_requests);
204 messages_.erase(messages_.begin());
208 // This is used to emulate different sub-processes, since this filter will
209 // have a different ID than the original.
210 class TestFilter : public ResourceMessageFilter {
212 explicit TestFilter(ResourceContext* resource_context)
213 : ResourceMessageFilter(
214 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
215 PROCESS_TYPE_RENDERER, NULL, NULL, NULL, NULL,
216 base::Bind(&TestFilter::GetContexts, base::Unretained(this))),
217 resource_context_(resource_context),
219 received_after_canceled_(0) {
220 ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
221 set_peer_pid_for_testing(base::GetCurrentProcId());
224 void set_canceled(bool canceled) { canceled_ = canceled; }
225 int received_after_canceled() const { return received_after_canceled_; }
227 // ResourceMessageFilter override
228 virtual bool Send(IPC::Message* msg) OVERRIDE {
229 // No messages should be received when the process has been canceled.
231 received_after_canceled_++;
232 ReleaseHandlesInMessage(*msg);
237 ResourceContext* resource_context() { return resource_context_; }
240 virtual ~TestFilter() {}
243 void GetContexts(const ResourceHostMsg_Request& request,
244 ResourceContext** resource_context,
245 net::URLRequestContext** request_context) {
246 *resource_context = resource_context_;
247 *request_context = resource_context_->GetRequestContext();
250 ResourceContext* resource_context_;
252 int received_after_canceled_;
254 DISALLOW_COPY_AND_ASSIGN(TestFilter);
258 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
259 // For the test, we want all the incoming messages to go to the same place,
260 // which is why this forwards.
261 class ForwardingFilter : public TestFilter {
263 explicit ForwardingFilter(IPC::Sender* dest,
264 ResourceContext* resource_context)
265 : TestFilter(resource_context),
269 // TestFilter override
270 virtual bool Send(IPC::Message* msg) OVERRIDE {
271 return dest_->Send(msg);
275 virtual ~ForwardingFilter() {}
279 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
282 // This class is a variation on URLRequestTestJob that will call
283 // URLRequest::OnBeforeNetworkStart before starting.
284 class URLRequestTestDelayedNetworkJob : public net::URLRequestTestJob {
286 URLRequestTestDelayedNetworkJob(net::URLRequest* request,
287 net::NetworkDelegate* network_delegate)
288 : net::URLRequestTestJob(request, network_delegate) {}
290 // Only start if not deferred for network start.
291 virtual void Start() OVERRIDE {
293 NotifyBeforeNetworkStart(&defer);
296 net::URLRequestTestJob::Start();
299 virtual void ResumeNetworkStart() OVERRIDE {
300 net::URLRequestTestJob::StartAsync();
304 virtual ~URLRequestTestDelayedNetworkJob() {}
306 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob);
309 // This class is a variation on URLRequestTestJob in that it does
310 // not complete start upon entry, only when specifically told to.
311 class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
313 URLRequestTestDelayedStartJob(net::URLRequest* request,
314 net::NetworkDelegate* network_delegate)
315 : net::URLRequestTestJob(request, network_delegate) {
318 URLRequestTestDelayedStartJob(net::URLRequest* request,
319 net::NetworkDelegate* network_delegate,
321 : net::URLRequestTestJob(request, network_delegate, auto_advance) {
324 URLRequestTestDelayedStartJob(net::URLRequest* request,
325 net::NetworkDelegate* network_delegate,
326 const std::string& response_headers,
327 const std::string& response_data,
329 : net::URLRequestTestJob(request,
337 // Do nothing until you're told to.
338 virtual void Start() OVERRIDE {}
340 // Finish starting a URL request whose job is an instance of
341 // URLRequestTestDelayedStartJob. It is illegal to call this routine
342 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
343 static void CompleteStart(net::URLRequest* request) {
344 for (URLRequestTestDelayedStartJob* job = list_head_;
347 if (job->request() == request) {
348 job->net::URLRequestTestJob::Start();
355 static bool DelayedStartQueueEmpty() {
359 static void ClearQueue() {
362 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
363 << "; may result in leaks.";
369 virtual ~URLRequestTestDelayedStartJob() {
370 for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
371 job = &(*job)->next_) {
373 *job = (*job)->next_;
386 static URLRequestTestDelayedStartJob* list_head_;
387 URLRequestTestDelayedStartJob* next_;
390 URLRequestTestDelayedStartJob*
391 URLRequestTestDelayedStartJob::list_head_ = NULL;
393 // This class is a variation on URLRequestTestJob in that it
394 // returns IO_pending errors before every read, not just the first one.
395 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
397 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
398 net::NetworkDelegate* network_delegate)
399 : net::URLRequestTestJob(request, network_delegate) {}
400 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
401 net::NetworkDelegate* network_delegate,
403 : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
404 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
405 net::NetworkDelegate* network_delegate,
406 const std::string& response_headers,
407 const std::string& response_data,
409 : net::URLRequestTestJob(request,
416 virtual ~URLRequestTestDelayedCompletionJob() {}
419 virtual bool NextReadAsync() OVERRIDE { return true; }
422 class URLRequestBigJob : public net::URLRequestSimpleJob {
424 URLRequestBigJob(net::URLRequest* request,
425 net::NetworkDelegate* network_delegate)
426 : net::URLRequestSimpleJob(request, network_delegate) {
429 virtual int GetData(std::string* mime_type,
430 std::string* charset,
432 const net::CompletionCallback& callback) const OVERRIDE {
433 *mime_type = "text/plain";
438 if (!ParseURL(request_->url(), &text, &count))
439 return net::ERR_INVALID_URL;
441 data->reserve(text.size() * count);
442 for (int i = 0; i < count; ++i)
449 virtual ~URLRequestBigJob() {}
451 // big-job:substring,N
452 static bool ParseURL(const GURL& url, std::string* text, int* count) {
453 std::vector<std::string> parts;
454 base::SplitString(url.path(), ',', &parts);
456 if (parts.size() != 2)
460 return base::StringToInt(parts[1], count);
464 // Associated with an URLRequest to determine if the URLRequest gets deleted.
465 class TestUserData : public base::SupportsUserData::Data {
467 explicit TestUserData(bool* was_deleted)
468 : was_deleted_(was_deleted) {
471 virtual ~TestUserData() {
472 *was_deleted_ = true;
479 class TransfersAllNavigationsContentBrowserClient
480 : public TestContentBrowserClient {
482 virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context,
483 const GURL& current_url,
484 const GURL& new_url) OVERRIDE {
489 enum GenericResourceThrottleFlags {
491 DEFER_STARTING_REQUEST = 1 << 0,
492 DEFER_PROCESSING_RESPONSE = 1 << 1,
493 CANCEL_BEFORE_START = 1 << 2,
494 DEFER_NETWORK_START = 1 << 3
497 // Throttle that tracks the current throttle blocking a request. Only one
498 // can throttle any request at a time.
499 class GenericResourceThrottle : public ResourceThrottle {
501 // The value is used to indicate that the throttle should not provide
502 // a error code when cancelling a request. net::OK is used, because this
503 // is not an error code.
504 static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;
506 GenericResourceThrottle(int flags, int code)
508 error_code_for_cancellation_(code) {
511 virtual ~GenericResourceThrottle() {
512 if (active_throttle_ == this)
513 active_throttle_ = NULL;
516 // ResourceThrottle implementation:
517 virtual void WillStartRequest(bool* defer) OVERRIDE {
518 ASSERT_EQ(NULL, active_throttle_);
519 if (flags_ & DEFER_STARTING_REQUEST) {
520 active_throttle_ = this;
524 if (flags_ & CANCEL_BEFORE_START) {
525 if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
526 controller()->Cancel();
528 controller()->CancelWithError(error_code_for_cancellation_);
533 virtual void WillProcessResponse(bool* defer) OVERRIDE {
534 ASSERT_EQ(NULL, active_throttle_);
535 if (flags_ & DEFER_PROCESSING_RESPONSE) {
536 active_throttle_ = this;
541 virtual void OnBeforeNetworkStart(bool* defer) OVERRIDE {
542 ASSERT_EQ(NULL, active_throttle_);
544 if (flags_ & DEFER_NETWORK_START) {
545 active_throttle_ = this;
550 virtual const char* GetNameForLogging() const OVERRIDE {
551 return "GenericResourceThrottle";
555 ASSERT_TRUE(this == active_throttle_);
556 active_throttle_ = NULL;
557 controller()->Resume();
560 static GenericResourceThrottle* active_throttle() {
561 return active_throttle_;
565 int flags_; // bit-wise union of GenericResourceThrottleFlags.
566 int error_code_for_cancellation_;
568 // The currently active throttle, if any.
569 static GenericResourceThrottle* active_throttle_;
572 GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
574 class TestResourceDispatcherHostDelegate
575 : public ResourceDispatcherHostDelegate {
577 TestResourceDispatcherHostDelegate()
578 : create_two_throttles_(false),
580 error_code_for_cancellation_(
581 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
584 void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
585 user_data_.reset(user_data);
588 void set_flags(int value) {
592 void set_error_code_for_cancellation(int code) {
593 error_code_for_cancellation_ = code;
596 void set_create_two_throttles(bool create_two_throttles) {
597 create_two_throttles_ = create_two_throttles;
600 // ResourceDispatcherHostDelegate implementation:
602 virtual void RequestBeginning(
603 net::URLRequest* request,
604 ResourceContext* resource_context,
605 appcache::AppCacheService* appcache_service,
606 ResourceType::Type resource_type,
609 ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
611 const void* key = user_data_.get();
612 request->SetUserData(key, user_data_.release());
615 if (flags_ != NONE) {
616 throttles->push_back(new GenericResourceThrottle(
617 flags_, error_code_for_cancellation_));
618 if (create_two_throttles_)
619 throttles->push_back(new GenericResourceThrottle(
620 flags_, error_code_for_cancellation_));
625 bool create_two_throttles_;
627 int error_code_for_cancellation_;
628 scoped_ptr<base::SupportsUserData::Data> user_data_;
631 // Waits for a ShareableFileReference to be released.
632 class ShareableFileReleaseWaiter {
634 ShareableFileReleaseWaiter(const base::FilePath& path) {
635 scoped_refptr<ShareableFileReference> file =
636 ShareableFileReference::Get(path);
637 file->AddFinalReleaseCallback(
638 base::Bind(&ShareableFileReleaseWaiter::Released,
639 base::Unretained(this)));
647 void Released(const base::FilePath& path) {
653 DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter);
656 class ResourceDispatcherHostTest : public testing::Test,
659 ResourceDispatcherHostTest()
660 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
662 send_data_received_acks_(false) {
663 browser_context_.reset(new TestBrowserContext());
664 BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
665 base::RunLoop().RunUntilIdle();
666 filter_ = MakeForwardingFilter();
667 ResourceContext* resource_context = browser_context_->GetResourceContext();
668 resource_context->GetRequestContext()->set_network_delegate(
672 // IPC::Sender implementation
673 virtual bool Send(IPC::Message* msg) OVERRIDE {
674 accum_.AddMessage(*msg);
676 if (send_data_received_acks_ &&
677 msg->type() == ResourceMsg_DataReceived::ID) {
678 GenerateDataReceivedACK(*msg);
681 if (wait_for_request_complete_loop_ &&
682 msg->type() == ResourceMsg_RequestComplete::ID) {
683 wait_for_request_complete_loop_->Quit();
686 // Do not release handles in it yet; the accumulator owns them now.
693 virtual void SetUp() OVERRIDE {
694 DCHECK(!test_fixture_);
695 test_fixture_ = this;
696 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
697 net::URLRequest::Deprecated::RegisterProtocolFactory(
699 &ResourceDispatcherHostTest::Factory);
700 EnsureTestSchemeIsAllowed();
701 delay_start_ = false;
702 delay_complete_ = false;
703 network_start_notification_ = false;
704 url_request_jobs_created_count_ = 0;
707 virtual void TearDown() {
708 net::URLRequest::Deprecated::RegisterProtocolFactory("test", NULL);
709 if (!scheme_.empty())
710 net::URLRequest::Deprecated::RegisterProtocolFactory(
711 scheme_, old_factory_);
713 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
714 URLRequestTestDelayedStartJob::ClearQueue();
716 DCHECK(test_fixture_ == this);
717 test_fixture_ = NULL;
719 for (std::set<int>::iterator it = child_ids_.begin();
720 it != child_ids_.end(); ++it) {
721 host_.CancelRequestsForProcess(*it);
726 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
728 // Flush the message loop to make application verifiers happy.
729 if (ResourceDispatcherHostImpl::Get())
730 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
731 browser_context_->GetResourceContext());
733 WorkerServiceImpl::GetInstance()->PerformTeardownForTesting();
735 browser_context_.reset();
736 base::RunLoop().RunUntilIdle();
739 // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
740 // to leak per-child state on test shutdown.
741 ForwardingFilter* MakeForwardingFilter() {
742 ForwardingFilter* filter =
743 new ForwardingFilter(this, browser_context_->GetResourceContext());
744 child_ids_.insert(filter->child_id());
748 // Creates a request using the current test object as the filter and
749 // SubResource as the resource type.
750 void MakeTestRequest(int render_view_id,
754 // Generates a request using the given filter and resource type.
755 void MakeTestRequestWithResourceType(ResourceMessageFilter* filter,
756 int render_view_id, int request_id,
758 ResourceType::Type type);
760 void CancelRequest(int request_id);
761 void RendererCancelRequest(int request_id) {
762 ResourceMessageFilter* old_filter = SetFilter(filter_.get());
763 host_.OnCancelRequest(request_id);
764 SetFilter(old_filter);
767 void CompleteStartRequest(int request_id);
768 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
770 net::TestNetworkDelegate* network_delegate() { return &network_delegate_; }
772 void EnsureSchemeIsAllowed(const std::string& scheme) {
773 ChildProcessSecurityPolicyImpl* policy =
774 ChildProcessSecurityPolicyImpl::GetInstance();
775 if (!policy->IsWebSafeScheme(scheme))
776 policy->RegisterWebSafeScheme(scheme);
779 void EnsureTestSchemeIsAllowed() {
780 EnsureSchemeIsAllowed("test");
783 // Sets a particular response for any request from now on. To switch back to
784 // the default bahavior, pass an empty |headers|. |headers| should be raw-
785 // formatted (NULLs instead of EOLs).
786 void SetResponse(const std::string& headers, const std::string& data) {
787 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
789 response_data_ = data;
791 void SetResponse(const std::string& headers) {
792 SetResponse(headers, std::string());
795 void SendDataReceivedACKs(bool send_acks) {
796 send_data_received_acks_ = send_acks;
799 // Intercepts requests for the given protocol.
800 void HandleScheme(const std::string& scheme) {
801 DCHECK(scheme_.empty());
802 DCHECK(!old_factory_);
804 old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory(
805 scheme_, &ResourceDispatcherHostTest::Factory);
806 EnsureSchemeIsAllowed(scheme);
809 // Our own net::URLRequestJob factory.
810 static net::URLRequestJob* Factory(net::URLRequest* request,
811 net::NetworkDelegate* network_delegate,
812 const std::string& scheme) {
813 url_request_jobs_created_count_++;
814 if (test_fixture_->response_headers_.empty()) {
816 return new URLRequestTestDelayedStartJob(request, network_delegate);
817 } else if (delay_complete_) {
818 return new URLRequestTestDelayedCompletionJob(request,
820 } else if (network_start_notification_) {
821 return new URLRequestTestDelayedNetworkJob(request, network_delegate);
822 } else if (scheme == "big-job") {
823 return new URLRequestBigJob(request, network_delegate);
825 return new net::URLRequestTestJob(request, network_delegate);
829 return new URLRequestTestDelayedStartJob(
830 request, network_delegate,
831 test_fixture_->response_headers_, test_fixture_->response_data_,
833 } else if (delay_complete_) {
834 return new URLRequestTestDelayedCompletionJob(
835 request, network_delegate,
836 test_fixture_->response_headers_, test_fixture_->response_data_,
839 return new net::URLRequestTestJob(
840 request, network_delegate,
841 test_fixture_->response_headers_, test_fixture_->response_data_,
847 void SetDelayedStartJobGeneration(bool delay_job_start) {
848 delay_start_ = delay_job_start;
851 void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
852 delay_complete_ = delay_job_complete;
855 void SetNetworkStartNotificationJobGeneration(bool notification) {
856 network_start_notification_ = notification;
859 void GenerateDataReceivedACK(const IPC::Message& msg) {
860 EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
863 bool result = PickleIterator(msg).ReadInt(&request_id);
865 scoped_ptr<IPC::Message> ack(
866 new ResourceHostMsg_DataReceived_ACK(request_id));
868 base::MessageLoop::current()->PostTask(
870 base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
873 // Setting filters for testing renderer messages.
874 // Returns the previous filter.
875 ResourceMessageFilter* SetFilter(ResourceMessageFilter* new_filter) {
876 ResourceMessageFilter* old_filter = host_.filter_;
877 host_.filter_ = new_filter;
881 void WaitForRequestComplete() {
882 DCHECK(!wait_for_request_complete_loop_);
883 wait_for_request_complete_loop_.reset(new base::RunLoop);
884 wait_for_request_complete_loop_->Run();
885 wait_for_request_complete_loop_.reset();
888 content::TestBrowserThreadBundle thread_bundle_;
889 scoped_ptr<TestBrowserContext> browser_context_;
890 scoped_refptr<ForwardingFilter> filter_;
891 net::TestNetworkDelegate network_delegate_;
892 ResourceDispatcherHostImpl host_;
893 ResourceIPCAccumulator accum_;
894 std::string response_headers_;
895 std::string response_data_;
897 net::URLRequest::ProtocolFactory* old_factory_;
898 bool send_data_received_acks_;
899 std::set<int> child_ids_;
900 scoped_ptr<base::RunLoop> wait_for_request_complete_loop_;
901 static ResourceDispatcherHostTest* test_fixture_;
902 static bool delay_start_;
903 static bool delay_complete_;
904 static bool network_start_notification_;
905 static int url_request_jobs_created_count_;
908 ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL;
909 bool ResourceDispatcherHostTest::delay_start_ = false;
910 bool ResourceDispatcherHostTest::delay_complete_ = false;
911 bool ResourceDispatcherHostTest::network_start_notification_ = false;
912 int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0;
914 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
917 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
918 url, ResourceType::SUB_RESOURCE);
921 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
922 ResourceMessageFilter* filter,
926 ResourceType::Type type) {
927 ResourceHostMsg_Request request =
928 CreateResourceRequest("GET", type, url);
929 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
931 host_.OnMessageReceived(msg, filter, &msg_was_ok);
935 void ResourceDispatcherHostTest::CancelRequest(int request_id) {
936 host_.CancelRequest(filter_->child_id(), request_id);
939 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
940 CompleteStartRequest(filter_.get(), request_id);
943 void ResourceDispatcherHostTest::CompleteStartRequest(
944 ResourceMessageFilter* filter,
946 GlobalRequestID gid(filter->child_id(), request_id);
947 net::URLRequest* req = host_.GetURLRequest(gid);
950 URLRequestTestDelayedStartJob::CompleteStart(req);
953 void CheckRequestCompleteErrorCode(const IPC::Message& message,
954 int expected_error_code) {
955 // Verify the expected error code was received.
959 ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
961 PickleIterator iter(message);
962 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
963 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
964 ASSERT_EQ(expected_error_code, error_code);
967 testing::AssertionResult ExtractDataOffsetAndLength(const IPC::Message& message,
970 PickleIterator iter(message);
972 if (!IPC::ReadParam(&message, &iter, &request_id))
973 return testing::AssertionFailure() << "Could not read request_id";
974 if (!IPC::ReadParam(&message, &iter, data_offset))
975 return testing::AssertionFailure() << "Could not read data_offset";
976 if (!IPC::ReadParam(&message, &iter, data_length))
977 return testing::AssertionFailure() << "Could not read data_length";
978 return testing::AssertionSuccess();
981 void CheckSuccessfulRequestWithErrorCode(
982 const std::vector<IPC::Message>& messages,
983 const std::string& reference_data,
984 int expected_error) {
985 // A successful request will have received 4 messages:
986 // ReceivedResponse (indicates headers received)
987 // SetDataBuffer (contains shared memory handle)
988 // DataReceived (data offset and length into shared memory)
989 // RequestComplete (request is done)
991 // This function verifies that we received 4 messages and that they are
992 // appropriate. It allows for an error code other than net::OK if the request
993 // should successfully receive data and then abort, e.g., on cancel.
994 ASSERT_EQ(4U, messages.size());
996 // The first messages should be received response
997 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
999 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
1001 PickleIterator iter(messages[1]);
1003 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
1004 base::SharedMemoryHandle shm_handle;
1005 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
1007 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
1009 // Followed by the data, currently we only do the data in one chunk, but
1010 // should probably test multiple chunks later
1011 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
1016 ExtractDataOffsetAndLength(messages[2], &data_offset, &data_length));
1018 ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
1019 ASSERT_GE(shm_size, data_length);
1021 base::SharedMemory shared_mem(shm_handle, true); // read only
1022 shared_mem.Map(data_length);
1023 const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
1024 ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
1026 // The last message should be all data received.
1027 CheckRequestCompleteErrorCode(messages[3], expected_error);
1030 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
1031 const std::string& reference_data) {
1032 CheckSuccessfulRequestWithErrorCode(messages, reference_data, net::OK);
1035 void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages,
1036 const std::string& reference_data) {
1037 ASSERT_EQ(5U, messages.size());
1038 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type());
1040 const std::vector<IPC::Message> second_req_msgs =
1041 std::vector<IPC::Message>(messages.begin() + 1, messages.end());
1042 CheckSuccessfulRequest(second_req_msgs, reference_data);
1045 void CheckFailedRequest(const std::vector<IPC::Message>& messages,
1046 const std::string& reference_data,
1047 int expected_error) {
1048 ASSERT_LT(0U, messages.size());
1049 ASSERT_GE(2U, messages.size());
1050 size_t failure_index = messages.size() - 1;
1052 if (messages.size() == 2) {
1053 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
1056 CheckRequestCompleteErrorCode(messages[failure_index], expected_error);
1059 // Tests whether many messages get dispatched properly.
1060 TEST_F(ResourceDispatcherHostTest, TestMany) {
1061 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1062 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1063 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1064 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1065 net::URLRequestTestJob::test_url_4(),
1066 ResourceType::PREFETCH); // detachable type
1067 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1069 // Finish the redirection
1070 ResourceHostMsg_FollowRedirect redirect_msg(5, false, GURL());
1072 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
1073 base::MessageLoop::current()->RunUntilIdle();
1075 // flush all the pending requests
1076 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1078 // sorts out all the messages we saw by request
1079 ResourceIPCAccumulator::ClassifiedMessages msgs;
1080 accum_.GetClassifiedMessages(&msgs);
1082 // there are five requests, so we should have gotten them classified as such
1083 ASSERT_EQ(5U, msgs.size());
1085 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1086 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
1087 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1088 CheckSuccessfulRequest(msgs[3], net::URLRequestTestJob::test_data_4());
1089 CheckSuccessfulRedirect(msgs[4], net::URLRequestTestJob::test_data_2());
1092 // Tests whether messages get canceled properly. We issue four requests,
1093 // cancel two of them, and make sure that each sent the proper notifications.
1094 TEST_F(ResourceDispatcherHostTest, Cancel) {
1095 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1096 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1097 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1099 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1100 net::URLRequestTestJob::test_url_4(),
1101 ResourceType::PREFETCH); // detachable type
1105 // Cancel request must come from the renderer for a detachable resource to
1107 RendererCancelRequest(4);
1109 // The handler should have been detached now.
1110 GlobalRequestID global_request_id(filter_->child_id(), 4);
1111 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1112 host_.GetURLRequest(global_request_id));
1113 ASSERT_TRUE(info->detachable_handler()->is_detached());
1115 // flush all the pending requests
1116 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1117 base::MessageLoop::current()->RunUntilIdle();
1119 // Everything should be out now.
1120 EXPECT_EQ(0, host_.pending_requests());
1122 ResourceIPCAccumulator::ClassifiedMessages msgs;
1123 accum_.GetClassifiedMessages(&msgs);
1125 // there are four requests, so we should have gotten them classified as such
1126 ASSERT_EQ(4U, msgs.size());
1128 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1129 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1131 // Check that request 2 and 4 got canceled, as far as the renderer is
1132 // concerned. Request 2 will have been deleted.
1133 ASSERT_EQ(1U, msgs[1].size());
1134 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1136 ASSERT_EQ(2U, msgs[3].size());
1137 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[3][0].type());
1138 CheckRequestCompleteErrorCode(msgs[3][1], net::ERR_ABORTED);
1140 // However, request 4 should have actually gone to completion. (Only request 2
1142 EXPECT_EQ(4, network_delegate()->completed_requests());
1143 EXPECT_EQ(1, network_delegate()->canceled_requests());
1144 EXPECT_EQ(0, network_delegate()->error_count());
1147 // Shows that detachable requests will timeout if the request takes too long to
1149 TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
1150 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1151 net::URLRequestTestJob::test_url_2(),
1152 ResourceType::PREFETCH); // detachable type
1153 GlobalRequestID global_request_id(filter_->child_id(), 1);
1154 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1155 host_.GetURLRequest(global_request_id));
1156 ASSERT_TRUE(info->detachable_handler());
1157 info->detachable_handler()->set_cancel_delay(
1158 base::TimeDelta::FromMilliseconds(200));
1159 base::MessageLoop::current()->RunUntilIdle();
1161 RendererCancelRequest(1);
1163 // From the renderer's perspective, the request was cancelled.
1164 ResourceIPCAccumulator::ClassifiedMessages msgs;
1165 accum_.GetClassifiedMessages(&msgs);
1166 ASSERT_EQ(1U, msgs.size());
1167 ASSERT_EQ(2U, msgs[0].size());
1168 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1169 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1171 // But it continues detached.
1172 EXPECT_EQ(1, host_.pending_requests());
1173 EXPECT_TRUE(info->detachable_handler()->is_detached());
1175 // Wait until after the delay timer times out before we start processing any
1177 base::OneShotTimer<base::MessageLoop> timer;
1178 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1179 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1180 base::MessageLoop::current()->Run();
1182 // The prefetch should be cancelled by now.
1183 EXPECT_EQ(0, host_.pending_requests());
1184 EXPECT_EQ(1, network_delegate()->completed_requests());
1185 EXPECT_EQ(1, network_delegate()->canceled_requests());
1186 EXPECT_EQ(0, network_delegate()->error_count());
1189 // If the filter has disappeared then detachable resources should continue to
1191 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
1192 // test_url_1's data is available synchronously, so use 2 and 3.
1193 ResourceHostMsg_Request request_prefetch = CreateResourceRequest(
1194 "GET", ResourceType::PREFETCH, net::URLRequestTestJob::test_url_2());
1195 ResourceHostMsg_Request request_ping = CreateResourceRequest(
1196 "GET", ResourceType::PING, net::URLRequestTestJob::test_url_3());
1199 ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch);
1200 host_.OnMessageReceived(msg_prefetch, filter_, &msg_was_ok);
1201 ResourceHostMsg_RequestResource msg_ping(0, 2, request_ping);
1202 host_.OnMessageReceived(msg_ping, filter_, &msg_was_ok);
1204 // Remove the filter before processing the requests by simulating channel
1206 ResourceRequestInfoImpl* info_prefetch = ResourceRequestInfoImpl::ForRequest(
1207 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
1208 ResourceRequestInfoImpl* info_ping = ResourceRequestInfoImpl::ForRequest(
1209 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2)));
1210 DCHECK_EQ(filter_.get(), info_prefetch->filter());
1211 DCHECK_EQ(filter_.get(), info_ping->filter());
1212 filter_->OnChannelClosing();
1213 info_prefetch->filter_.reset();
1214 info_ping->filter_.reset();
1216 // From the renderer's perspective, the requests were cancelled.
1217 ResourceIPCAccumulator::ClassifiedMessages msgs;
1218 accum_.GetClassifiedMessages(&msgs);
1219 ASSERT_EQ(2U, msgs.size());
1220 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1221 CheckRequestCompleteErrorCode(msgs[1][0], net::ERR_ABORTED);
1223 // But it continues detached.
1224 EXPECT_EQ(2, host_.pending_requests());
1225 EXPECT_TRUE(info_prefetch->detachable_handler()->is_detached());
1226 EXPECT_TRUE(info_ping->detachable_handler()->is_detached());
1230 // Make sure the requests weren't canceled early.
1231 EXPECT_EQ(2, host_.pending_requests());
1233 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1234 base::MessageLoop::current()->RunUntilIdle();
1236 EXPECT_EQ(0, host_.pending_requests());
1237 EXPECT_EQ(2, network_delegate()->completed_requests());
1238 EXPECT_EQ(0, network_delegate()->canceled_requests());
1239 EXPECT_EQ(0, network_delegate()->error_count());
1242 // If the filter has disappeared (original process dies) then detachable
1243 // resources should continue to load, even when redirected.
1244 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
1245 ResourceHostMsg_Request request = CreateResourceRequest(
1246 "GET", ResourceType::PREFETCH,
1247 net::URLRequestTestJob::test_url_redirect_to_url_2());
1249 ResourceHostMsg_RequestResource msg(0, 1, request);
1251 host_.OnMessageReceived(msg, filter_, &msg_was_ok);
1253 // Remove the filter before processing the request by simulating channel
1255 GlobalRequestID global_request_id(filter_->child_id(), 1);
1256 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1257 host_.GetURLRequest(global_request_id));
1258 info->filter_->OnChannelClosing();
1259 info->filter_.reset();
1261 // From the renderer's perspective, the request was cancelled.
1262 ResourceIPCAccumulator::ClassifiedMessages msgs;
1263 accum_.GetClassifiedMessages(&msgs);
1264 ASSERT_EQ(1U, msgs.size());
1265 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1267 // But it continues detached.
1268 EXPECT_EQ(1, host_.pending_requests());
1269 EXPECT_TRUE(info->detachable_handler()->is_detached());
1271 // Verify no redirects before resetting the filter.
1272 net::URLRequest* url_request = host_.GetURLRequest(global_request_id);
1273 EXPECT_EQ(1u, url_request->url_chain().size());
1276 // Verify that a redirect was followed.
1277 EXPECT_EQ(2u, url_request->url_chain().size());
1279 // Make sure the request wasn't canceled early.
1280 EXPECT_EQ(1, host_.pending_requests());
1282 // Finish up the request.
1283 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1284 base::MessageLoop::current()->RunUntilIdle();
1286 EXPECT_EQ(0, host_.pending_requests());
1287 EXPECT_EQ(1, network_delegate()->completed_requests());
1288 EXPECT_EQ(0, network_delegate()->canceled_requests());
1289 EXPECT_EQ(0, network_delegate()->error_count());
1292 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
1293 bool was_deleted = false;
1295 // Arrange to have requests deferred before starting.
1296 TestResourceDispatcherHostDelegate delegate;
1297 delegate.set_flags(DEFER_STARTING_REQUEST);
1298 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1299 host_.SetDelegate(&delegate);
1301 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1302 // We cancel from the renderer because all non-renderer cancels delete
1303 // the request synchronously.
1304 RendererCancelRequest(1);
1306 // Our TestResourceThrottle should not have been deleted yet. This is to
1307 // ensure that destruction of the URLRequest happens asynchronously to
1308 // calling CancelRequest.
1309 EXPECT_FALSE(was_deleted);
1311 base::MessageLoop::current()->RunUntilIdle();
1313 EXPECT_TRUE(was_deleted);
1316 TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
1317 bool was_deleted = false;
1319 // Arrange to have requests deferred before starting.
1320 TestResourceDispatcherHostDelegate delegate;
1321 delegate.set_flags(DEFER_STARTING_REQUEST);
1322 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1323 host_.SetDelegate(&delegate);
1325 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1326 net::URLRequestTestJob::test_url_1(),
1327 ResourceType::PREFETCH); // detachable type
1328 // Cancel request must come from the renderer for a detachable resource to
1330 RendererCancelRequest(1);
1332 // Even after driving the event loop, the request has not been deleted.
1333 EXPECT_FALSE(was_deleted);
1335 // However, it is still throttled because the defer happened above the
1336 // DetachableResourceHandler.
1337 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1338 base::MessageLoop::current()->RunUntilIdle();
1339 EXPECT_FALSE(was_deleted);
1341 // Resume the request.
1342 GenericResourceThrottle* throttle =
1343 GenericResourceThrottle::active_throttle();
1344 ASSERT_TRUE(throttle);
1347 // Now, the request completes.
1348 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1349 base::MessageLoop::current()->RunUntilIdle();
1350 EXPECT_TRUE(was_deleted);
1351 EXPECT_EQ(1, network_delegate()->completed_requests());
1352 EXPECT_EQ(0, network_delegate()->canceled_requests());
1353 EXPECT_EQ(0, network_delegate()->error_count());
1356 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1357 // URLRequest will not be started.
1358 TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
1359 TestResourceDispatcherHostDelegate delegate;
1360 delegate.set_flags(CANCEL_BEFORE_START);
1361 host_.SetDelegate(&delegate);
1363 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1365 // flush all the pending requests
1366 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1367 base::MessageLoop::current()->RunUntilIdle();
1369 ResourceIPCAccumulator::ClassifiedMessages msgs;
1370 accum_.GetClassifiedMessages(&msgs);
1372 // Check that request got canceled.
1373 ASSERT_EQ(1U, msgs[0].size());
1374 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1376 // Make sure URLRequest is never started.
1377 EXPECT_EQ(0, url_request_jobs_created_count_);
1380 TEST_F(ResourceDispatcherHostTest, PausedStartError) {
1381 // Arrange to have requests deferred before processing response headers.
1382 TestResourceDispatcherHostDelegate delegate;
1383 delegate.set_flags(DEFER_PROCESSING_RESPONSE);
1384 host_.SetDelegate(&delegate);
1386 SetDelayedStartJobGeneration(true);
1387 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1388 CompleteStartRequest(1);
1390 // flush all the pending requests
1391 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1392 base::MessageLoop::current()->RunUntilIdle();
1394 EXPECT_EQ(0, host_.pending_requests());
1397 // Test the OnBeforeNetworkStart throttle.
1398 TEST_F(ResourceDispatcherHostTest, ThrottleNetworkStart) {
1399 // Arrange to have requests deferred before processing response headers.
1400 TestResourceDispatcherHostDelegate delegate;
1401 delegate.set_flags(DEFER_NETWORK_START);
1402 host_.SetDelegate(&delegate);
1404 SetNetworkStartNotificationJobGeneration(true);
1405 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1407 // Should have deferred for network start.
1408 GenericResourceThrottle* first_throttle =
1409 GenericResourceThrottle::active_throttle();
1410 ASSERT_TRUE(first_throttle);
1411 EXPECT_EQ(0, network_delegate()->completed_requests());
1412 EXPECT_EQ(1, host_.pending_requests());
1414 first_throttle->Resume();
1416 // Flush all the pending requests.
1417 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1418 base::MessageLoop::current()->RunUntilIdle();
1420 EXPECT_EQ(1, network_delegate()->completed_requests());
1421 EXPECT_EQ(0, host_.pending_requests());
1424 TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
1425 // Arrange to have requests deferred before starting.
1426 TestResourceDispatcherHostDelegate delegate;
1427 delegate.set_flags(DEFER_STARTING_REQUEST);
1428 delegate.set_create_two_throttles(true);
1429 host_.SetDelegate(&delegate);
1431 // Make sure the first throttle blocked the request, and then resume.
1432 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1433 GenericResourceThrottle* first_throttle =
1434 GenericResourceThrottle::active_throttle();
1435 ASSERT_TRUE(first_throttle);
1436 first_throttle->Resume();
1438 // Make sure the second throttle blocked the request, and then resume.
1439 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1440 ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
1441 GenericResourceThrottle::active_throttle()->Resume();
1443 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1445 // The request is started asynchronously.
1446 base::MessageLoop::current()->RunUntilIdle();
1448 // Flush all the pending requests.
1449 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1451 EXPECT_EQ(0, host_.pending_requests());
1453 // Make sure the request completed successfully.
1454 ResourceIPCAccumulator::ClassifiedMessages msgs;
1455 accum_.GetClassifiedMessages(&msgs);
1456 ASSERT_EQ(1U, msgs.size());
1457 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1461 // Tests that the delegate can cancel a request and provide a error code.
1462 TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
1463 TestResourceDispatcherHostDelegate delegate;
1464 delegate.set_flags(CANCEL_BEFORE_START);
1465 delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
1466 host_.SetDelegate(&delegate);
1468 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1469 // The request will get cancelled by the throttle.
1471 // flush all the pending requests
1472 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1473 base::MessageLoop::current()->RunUntilIdle();
1475 ResourceIPCAccumulator::ClassifiedMessages msgs;
1476 accum_.GetClassifiedMessages(&msgs);
1478 // Check the cancellation
1479 ASSERT_EQ(1U, msgs.size());
1480 ASSERT_EQ(1U, msgs[0].size());
1482 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ACCESS_DENIED);
1485 // Tests CancelRequestsForProcess
1486 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
1487 scoped_refptr<TestFilter> test_filter = new TestFilter(
1488 browser_context_->GetResourceContext());
1489 child_ids_.insert(test_filter->child_id());
1491 // request 1 goes to the test delegate
1492 ResourceHostMsg_Request request = CreateResourceRequest(
1493 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
1495 MakeTestRequestWithResourceType(test_filter.get(), 0, 1,
1496 net::URLRequestTestJob::test_url_1(),
1497 ResourceType::SUB_RESOURCE);
1499 // request 2 goes to us
1500 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1502 // request 3 goes to the test delegate
1503 MakeTestRequestWithResourceType(test_filter.get(), 0, 3,
1504 net::URLRequestTestJob::test_url_3(),
1505 ResourceType::SUB_RESOURCE);
1507 // request 4 goes to us
1508 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1509 net::URLRequestTestJob::test_url_4(),
1510 ResourceType::PREFETCH); // detachable type
1513 // Make sure all requests have finished stage one. test_url_1 will have
1515 base::MessageLoop::current()->RunUntilIdle();
1518 // Now that the async IO path is in place, the IO always completes on the
1519 // initial call; so the requests have already completed. This basically
1520 // breaks the whole test.
1521 //EXPECT_EQ(3, host_.pending_requests());
1523 // Process test_url_2 and test_url_3 for one level so one callback is called.
1524 // We'll cancel test_url_4 (detachable) before processing it to verify that it
1525 // delays the cancel.
1526 for (int i = 0; i < 2; i++)
1527 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1529 // Cancel the requests to the test process.
1530 host_.CancelRequestsForProcess(filter_->child_id());
1531 test_filter->set_canceled(true);
1533 // The requests should all be cancelled, except request 4, which is detached.
1534 EXPECT_EQ(1, host_.pending_requests());
1535 GlobalRequestID global_request_id(filter_->child_id(), 4);
1536 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1537 host_.GetURLRequest(global_request_id));
1538 ASSERT_TRUE(info->detachable_handler()->is_detached());
1540 // Flush all the pending requests.
1541 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1543 EXPECT_EQ(0, host_.pending_requests());
1545 // The test delegate should not have gotten any messages after being canceled.
1546 ASSERT_EQ(0, test_filter->received_after_canceled());
1548 // There should be two results.
1549 ResourceIPCAccumulator::ClassifiedMessages msgs;
1550 accum_.GetClassifiedMessages(&msgs);
1551 ASSERT_EQ(2U, msgs.size());
1552 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1553 // The detachable request was cancelled by the renderer before it
1554 // finished. From the perspective of the renderer, it should have cancelled.
1555 ASSERT_EQ(2U, msgs[1].size());
1556 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1557 CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED);
1558 // But it completed anyway. For the network stack, no requests were canceled.
1559 EXPECT_EQ(4, network_delegate()->completed_requests());
1560 EXPECT_EQ(0, network_delegate()->canceled_requests());
1561 EXPECT_EQ(0, network_delegate()->error_count());
1564 TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
1565 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1566 net::URLRequestTestJob::test_url_4(),
1567 ResourceType::PREFETCH); // detachable type
1568 GlobalRequestID global_request_id(filter_->child_id(), 1);
1569 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1570 host_.GetURLRequest(global_request_id));
1571 ASSERT_TRUE(info->detachable_handler());
1572 info->detachable_handler()->set_cancel_delay(
1573 base::TimeDelta::FromMilliseconds(200));
1574 base::MessageLoop::current()->RunUntilIdle();
1576 // Cancel the requests to the test process.
1577 host_.CancelRequestsForProcess(filter_->child_id());
1578 EXPECT_EQ(1, host_.pending_requests());
1580 // Wait until after the delay timer times out before we start processing any
1582 base::OneShotTimer<base::MessageLoop> timer;
1583 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1584 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1585 base::MessageLoop::current()->Run();
1587 // The prefetch should be cancelled by now.
1588 EXPECT_EQ(0, host_.pending_requests());
1590 // In case any messages are still to be processed.
1591 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1592 base::MessageLoop::current()->RunUntilIdle();
1594 ResourceIPCAccumulator::ClassifiedMessages msgs;
1595 accum_.GetClassifiedMessages(&msgs);
1597 ASSERT_EQ(1U, msgs.size());
1599 // The request should have cancelled.
1600 ASSERT_EQ(2U, msgs[0].size());
1601 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1602 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1603 // And not run to completion.
1604 EXPECT_EQ(1, network_delegate()->completed_requests());
1605 EXPECT_EQ(1, network_delegate()->canceled_requests());
1606 EXPECT_EQ(0, network_delegate()->error_count());
1609 // Tests blocking and resuming requests.
1610 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
1611 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1612 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1613 host_.BlockRequestsForRoute(filter_->child_id(), 3);
1615 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1616 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1617 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1618 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1619 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1620 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1622 // Flush all the pending requests
1623 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1625 // Sort out all the messages we saw by request
1626 ResourceIPCAccumulator::ClassifiedMessages msgs;
1627 accum_.GetClassifiedMessages(&msgs);
1629 // All requests but the 2 for the RVH 0 should have been blocked.
1630 ASSERT_EQ(2U, msgs.size());
1632 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1633 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1635 // Resume requests for RVH 1 and flush pending requests.
1636 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
1638 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1641 accum_.GetClassifiedMessages(&msgs);
1642 ASSERT_EQ(2U, msgs.size());
1643 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1644 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
1646 // Test that new requests are not blocked for RVH 1.
1647 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1648 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1650 accum_.GetClassifiedMessages(&msgs);
1651 ASSERT_EQ(1U, msgs.size());
1652 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1654 // Now resumes requests for all RVH (2 and 3).
1655 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
1656 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
1658 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1661 accum_.GetClassifiedMessages(&msgs);
1662 ASSERT_EQ(2U, msgs.size());
1663 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1664 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1667 // Tests blocking and canceling requests.
1668 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
1669 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1671 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1672 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1673 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1674 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1675 // Blocked detachable resources should not delay cancellation.
1676 MakeTestRequestWithResourceType(filter_.get(), 1, 5,
1677 net::URLRequestTestJob::test_url_4(),
1678 ResourceType::PREFETCH); // detachable type
1680 // Flush all the pending requests.
1681 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1683 // Sort out all the messages we saw by request.
1684 ResourceIPCAccumulator::ClassifiedMessages msgs;
1685 accum_.GetClassifiedMessages(&msgs);
1687 // The 2 requests for the RVH 0 should have been processed.
1688 ASSERT_EQ(2U, msgs.size());
1690 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1691 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1693 // Cancel requests for RVH 1.
1694 host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
1696 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1699 accum_.GetClassifiedMessages(&msgs);
1700 ASSERT_EQ(0U, msgs.size());
1703 // Tests that blocked requests are canceled if their associated process dies.
1704 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
1705 // This second filter is used to emulate a second process.
1706 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1708 host_.BlockRequestsForRoute(second_filter->child_id(), 0);
1710 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1711 net::URLRequestTestJob::test_url_1(),
1712 ResourceType::SUB_RESOURCE);
1713 MakeTestRequestWithResourceType(second_filter.get(), 0, 2,
1714 net::URLRequestTestJob::test_url_2(),
1715 ResourceType::SUB_RESOURCE);
1716 MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1717 net::URLRequestTestJob::test_url_3(),
1718 ResourceType::SUB_RESOURCE);
1719 MakeTestRequestWithResourceType(second_filter.get(), 0, 4,
1720 net::URLRequestTestJob::test_url_1(),
1721 ResourceType::SUB_RESOURCE);
1722 MakeTestRequestWithResourceType(second_filter.get(), 0, 5,
1723 net::URLRequestTestJob::test_url_4(),
1724 ResourceType::PREFETCH); // detachable type
1726 // Simulate process death.
1727 host_.CancelRequestsForProcess(second_filter->child_id());
1729 // Flush all the pending requests.
1730 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1732 // Sort out all the messages we saw by request.
1733 ResourceIPCAccumulator::ClassifiedMessages msgs;
1734 accum_.GetClassifiedMessages(&msgs);
1736 // The 2 requests for the RVH 0 should have been processed. Note that
1737 // blocked detachable requests are canceled without delay.
1738 ASSERT_EQ(2U, msgs.size());
1740 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1741 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1743 EXPECT_TRUE(host_.blocked_loaders_map_.empty());
1746 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1747 // away. Note that we rely on Purify for finding the leaks if any.
1748 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1749 // destructor to make sure the blocked requests are deleted.
1750 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
1751 // This second filter is used to emulate a second process.
1752 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1754 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1755 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1756 host_.BlockRequestsForRoute(second_filter->child_id(), 1);
1758 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1759 net::URLRequestTestJob::test_url_1(),
1760 ResourceType::SUB_RESOURCE);
1761 MakeTestRequestWithResourceType(filter_.get(), 1, 2,
1762 net::URLRequestTestJob::test_url_2(),
1763 ResourceType::SUB_RESOURCE);
1764 MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1765 net::URLRequestTestJob::test_url_3(),
1766 ResourceType::SUB_RESOURCE);
1767 MakeTestRequestWithResourceType(second_filter.get(), 1, 4,
1768 net::URLRequestTestJob::test_url_1(),
1769 ResourceType::SUB_RESOURCE);
1770 MakeTestRequestWithResourceType(filter_.get(), 2, 5,
1771 net::URLRequestTestJob::test_url_2(),
1772 ResourceType::SUB_RESOURCE);
1773 MakeTestRequestWithResourceType(filter_.get(), 2, 6,
1774 net::URLRequestTestJob::test_url_3(),
1775 ResourceType::SUB_RESOURCE);
1776 MakeTestRequestWithResourceType(filter_.get(), 0, 7,
1777 net::URLRequestTestJob::test_url_4(),
1778 ResourceType::PREFETCH); // detachable type
1779 MakeTestRequestWithResourceType(second_filter.get(), 1, 8,
1780 net::URLRequestTestJob::test_url_4(),
1781 ResourceType::PREFETCH); // detachable type
1783 host_.CancelRequestsForProcess(filter_->child_id());
1784 host_.CancelRequestsForProcess(second_filter->child_id());
1786 // Flush all the pending requests.
1787 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1790 // Test the private helper method "CalculateApproximateMemoryCost()".
1791 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
1792 net::URLRequestContext context;
1793 net::URLRequest req(
1794 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL, &context);
1796 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1798 // Add 9 bytes of referrer.
1799 req.SetReferrer("123456789");
1801 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1803 // Add 33 bytes of upload content.
1804 std::string upload_content;
1805 upload_content.resize(33);
1806 std::fill(upload_content.begin(), upload_content.end(), 'x');
1807 scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader(
1808 upload_content.data(), upload_content.size()));
1809 req.set_upload(make_scoped_ptr(
1810 net::UploadDataStream::CreateWithReader(reader.Pass(), 0)));
1812 // Since the upload throttling is disabled, this has no effect on the cost.
1814 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1817 // Test that too much memory for outstanding requests for a particular
1818 // render_process_host_id causes requests to fail.
1819 TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
1820 // Expected cost of each request as measured by
1821 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1822 int kMemoryCostOfTest2Req =
1823 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
1824 std::string("GET").size() +
1825 net::URLRequestTestJob::test_url_2().spec().size();
1827 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1828 int kMaxCostPerProcess = 440000;
1829 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
1831 // Determine how many instance of test_url_2() we can request before
1832 // throttling kicks in.
1833 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
1835 // This second filter is used to emulate a second process.
1836 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1838 // Saturate the number of outstanding requests for our process.
1839 for (size_t i = 0; i < kMaxRequests; ++i) {
1840 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1841 net::URLRequestTestJob::test_url_2(),
1842 ResourceType::SUB_RESOURCE);
1845 // Issue two more requests for our process -- these should fail immediately.
1846 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 1,
1847 net::URLRequestTestJob::test_url_2(),
1848 ResourceType::SUB_RESOURCE);
1849 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 2,
1850 net::URLRequestTestJob::test_url_2(),
1851 ResourceType::SUB_RESOURCE);
1853 // Issue two requests for the second process -- these should succeed since
1854 // it is just process 0 that is saturated.
1855 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 3,
1856 net::URLRequestTestJob::test_url_2(),
1857 ResourceType::SUB_RESOURCE);
1858 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 4,
1859 net::URLRequestTestJob::test_url_2(),
1860 ResourceType::SUB_RESOURCE);
1862 // Flush all the pending requests.
1863 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1864 base::MessageLoop::current()->RunUntilIdle();
1866 // Sorts out all the messages we saw by request.
1867 ResourceIPCAccumulator::ClassifiedMessages msgs;
1868 accum_.GetClassifiedMessages(&msgs);
1870 // We issued (kMaxRequests + 4) total requests.
1871 ASSERT_EQ(kMaxRequests + 4, msgs.size());
1873 // Check that the first kMaxRequests succeeded.
1874 for (size_t i = 0; i < kMaxRequests; ++i)
1875 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1877 // Check that the subsequent two requests (kMaxRequests + 1) and
1878 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1879 for (int i = 0; i < 2; ++i) {
1880 // Should have sent a single RequestComplete message.
1881 int index = kMaxRequests + i;
1882 CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(),
1883 net::ERR_INSUFFICIENT_RESOURCES);
1886 // The final 2 requests should have succeeded.
1887 CheckSuccessfulRequest(msgs[kMaxRequests + 2],
1888 net::URLRequestTestJob::test_data_2());
1889 CheckSuccessfulRequest(msgs[kMaxRequests + 3],
1890 net::URLRequestTestJob::test_data_2());
1893 // Test that when too many requests are outstanding for a particular
1894 // render_process_host_id, any subsequent request from it fails. Also verify
1895 // that the global limit is honored.
1896 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
1897 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1898 const size_t kMaxRequestsPerProcess = 2;
1899 host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
1900 const size_t kMaxRequests = 3;
1901 host_.set_max_num_in_flight_requests(kMaxRequests);
1903 // Needed to emulate additional processes.
1904 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1905 scoped_refptr<ForwardingFilter> third_filter = MakeForwardingFilter();
1907 // Saturate the number of outstanding requests for our process.
1908 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
1909 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1910 net::URLRequestTestJob::test_url_2(),
1911 ResourceType::SUB_RESOURCE);
1914 // Issue another request for our process -- this should fail immediately.
1915 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequestsPerProcess + 1,
1916 net::URLRequestTestJob::test_url_2(),
1917 ResourceType::SUB_RESOURCE);
1919 // Issue a request for the second process -- this should succeed, because it
1920 // is just process 0 that is saturated.
1921 MakeTestRequestWithResourceType(
1922 second_filter.get(), 0, kMaxRequestsPerProcess + 2,
1923 net::URLRequestTestJob::test_url_2(), ResourceType::SUB_RESOURCE);
1925 // Issue a request for the third process -- this should fail, because the
1926 // global limit has been reached.
1927 MakeTestRequestWithResourceType(
1928 third_filter.get(), 0, kMaxRequestsPerProcess + 3,
1929 net::URLRequestTestJob::test_url_2(), ResourceType::SUB_RESOURCE);
1931 // Flush all the pending requests.
1932 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1933 base::MessageLoop::current()->RunUntilIdle();
1935 // Sorts out all the messages we saw by request.
1936 ResourceIPCAccumulator::ClassifiedMessages msgs;
1937 accum_.GetClassifiedMessages(&msgs);
1939 // The processes issued the following requests:
1940 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1941 // #2 issued 1 request that passed
1942 // #3 issued 1 request that failed
1943 ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size());
1945 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
1946 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1948 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0],
1949 net::URLRequestTestJob::test_data_2(),
1950 net::ERR_INSUFFICIENT_RESOURCES);
1951 CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1],
1952 net::URLRequestTestJob::test_data_2());
1953 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2],
1954 net::URLRequestTestJob::test_data_2(),
1955 net::ERR_INSUFFICIENT_RESOURCES);
1958 // Tests that we sniff the mime type for a simple request.
1959 TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
1960 std::string raw_headers("HTTP/1.1 200 OK\n\n");
1961 std::string response_data("<html><title>Test One</title></html>");
1962 SetResponse(raw_headers, response_data);
1964 HandleScheme("http");
1965 MakeTestRequest(0, 1, GURL("http:bla"));
1967 // Flush all pending requests.
1968 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1970 // Sorts out all the messages we saw by request.
1971 ResourceIPCAccumulator::ClassifiedMessages msgs;
1972 accum_.GetClassifiedMessages(&msgs);
1973 ASSERT_EQ(1U, msgs.size());
1975 ResourceResponseHead response_head;
1976 GetResponseHead(msgs[0], &response_head);
1977 ASSERT_EQ("text/html", response_head.mime_type);
1980 // Tests that we don't sniff the mime type when the server provides one.
1981 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
1982 std::string raw_headers("HTTP/1.1 200 OK\n"
1983 "Content-type: image/jpeg\n\n");
1984 std::string response_data("<html><title>Test One</title></html>");
1985 SetResponse(raw_headers, response_data);
1987 HandleScheme("http");
1988 MakeTestRequest(0, 1, GURL("http:bla"));
1990 // Flush all pending requests.
1991 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1993 // Sorts out all the messages we saw by request.
1994 ResourceIPCAccumulator::ClassifiedMessages msgs;
1995 accum_.GetClassifiedMessages(&msgs);
1996 ASSERT_EQ(1U, msgs.size());
1998 ResourceResponseHead response_head;
1999 GetResponseHead(msgs[0], &response_head);
2000 ASSERT_EQ("image/jpeg", response_head.mime_type);
2003 // Tests that we don't sniff the mime type when there is no message body.
2004 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
2005 SetResponse("HTTP/1.1 304 Not Modified\n\n");
2007 HandleScheme("http");
2008 MakeTestRequest(0, 1, GURL("http:bla"));
2010 // Flush all pending requests.
2011 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2013 // Sorts out all the messages we saw by request.
2014 ResourceIPCAccumulator::ClassifiedMessages msgs;
2015 accum_.GetClassifiedMessages(&msgs);
2016 ASSERT_EQ(1U, msgs.size());
2018 ResourceResponseHead response_head;
2019 GetResponseHead(msgs[0], &response_head);
2020 ASSERT_EQ("", response_head.mime_type);
2023 TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
2024 SetResponse("HTTP/1.1 204 No Content\n\n");
2026 HandleScheme("http");
2027 MakeTestRequest(0, 1, GURL("http:bla"));
2029 // Flush all pending requests.
2030 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2032 // Sorts out all the messages we saw by request.
2033 ResourceIPCAccumulator::ClassifiedMessages msgs;
2034 accum_.GetClassifiedMessages(&msgs);
2035 ASSERT_EQ(1U, msgs.size());
2037 ResourceResponseHead response_head;
2038 GetResponseHead(msgs[0], &response_head);
2039 ASSERT_EQ("text/plain", response_head.mime_type);
2042 TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
2043 SetResponse("HTTP/1.1 200 OK\n\n");
2045 HandleScheme("http");
2046 MakeTestRequest(0, 1, GURL("http:bla"));
2048 // Flush all pending requests.
2049 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2051 // Sorts out all the messages we saw by request.
2052 ResourceIPCAccumulator::ClassifiedMessages msgs;
2053 accum_.GetClassifiedMessages(&msgs);
2054 ASSERT_EQ(1U, msgs.size());
2056 ResourceResponseHead response_head;
2057 GetResponseHead(msgs[0], &response_head);
2058 ASSERT_EQ("text/plain", response_head.mime_type);
2061 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2062 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
2063 std::string raw_headers("HTTP/1.1 403 Forbidden\n"
2064 "Content-disposition: attachment; filename=blah\n"
2065 "Content-type: application/octet-stream\n\n");
2066 std::string response_data("<html><title>Test One</title></html>");
2067 SetResponse(raw_headers, response_data);
2069 HandleScheme("http");
2071 // Only MAIN_FRAMEs can trigger a download.
2072 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"),
2073 ResourceType::MAIN_FRAME);
2075 // Flush all pending requests.
2076 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2077 base::MessageLoop::current()->RunUntilIdle();
2079 // Sorts out all the messages we saw by request.
2080 ResourceIPCAccumulator::ClassifiedMessages msgs;
2081 accum_.GetClassifiedMessages(&msgs);
2083 // We should have gotten one RequestComplete message.
2084 ASSERT_EQ(1U, msgs.size());
2085 ASSERT_EQ(1U, msgs[0].size());
2086 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2088 // The RequestComplete message should have had the error code of
2089 // ERR_INVALID_RESPONSE.
2090 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_INVALID_RESPONSE);
2093 // Test for http://crbug.com/76202 . We don't want to destroy a
2094 // download request prematurely when processing a cancellation from
2096 TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
2097 EXPECT_EQ(0, host_.pending_requests());
2099 int render_view_id = 0;
2102 std::string raw_headers("HTTP\n"
2103 "Content-disposition: attachment; filename=foo\n\n");
2104 std::string response_data("01234567890123456789\x01foobar");
2106 // Get past sniffing metrics in the BufferedResourceHandler. Note that
2107 // if we don't get past the sniffing metrics, the result will be that
2108 // the BufferedResourceHandler won't have figured out that it's a download,
2109 // won't have constructed a DownloadResourceHandler, and and the request
2110 // will be successfully canceled below, failing the test.
2111 response_data.resize(1025, ' ');
2113 SetResponse(raw_headers, response_data);
2114 SetDelayedCompleteJobGeneration(true);
2115 HandleScheme("http");
2117 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2118 GURL("http://example.com/blah"),
2119 ResourceType::MAIN_FRAME);
2120 // Return some data so that the request is identified as a download
2121 // and the proper resource handlers are created.
2122 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2124 // And now simulate a cancellation coming from the renderer.
2125 ResourceHostMsg_CancelRequest msg(request_id);
2127 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2129 // Since the request had already started processing as a download,
2130 // the cancellation above should have been ignored and the request
2131 // should still be alive.
2132 EXPECT_EQ(1, host_.pending_requests());
2134 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2137 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
2138 EXPECT_EQ(0, host_.pending_requests());
2140 int render_view_id = 0;
2143 std::string raw_headers("HTTP\n"
2144 "Content-disposition: attachment; filename=foo\n\n");
2145 std::string response_data("01234567890123456789\x01foobar");
2146 // Get past sniffing metrics.
2147 response_data.resize(1025, ' ');
2149 SetResponse(raw_headers, response_data);
2150 SetDelayedCompleteJobGeneration(true);
2151 HandleScheme("http");
2153 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2154 GURL("http://example.com/blah"),
2155 ResourceType::MAIN_FRAME);
2156 // Return some data so that the request is identified as a download
2157 // and the proper resource handlers are created.
2158 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2160 // And now simulate a cancellation coming from the renderer.
2161 ResourceHostMsg_CancelRequest msg(request_id);
2163 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2165 // Since the request had already started processing as a download,
2166 // the cancellation above should have been ignored and the request
2167 // should still be alive.
2168 EXPECT_EQ(1, host_.pending_requests());
2170 // Cancelling by other methods shouldn't work either.
2171 host_.CancelRequestsForProcess(render_view_id);
2172 EXPECT_EQ(1, host_.pending_requests());
2174 // Cancelling by context should work.
2175 host_.CancelRequestsForContext(filter_->resource_context());
2176 EXPECT_EQ(0, host_.pending_requests());
2179 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
2180 EXPECT_EQ(0, host_.pending_requests());
2182 int render_view_id = 0;
2185 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2186 net::URLRequestTestJob::test_url_4(),
2187 ResourceType::PREFETCH); // detachable type
2189 // Simulate a cancel coming from the renderer.
2190 RendererCancelRequest(request_id);
2192 // Since the request had already started processing as detachable,
2193 // the cancellation above should have been ignored and the request
2194 // should have been detached.
2195 EXPECT_EQ(1, host_.pending_requests());
2197 // Cancelling by other methods should also leave it detached.
2198 host_.CancelRequestsForProcess(render_view_id);
2199 EXPECT_EQ(1, host_.pending_requests());
2201 // Cancelling by context should work.
2202 host_.CancelRequestsForContext(filter_->resource_context());
2203 EXPECT_EQ(0, host_.pending_requests());
2206 // Test the cancelling of requests that are being transferred to a new renderer
2207 // due to a redirection.
2208 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
2209 EXPECT_EQ(0, host_.pending_requests());
2211 int render_view_id = 0;
2214 std::string raw_headers("HTTP/1.1 200 OK\n"
2215 "Content-Type: text/html; charset=utf-8\n\n");
2216 std::string response_data("<html>foobar</html>");
2218 SetResponse(raw_headers, response_data);
2219 HandleScheme("http");
2221 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2222 GURL("http://example.com/blah"),
2223 ResourceType::MAIN_FRAME);
2226 GlobalRequestID global_request_id(filter_->child_id(), request_id);
2227 host_.MarkAsTransferredNavigation(global_request_id);
2229 // And now simulate a cancellation coming from the renderer.
2230 ResourceHostMsg_CancelRequest msg(request_id);
2232 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2234 // Since the request is marked as being transferred,
2235 // the cancellation above should have been ignored and the request
2236 // should still be alive.
2237 EXPECT_EQ(1, host_.pending_requests());
2239 // Cancelling by other methods shouldn't work either.
2240 host_.CancelRequestsForProcess(render_view_id);
2241 EXPECT_EQ(1, host_.pending_requests());
2243 // Cancelling by context should work.
2244 host_.CancelRequestsForContext(filter_->resource_context());
2245 EXPECT_EQ(0, host_.pending_requests());
2248 // Test transferred navigations with text/html, which doesn't trigger any
2249 // content sniffing.
2250 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
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.
2277 const std::string kResponseBody = "hello world";
2278 SetResponse("HTTP/1.1 200 OK\n"
2279 "Content-Type: text/html\n\n",
2281 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
2283 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
2284 base::MessageLoop::current()->RunUntilIdle();
2286 // Flush all the pending requests to get the response through the
2287 // BufferedResourceHandler.
2288 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2290 // Restore, now that we've set up a transfer.
2291 SetBrowserClientForTesting(old_client);
2293 // This second filter is used to emulate a second process.
2294 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2296 int new_render_view_id = 1;
2297 int new_request_id = 2;
2299 ResourceHostMsg_Request request =
2300 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2301 GURL("http://other.com/blech"));
2302 request.transferred_request_child_id = filter_->child_id();
2303 request.transferred_request_request_id = request_id;
2305 ResourceHostMsg_RequestResource transfer_request_msg(
2306 new_render_view_id, new_request_id, request);
2307 host_.OnMessageReceived(
2308 transfer_request_msg, second_filter.get(), &msg_was_ok);
2309 base::MessageLoop::current()->RunUntilIdle();
2311 // Check generated messages.
2312 ResourceIPCAccumulator::ClassifiedMessages msgs;
2313 accum_.GetClassifiedMessages(&msgs);
2315 ASSERT_EQ(2U, msgs.size());
2316 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2317 CheckSuccessfulRequest(msgs[1], kResponseBody);
2320 // Test transferred navigations with text/plain, which causes
2321 // BufferedResourceHandler to buffer the response to sniff the content
2322 // before the transfer occurs.
2323 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
2324 // This test expects the cross site request to be leaked, so it can transfer
2325 // the request directly.
2326 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2328 EXPECT_EQ(0, host_.pending_requests());
2330 int render_view_id = 0;
2333 // Configure initial request.
2334 SetResponse("HTTP/1.1 302 Found\n"
2335 "Location: http://other.com/blech\n\n");
2337 HandleScheme("http");
2339 // Temporarily replace ContentBrowserClient with one that will trigger the
2340 // transfer navigation code paths.
2341 TransfersAllNavigationsContentBrowserClient new_client;
2342 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2344 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2345 GURL("http://example.com/blah"),
2346 ResourceType::MAIN_FRAME);
2348 // Now that we're blocked on the redirect, update the response and unblock by
2349 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
2350 // MIME type, which causes BufferedResourceHandler to buffer it before the
2352 const std::string kResponseBody = "hello world";
2353 SetResponse("HTTP/1.1 200 OK\n"
2354 "Content-Type: text/plain\n\n",
2356 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
2358 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
2359 base::MessageLoop::current()->RunUntilIdle();
2361 // Flush all the pending requests to get the response through the
2362 // BufferedResourceHandler.
2363 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2365 // Restore, now that we've set up a transfer.
2366 SetBrowserClientForTesting(old_client);
2368 // This second filter is used to emulate a second process.
2369 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2371 int new_render_view_id = 1;
2372 int new_request_id = 2;
2374 ResourceHostMsg_Request request =
2375 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2376 GURL("http://other.com/blech"));
2377 request.transferred_request_child_id = filter_->child_id();
2378 request.transferred_request_request_id = request_id;
2380 ResourceHostMsg_RequestResource transfer_request_msg(
2381 new_render_view_id, new_request_id, request);
2382 host_.OnMessageReceived(
2383 transfer_request_msg, second_filter.get(), &msg_was_ok);
2384 base::MessageLoop::current()->RunUntilIdle();
2386 // Check generated messages.
2387 ResourceIPCAccumulator::ClassifiedMessages msgs;
2388 accum_.GetClassifiedMessages(&msgs);
2390 ASSERT_EQ(2U, msgs.size());
2391 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2392 CheckSuccessfulRequest(msgs[1], kResponseBody);
2395 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
2396 // This test expects the cross site request to be leaked, so it can transfer
2397 // the request directly.
2398 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2400 EXPECT_EQ(0, host_.pending_requests());
2402 int render_view_id = 0;
2404 int first_child_id = -1;
2406 // Configure initial request.
2407 SetResponse("HTTP/1.1 302 Found\n"
2408 "Location: http://other.com/blech\n\n");
2409 const std::string kResponseBody = "hello world";
2411 HandleScheme("http");
2413 // Temporarily replace ContentBrowserClient with one that will trigger the
2414 // transfer navigation code paths.
2415 TransfersAllNavigationsContentBrowserClient new_client;
2416 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2418 // Create a first filter that can be deleted before the second one starts.
2420 scoped_refptr<ForwardingFilter> first_filter = MakeForwardingFilter();
2421 first_child_id = first_filter->child_id();
2423 ResourceHostMsg_Request first_request =
2424 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2425 GURL("http://example.com/blah"));
2427 ResourceHostMsg_RequestResource first_request_msg(
2428 render_view_id, request_id, first_request);
2430 host_.OnMessageReceived(
2431 first_request_msg, first_filter.get(), &msg_was_ok);
2432 base::MessageLoop::current()->RunUntilIdle();
2434 // Now that we're blocked on the redirect, update the response and unblock
2435 // by telling the AsyncResourceHandler to follow the redirect.
2436 SetResponse("HTTP/1.1 200 OK\n"
2437 "Content-Type: text/html\n\n",
2439 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
2440 host_.OnMessageReceived(redirect_msg, first_filter.get(), &msg_was_ok);
2441 base::MessageLoop::current()->RunUntilIdle();
2443 // Flush all the pending requests to get the response through the
2444 // BufferedResourceHandler.
2445 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2447 // The first filter is now deleted, as if the child process died.
2450 SetBrowserClientForTesting(old_client);
2452 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2453 GlobalRequestID first_global_request_id(first_child_id, request_id);
2455 // This second filter is used to emulate a second process.
2456 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2458 int new_render_view_id = 1;
2459 int new_request_id = 2;
2461 ResourceHostMsg_Request request =
2462 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2463 GURL("http://other.com/blech"));
2464 request.transferred_request_child_id = first_child_id;
2465 request.transferred_request_request_id = request_id;
2468 child_ids_.insert(second_filter->child_id());
2469 ResourceHostMsg_RequestResource transfer_request_msg(
2470 new_render_view_id, new_request_id, request);
2472 host_.OnMessageReceived(
2473 transfer_request_msg, second_filter.get(), &msg_was_ok);
2474 base::MessageLoop::current()->RunUntilIdle();
2476 // Check generated messages.
2477 ResourceIPCAccumulator::ClassifiedMessages msgs;
2478 accum_.GetClassifiedMessages(&msgs);
2480 ASSERT_EQ(2U, msgs.size());
2481 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2482 CheckSuccessfulRequest(msgs[1], kResponseBody);
2485 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
2486 // This test expects the cross site request to be leaked, so it can transfer
2487 // the request directly.
2488 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2490 EXPECT_EQ(0, host_.pending_requests());
2492 int render_view_id = 0;
2495 // Configure initial request.
2496 SetResponse("HTTP/1.1 302 Found\n"
2497 "Location: http://other.com/blech\n\n");
2499 HandleScheme("http");
2501 // Temporarily replace ContentBrowserClient with one that will trigger the
2502 // transfer navigation code paths.
2503 TransfersAllNavigationsContentBrowserClient new_client;
2504 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2506 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2507 GURL("http://example.com/blah"),
2508 ResourceType::MAIN_FRAME);
2510 // Now that we're blocked on the redirect, simulate hitting another redirect.
2511 SetResponse("HTTP/1.1 302 Found\n"
2512 "Location: http://other.com/blerg\n\n");
2513 ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL());
2515 host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok);
2516 base::MessageLoop::current()->RunUntilIdle();
2518 // Now that we're blocked on the second redirect, update the response and
2519 // unblock by telling the AsyncResourceHandler to follow the redirect.
2520 // Again, use text/plain to force BufferedResourceHandler to buffer before
2522 const std::string kResponseBody = "hello world";
2523 SetResponse("HTTP/1.1 200 OK\n"
2524 "Content-Type: text/plain\n\n",
2526 ResourceHostMsg_FollowRedirect redirect_msg2(request_id, false, GURL());
2527 host_.OnMessageReceived(redirect_msg2, filter_.get(), &msg_was_ok);
2528 base::MessageLoop::current()->RunUntilIdle();
2530 // Flush all the pending requests to get the response through the
2531 // BufferedResourceHandler.
2532 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2535 SetBrowserClientForTesting(old_client);
2537 // This second filter is used to emulate a second process.
2538 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2540 int new_render_view_id = 1;
2541 int new_request_id = 2;
2543 ResourceHostMsg_Request request =
2544 CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
2545 GURL("http://other.com/blech"));
2546 request.transferred_request_child_id = filter_->child_id();
2547 request.transferred_request_request_id = request_id;
2550 child_ids_.insert(second_filter->child_id());
2551 ResourceHostMsg_RequestResource transfer_request_msg(
2552 new_render_view_id, new_request_id, request);
2553 host_.OnMessageReceived(
2554 transfer_request_msg, second_filter.get(), &msg_was_ok);
2556 // Verify that we update the ResourceRequestInfo.
2557 GlobalRequestID global_request_id(second_filter->child_id(), new_request_id);
2558 const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
2559 host_.GetURLRequest(global_request_id));
2560 EXPECT_EQ(second_filter->child_id(), info->GetChildID());
2561 EXPECT_EQ(new_render_view_id, info->GetRouteID());
2562 EXPECT_EQ(new_request_id, info->GetRequestID());
2563 EXPECT_EQ(second_filter, info->filter());
2565 // Let request complete.
2566 base::MessageLoop::current()->RunUntilIdle();
2568 // Check generated messages.
2569 ResourceIPCAccumulator::ClassifiedMessages msgs;
2570 accum_.GetClassifiedMessages(&msgs);
2572 ASSERT_EQ(2U, msgs.size());
2573 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2574 CheckSuccessfulRequest(msgs[1], kResponseBody);
2577 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
2578 EXPECT_EQ(0, host_.pending_requests());
2580 HandleScheme("http");
2582 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"),
2583 ResourceType::MAIN_FRAME);
2585 // Flush all pending requests.
2586 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2588 // Sort all the messages we saw by request.
2589 ResourceIPCAccumulator::ClassifiedMessages msgs;
2590 accum_.GetClassifiedMessages(&msgs);
2592 // We should have gotten one RequestComplete message.
2593 ASSERT_EQ(1U, msgs[0].size());
2594 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2596 // The RequestComplete message should have the error code of
2597 // ERR_UNKNOWN_URL_SCHEME.
2598 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME);
2601 TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
2602 EXPECT_EQ(0, host_.pending_requests());
2604 SendDataReceivedACKs(true);
2606 HandleScheme("big-job");
2607 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2609 // Sort all the messages we saw by request.
2610 ResourceIPCAccumulator::ClassifiedMessages msgs;
2611 accum_.GetClassifiedMessages(&msgs);
2613 size_t size = msgs[0].size();
2615 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2616 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2617 for (size_t i = 2; i < size - 1; ++i)
2618 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2619 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
2622 // Request a very large detachable resource and cancel part way. Some of the
2623 // data should have been sent to the renderer, but not all.
2624 TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) {
2625 EXPECT_EQ(0, host_.pending_requests());
2627 int render_view_id = 0;
2630 std::string raw_headers("HTTP\n"
2631 "Content-type: image/jpeg\n\n");
2632 std::string response_data("01234567890123456789\x01foobar");
2634 // Create a response larger than kMaxAllocationSize (currently 32K). Note
2635 // that if this increase beyond 512K we'll need to make the response longer.
2636 const int kAllocSize = 1024*512;
2637 response_data.resize(kAllocSize, ' ');
2639 SetResponse(raw_headers, response_data);
2640 SetDelayedCompleteJobGeneration(true);
2641 HandleScheme("http");
2643 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2644 GURL("http://example.com/blah"),
2645 ResourceType::PREFETCH);
2647 // Get a bit of data before cancelling.
2648 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2650 // Simulate a cancellation coming from the renderer.
2651 ResourceHostMsg_CancelRequest msg(request_id);
2653 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2655 EXPECT_EQ(1, host_.pending_requests());
2657 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2659 // Sort all the messages we saw by request.
2660 ResourceIPCAccumulator::ClassifiedMessages msgs;
2661 accum_.GetClassifiedMessages(&msgs);
2663 EXPECT_EQ(4U, msgs[0].size());
2665 // Figure out how many bytes were received by the renderer.
2669 ExtractDataOffsetAndLength(msgs[0][2], &data_offset, &data_length));
2670 EXPECT_LT(0, data_length);
2671 EXPECT_GT(kAllocSize, data_length);
2673 // Verify the data that was received before cancellation. The request should
2674 // have appeared to cancel, however.
2675 CheckSuccessfulRequestWithErrorCode(
2677 std::string(response_data.begin(), response_data.begin() + data_length),
2681 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
2682 EXPECT_EQ(0, host_.pending_requests());
2684 HandleScheme("big-job");
2685 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2687 // Sort all the messages we saw by request.
2688 ResourceIPCAccumulator::ClassifiedMessages msgs;
2689 accum_.GetClassifiedMessages(&msgs);
2691 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2692 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2693 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2694 for (size_t i = 2; i < msgs[0].size(); ++i)
2695 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2697 // NOTE: If we fail the above checks then it means that we probably didn't
2698 // load a big enough response to trigger the delay mechanism we are trying to
2701 msgs[0].erase(msgs[0].begin());
2702 msgs[0].erase(msgs[0].begin());
2704 // ACK all DataReceived messages until we find a RequestComplete message.
2705 bool complete = false;
2707 for (size_t i = 0; i < msgs[0].size(); ++i) {
2708 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2713 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2715 ResourceHostMsg_DataReceived_ACK msg(1);
2717 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2720 base::MessageLoop::current()->RunUntilIdle();
2723 accum_.GetClassifiedMessages(&msgs);
2727 // Flakyness of this test might indicate memory corruption issues with
2728 // for example the ResourceBuffer of AsyncResourceHandler.
2729 TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) {
2730 EXPECT_EQ(0, host_.pending_requests());
2732 HandleScheme("big-job");
2733 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2735 // Sort all the messages we saw by request.
2736 ResourceIPCAccumulator::ClassifiedMessages msgs;
2737 accum_.GetClassifiedMessages(&msgs);
2739 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2740 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2741 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2742 for (size_t i = 2; i < msgs[0].size(); ++i)
2743 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2745 // NOTE: If we fail the above checks then it means that we probably didn't
2746 // load a big enough response to trigger the delay mechanism.
2748 // Send some unexpected ACKs.
2749 for (size_t i = 0; i < 128; ++i) {
2750 ResourceHostMsg_DataReceived_ACK msg(1);
2752 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2755 msgs[0].erase(msgs[0].begin());
2756 msgs[0].erase(msgs[0].begin());
2758 // ACK all DataReceived messages until we find a RequestComplete message.
2759 bool complete = false;
2761 for (size_t i = 0; i < msgs[0].size(); ++i) {
2762 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2767 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2769 ResourceHostMsg_DataReceived_ACK msg(1);
2771 host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
2774 base::MessageLoop::current()->RunUntilIdle();
2777 accum_.GetClassifiedMessages(&msgs);
2781 // Tests the dispatcher host's temporary file management.
2782 TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFile) {
2783 const int kRequestID = 1;
2785 // Create a temporary file.
2786 base::FilePath file_path;
2787 ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
2788 scoped_refptr<ShareableFileReference> deletable_file =
2789 ShareableFileReference::GetOrCreate(
2791 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
2792 BrowserThread::GetMessageLoopProxyForThread(
2793 BrowserThread::FILE).get());
2796 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2797 filter_->child_id(), file_path));
2799 // Register it for a resource request.
2800 host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
2802 // Should be readable now.
2803 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2804 filter_->child_id(), file_path));
2806 // The child releases from the request.
2807 bool msg_was_ok = true;
2808 ResourceHostMsg_ReleaseDownloadedFile release_msg(kRequestID);
2809 host_.OnMessageReceived(release_msg, filter_, &msg_was_ok);
2810 ASSERT_TRUE(msg_was_ok);
2812 // Still readable because there is another reference to the file. (The child
2813 // may take additional blob references.)
2814 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2815 filter_->child_id(), file_path));
2817 // Release extra references and wait for the file to be deleted. (This relies
2818 // on the delete happening on the FILE thread which is mapped to main thread
2820 deletable_file = NULL;
2821 base::RunLoop().RunUntilIdle();
2823 // The file is no longer readable to the child and has been deleted.
2824 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2825 filter_->child_id(), file_path));
2826 EXPECT_FALSE(base::PathExists(file_path));
2829 // Tests that temporary files held on behalf of child processes are released
2830 // when the child process dies.
2831 TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) {
2832 const int kRequestID = 1;
2834 // Create a temporary file.
2835 base::FilePath file_path;
2836 ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
2837 scoped_refptr<ShareableFileReference> deletable_file =
2838 ShareableFileReference::GetOrCreate(
2840 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
2841 BrowserThread::GetMessageLoopProxyForThread(
2842 BrowserThread::FILE).get());
2844 // Register it for a resource request.
2845 host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
2846 deletable_file = NULL;
2848 // Should be readable now.
2849 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2850 filter_->child_id(), file_path));
2852 // Let the process die.
2853 filter_->OnChannelClosing();
2854 base::RunLoop().RunUntilIdle();
2856 // The file is no longer readable to the child and has been deleted.
2857 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2858 filter_->child_id(), file_path));
2859 EXPECT_FALSE(base::PathExists(file_path));
2862 TEST_F(ResourceDispatcherHostTest, DownloadToFile) {
2863 // Make a request which downloads to file.
2864 ResourceHostMsg_Request request = CreateResourceRequest(
2865 "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
2866 request.download_to_file = true;
2867 ResourceHostMsg_RequestResource request_msg(0, 1, request);
2869 host_.OnMessageReceived(request_msg, filter_, &msg_was_ok);
2870 ASSERT_TRUE(msg_was_ok);
2872 // Running the message loop until idle does not work because
2873 // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
2874 // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
2875 // until idle so the loader is gone.
2876 WaitForRequestComplete();
2877 base::RunLoop().RunUntilIdle();
2878 EXPECT_EQ(0, host_.pending_requests());
2880 ResourceIPCAccumulator::ClassifiedMessages msgs;
2881 accum_.GetClassifiedMessages(&msgs);
2883 ASSERT_EQ(1U, msgs.size());
2884 const std::vector<IPC::Message>& messages = msgs[0];
2886 // The request should contain the following messages:
2887 // ReceivedResponse (indicates headers received and filename)
2888 // DataDownloaded* (bytes downloaded and total length)
2889 // RequestComplete (request is done)
2892 ResourceResponseHead response_head;
2893 GetResponseHead(messages, &response_head);
2894 ASSERT_FALSE(response_head.download_file_path.empty());
2897 size_t total_len = 0;
2898 for (size_t i = 1; i < messages.size() - 1; i++) {
2899 ASSERT_EQ(ResourceMsg_DataDownloaded::ID, messages[i].type());
2900 PickleIterator iter(messages[i]);
2901 int request_id, data_len;
2902 ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &request_id));
2903 ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &data_len));
2904 total_len += data_len;
2906 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len);
2909 CheckRequestCompleteErrorCode(messages.back(), net::OK);
2911 // Verify that the data ended up in the temporary file.
2912 std::string contents;
2913 ASSERT_TRUE(base::ReadFileToString(response_head.download_file_path,
2915 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
2917 // The file should be readable by the child.
2918 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2919 filter_->child_id(), response_head.download_file_path));
2921 // When the renderer releases the file, it should be deleted. Again,
2922 // RunUntilIdle doesn't work because base::WorkerPool is involved.
2923 ShareableFileReleaseWaiter waiter(response_head.download_file_path);
2924 ResourceHostMsg_ReleaseDownloadedFile release_msg(1);
2925 host_.OnMessageReceived(release_msg, filter_, &msg_was_ok);
2926 ASSERT_TRUE(msg_was_ok);
2928 // The release callback runs before the delete is scheduled, so pump the
2929 // message loop for the delete itself. (This relies on the delete happening on
2930 // the FILE thread which is mapped to main thread in this test.)
2931 base::RunLoop().RunUntilIdle();
2933 EXPECT_FALSE(base::PathExists(response_head.download_file_path));
2934 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2935 filter_->child_id(), response_head.download_file_path));
2938 } // namespace content